diff --git a/obmc/mapper.py b/obmc/mapper.py
deleted file mode 100644
index ab23524..0000000
--- a/obmc/mapper.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# 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() != obmc.mapper.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
