diff --git a/obmc/mapper/bindings.py b/obmc/mapper/bindings.py
new file mode 100644
index 0000000..f193a50
--- /dev/null
+++ b/obmc/mapper/bindings.py
@@ -0,0 +1,163 @@
+# Contributors Listed Below - COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+import dbus
+import obmc.dbuslib.enums
+import obmc.utils.misc
+import obmc.utils.pathtree
+
+
+MAPPER_NAME = 'org.openbmc.ObjectMapper'
+MAPPER_IFACE = MAPPER_NAME
+MAPPER_PATH = '/org/openbmc/ObjectMapper'
+MAPPER_NOT_FOUND = MAPPER_NAME + '.Error.NotFound'
+
+
+class Mapper:
+    def __init__(self, bus):
+        self.bus = bus
+        obj = bus.get_object(MAPPER_NAME, MAPPER_PATH, introspect=False)
+        self.iface = dbus.Interface(
+            obj, dbus_interface=MAPPER_IFACE)
+
+    def get_object(self, path):
+        return self.iface.GetObject(path)
+
+    def get_subtree_paths(self, path='/', depth=0):
+        return self.iface.GetSubTreePaths(path, depth)
+
+    def get_subtree(self, path='/', depth=0):
+        return self.iface.GetSubTree(path, depth)
+
+    def get_ancestors(self, path):
+        return self.iface.GetAncestors(path)
+
+    @staticmethod
+    def __try_properties_interface(f, *a):
+        try:
+            return f(*a)
+        except dbus.exceptions.DBusException, e:
+            if obmc.dbuslib.enums.DBUS_UNKNOWN_INTERFACE in \
+                    e.get_dbus_message():
+                # interface doesn't have any properties
+                return None
+            if obmc.dbuslib.enums.DBUS_UNKNOWN_METHOD == e.get_dbus_name():
+                # properties interface not implemented at all
+                return None
+            raise
+
+    @staticmethod
+    def __get_properties_on_iface(properties_iface, iface):
+        properties = Mapper.__try_properties_interface(
+            properties_iface.GetAll, iface)
+        if properties is None:
+            return {}
+        return properties
+
+    def __get_properties_on_bus(self, path, bus, interfaces, match):
+        properties = {}
+        obj = self.bus.get_object(bus, path, introspect=False)
+        properties_iface = dbus.Interface(
+            obj, dbus_interface=dbus.PROPERTIES_IFACE)
+        for i in interfaces:
+            if not match(i):
+                continue
+            properties.update(self.__get_properties_on_iface(
+                properties_iface, i))
+
+        return properties
+
+    def enumerate_object(
+            self, path,
+            match=obmc.utils.misc.org_dot_openbmc_match,
+            mapper_data=None):
+        if mapper_data is None:
+            mapper_data = {path: self.get_object(path)}
+
+        obj = {}
+
+        for owner, interfaces in mapper_data[path].iteritems():
+            obj.update(
+                self.__get_properties_on_bus(
+                    path, owner, interfaces, match))
+
+        return obj
+
+    def enumerate_subtree(
+            self, path='/',
+            match=obmc.utils.misc.org_dot_openbmc_match,
+            mapper_data=None):
+        if mapper_data is None:
+            mapper_data = self.get_subtree(path)
+        managers = {}
+        owners = []
+
+        # look for objectmanager implementations as they result
+        # in fewer dbus calls
+        for path, bus_data in mapper_data.iteritems():
+            for owner, interfaces in bus_data.iteritems():
+                owners.append(owner)
+                if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces:
+                    managers[owner] = path
+
+        # also look in the parent objects
+        ancestors = self.get_ancestors(path)
+
+        # finally check the root for one too
+        try:
+            ancestors.update({path: self.get_object(path)})
+        except dbus.exceptions.DBusException, e:
+            if e.get_dbus_name() != MAPPER_NOT_FOUND:
+                raise
+
+        for path, bus_data in ancestors.iteritems():
+            for owner, interfaces in bus_data.iteritems():
+                if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces:
+                    managers[owner] = path
+
+        # make all the manager gmo (get managed objects) calls
+        results = {}
+        for owner, path in managers.iteritems():
+            if owner not in owners:
+                continue
+            obj = self.bus.get_object(owner, path, introspect=False)
+            iface = dbus.Interface(
+                obj, dbus.BUS_DAEMON_IFACE + '.ObjectManager')
+
+            # flatten (remove interface names) gmo results
+            for path, interfaces in iface.GetManagedObjects().iteritems():
+                if path not in mapper_data.iterkeys():
+                    continue
+                properties = {}
+                for iface, props in interfaces.iteritems():
+                    properties.update(props)
+                results.setdefault(path, {}).setdefault(owner, properties)
+
+        # make dbus calls for any remaining objects
+        for path, bus_data in mapper_data.iteritems():
+            for owner, interfaces in bus_data.iteritems():
+                if results.setdefault(path, {}).setdefault(owner, {}):
+                    continue
+                results[path][owner].update(
+                    self.__get_properties_on_bus(
+                        path, owner, interfaces, match))
+
+        objs = obmc.utils.pathtree.PathTree()
+        for path, owners in results.iteritems():
+            for owner, properties in owners.iteritems():
+                objs.setdefault(path, {}).update(properties)
+
+        return objs
