diff --git a/Makefile.am b/Makefile.am
index fe71472..5fe5662 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,28 +36,6 @@
 
 include_HEADERS = libmapper/mapper.h
 
-if HAVE_PYTHON
-
-all-local:
-	$(AM_V_at)$(PYTHON) ${top_builddir}/setup.py build
-
-clean-local:
-	rm -rfv ${top_builddir}/build
-
-install-exec-hook:
-	$(AM_V_at)$(PYTHON) ${top_builddir}/setup.py install \
-	--prefix=$(DESTDIR)${prefix} \
-	--install-data=$(DESTDIR)${datadir} \
-	--install-lib=$(DESTDIR)$(PYTHONDIR) \
-	--install-scripts=$(DESTDIR)${sbindir} \
-	--record=${top_builddir}/python_install.log
-
-uninstall-hook:
-	cat ${top_builddir}/python_install.log \
-	| $(AWK) '{print "$(DESTDIR)"$$1}' | xargs rm -fv
-
-endif
-
 SUBDIRS = fail-monitor
 
 check_PROGRAMS =
diff --git a/configure.ac b/configure.ac
index 030e72a..104c2df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,11 +18,6 @@
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
 AC_PROG_AWK
-# Python
-AM_PATH_PYTHON([2.7], [AC_SUBST([PYTHON], [echo "$PYTHON"])], [AC_MSG_ERROR([Could not find python-2.7 installed...python-2.7 is required])])
-AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :])
-AC_SUBST([HAVE_PYTHON])
-AC_SUBST([PYTHONDIR], ${pythondir})
 
 # Checks for libraries.
 PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus])
@@ -166,5 +161,5 @@
 )
 
 # Create configured output
-AC_CONFIG_FILES([Makefile setup.py fail-monitor/Makefile])
+AC_CONFIG_FILES([Makefile fail-monitor/Makefile])
 AC_OUTPUT
diff --git a/obmc/mapper/__init__.py b/obmc/mapper/__init__.py
deleted file mode 100644
index 679b9c8..0000000
--- a/obmc/mapper/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import obmc.mapper.bindings
-from obmc.mapper.bindings import Mapper
-from obmc.mapper.bindings import MAPPER_NAME
-from obmc.mapper.bindings import MAPPER_IFACE
-from obmc.mapper.bindings import MAPPER_PATH
-from obmc.mapper.bindings import MAPPER_NOT_FOUND
diff --git a/obmc/mapper/bindings.py b/obmc/mapper/bindings.py
deleted file mode 100644
index 8024105..0000000
--- a/obmc/mapper/bindings.py
+++ /dev/null
@@ -1,207 +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.pathtree
-
-
-MAPPER_NAME = 'xyz.openbmc_project.ObjectMapper'
-MAPPER_IFACE = MAPPER_NAME
-MAPPER_PATH = '/xyz/openbmc_project/object_mapper'
-MAPPER_NOT_FOUND = 'org.freedesktop.DBus.Error.FileNotFound'
-
-# The default D-Bus interfaces that we don't need to get
-# properties on during an enumerate.
-DEFAULT_IFACES = ['org.freedesktop.DBus.Introspectable',
-                  'org.freedesktop.DBus.Peer',
-                  'org.freedesktop.DBus.Properties']
-
-
-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)
-
-    @staticmethod
-    def retry(func, retries, interval):
-        e = None
-        count = 0
-        while count < retries:
-            try:
-                return func()
-            except dbus.exceptions.DBusException as e:
-                if e.get_dbus_name() not in \
-                    ['org.freedesktop.DBus.Error.ObjectPathInUse',
-                     'org.freedesktop.DBus.Error.LimitsExceeded']:
-                    raise
-
-                count += 1
-                if interval > 0:
-                    from time import sleep
-                    sleep(interval)
-        if e:
-            raise e
-
-    def get_object(self, path, retries=5, interfaces=[], interval=0.2):
-        return self.retry(
-            lambda: self.iface.GetObject(
-                path, interfaces, signature='sas'),
-            retries, interval)
-
-    def get_subtree_paths(
-            self, path='/', depth=0, retries=5, interfaces=[], interval=0.2):
-        return self.retry(
-            lambda: self.iface.GetSubTreePaths(
-                path, depth, interfaces, signature='sias'),
-            retries, interval)
-
-    def get_subtree(
-            self, path='/', depth=0, retries=5, interfaces=[], interval=0.2):
-        return self.retry(
-            lambda: self.iface.GetSubTree(
-                path, depth, interfaces, signature='sias'),
-            retries, interval)
-
-    def get_ancestors(self, path, retries=5, interfaces=[], interval=0.2):
-        return self.retry(
-            lambda: self.iface.GetAncestors(
-                path, interfaces, signature='sas'),
-            retries, interval)
-
-    @staticmethod
-    def __try_properties_interface(f, *a):
-        try:
-            return f(*a)
-        except dbus.exceptions.DBusException as e:
-            if obmc.dbuslib.enums.DBUS_UNKNOWN_INTERFACE in \
-                    e.get_dbus_name():
-                # 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 match and not match(i):
-                continue
-            if i in DEFAULT_IFACES:
-                continue
-            properties.update(self.__get_properties_on_iface(
-                properties_iface, i))
-
-        return properties
-
-    def enumerate_object(
-            self, path,
-            match=lambda x: x != dbus.BUS_DAEMON_IFACE + '.ObjectManager',
-            mapper_data=None):
-        if mapper_data is None:
-            mapper_data = {path: self.get_object(path)}
-
-        obj = {}
-
-        for owner, interfaces in mapper_data[path].items():
-            obj.update(
-                self.__get_properties_on_bus(
-                    path, owner, interfaces, match))
-
-        return obj
-
-    def enumerate_subtree(
-            self, path='/',
-            match=lambda x: x != dbus.BUS_DAEMON_IFACE + '.ObjectManager',
-            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.items():
-            for owner, interfaces in bus_data.items():
-                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 as e:
-            if e.get_dbus_name() != MAPPER_NOT_FOUND:
-                raise
-
-        for path, bus_data in ancestors.items():
-            for owner, interfaces in bus_data.items():
-                if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces:
-                    managers[owner] = path
-
-        mapper_keys = set(mapper_data.keys())
-
-        # make all the manager gmo (get managed objects) calls
-        results = {}
-        for owner, path in managers.items():
-            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().items():
-                if path not in mapper_keys:
-                    continue
-                properties = {}
-                for iface, props in interfaces.items():
-                    properties.update(props)
-                results.setdefault(path, {}).setdefault(owner, properties)
-
-        # make dbus calls for any remaining objects
-        for path, bus_data in mapper_data.items():
-            for owner, interfaces in bus_data.items():
-                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.items():
-            for owner, properties in owners.items():
-                objs.setdefault(path, {}).update(properties)
-
-        return objs
diff --git a/obmc/mapper/server.py b/obmc/mapper/server.py
deleted file mode 100644
index 4a6ce16..0000000
--- a/obmc/mapper/server.py
+++ /dev/null
@@ -1,803 +0,0 @@
-# Contributors Listed Below - COPYRIGHT 2017
-# [+] 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 dbus.service
-import dbus.exceptions
-import dbus.mainloop.glib
-# TODO: openbmc/openbmc#2994 remove python 2 support
-try:  # python 2
-    import gobject
-except ImportError:  # python 3
-    from gi.repository import GObject as gobject
-import xml.etree.ElementTree as ET
-import obmc.utils.pathtree
-import obmc.mapper
-import obmc.dbuslib.bindings
-import obmc.dbuslib.enums
-import sys
-import traceback
-from itertools import chain
-
-
-class MapperNotFoundException(dbus.exceptions.DBusException):
-    _dbus_error_name = obmc.mapper.MAPPER_NOT_FOUND
-
-    def __init__(self, path):
-        super(MapperNotFoundException, self).__init__(
-            "path or object not found: %s" % path)
-
-
-def find_dbus_interfaces(conn, service, path, callback, error_callback, **kw):
-    iface_match = kw.pop('iface_match', bool)
-
-    class _FindInterfaces(object):
-        def __init__(self):
-            self.results = {}
-            self.introspect_pending = []
-            self.gmo_pending = []
-            self.assoc_pending = []
-
-        @staticmethod
-        def _to_path(elements):
-            return '/' + '/'.join(elements)
-
-        @staticmethod
-        def _to_path_elements(path):
-            return filter(bool, path.split('/'))
-
-        def __call__(self, path):
-            try:
-                self._find_interfaces(path)
-            except Exception as e:
-                error_callback(service, path, e)
-
-        @staticmethod
-        def _match(iface):
-            return iface == dbus.BUS_DAEMON_IFACE + '.ObjectManager' \
-                or iface_match(iface)
-
-        def check_done(self):
-            if any([
-                    self.introspect_pending,
-                    self.gmo_pending,
-                    self.assoc_pending]):
-                return
-
-            callback(service, self.results)
-
-        def _assoc_callback(self, path, associations):
-            try:
-                iface = obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE
-                self.assoc_pending.remove(path)
-                self.results[path][iface]['associations'] = associations
-            except Exception as e:
-                error_callback(service, path, e)
-                return None
-
-            self.check_done()
-
-        def _gmo_callback(self, path, objs):
-            try:
-                self.gmo_pending.remove(path)
-                for k, v in objs.items():
-                    self.results[k] = dict(x for x in v.items()
-                                           if iface_match(x[0]))
-            except Exception as e:
-                error_callback(service, path, e)
-                return None
-
-            self.check_done()
-
-        def _introspect_callback(self, path, data):
-            self.introspect_pending.remove(path)
-            if data is None:
-                self.check_done()
-                return
-
-            try:
-                path_elements = self._to_path_elements(path)
-                root = ET.fromstring(data)
-                all_ifaces = root.findall('interface')
-                ifaces = filter(self._match,
-                                [x.attrib.get('name') for x in all_ifaces])
-                ifaces = {x: {} for x in ifaces}
-                self.results[path] = ifaces
-
-                if obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE in ifaces:
-                    obj = conn.get_object(service, path, introspect=False)
-                    iface = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
-                    self.assoc_pending.append(path)
-                    iface.Get.call_async(
-                        obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE,
-                        'associations',
-                        reply_handler=lambda x: self._assoc_callback(
-                            path, x),
-                        error_handler=lambda e: error_callback(
-                            service, path, e))
-
-                if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in ifaces:
-                    obj = conn.get_object(service, path, introspect=False)
-                    iface = dbus.Interface(
-                        obj, dbus.BUS_DAEMON_IFACE + '.ObjectManager')
-                    self.gmo_pending.append(path)
-                    iface.GetManagedObjects.call_async(
-                        reply_handler=lambda x: self._gmo_callback(
-                            path, x),
-                        error_handler=lambda e: error_callback(
-                            service, path, e))
-                else:
-                    children = filter(
-                        bool,
-                        [x.attrib.get('name') for x in root.findall('node')])
-                    children = [
-                        self._to_path(chain(path_elements,
-                                            self._to_path_elements(x)))
-                        for x in sorted(children)]
-                    for child in children:
-                        if child not in self.results:
-                            self._find_interfaces(child)
-            except Exception as e:
-                error_callback(service, path, e)
-                return None
-
-            self.check_done()
-
-        def _find_interfaces(self, path):
-            path = self._to_path(self._to_path_elements(path))
-            obj = conn.get_object(service, path, introspect=False)
-            iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
-            self.introspect_pending.append(path)
-            iface.Introspect.call_async(
-                reply_handler=lambda x: self._introspect_callback(path, x),
-                error_handler=lambda x: error_callback(service, path, x))
-
-    return _FindInterfaces()(path)
-
-
-@obmc.dbuslib.bindings.add_interfaces([obmc.dbuslib.enums.OBMC_ASSOC_IFACE])
-class Association(obmc.dbuslib.bindings.DbusProperties):
-    """Implementation of org.openbmc.Association."""
-
-    iface = obmc.dbuslib.enums.OBMC_ASSOC_IFACE
-
-    def __init__(self, bus, path, endpoints):
-        """Construct an Association.
-
-        Arguments:
-        bus -- The python-dbus connection to host the interface
-        path -- The D-Bus object path on which to implement the interface
-        endpoints -- A list of the initial association endpoints
-        """
-        super(Association, self).__init__(conn=bus, object_path=path)
-        self.properties = {self.iface: {'endpoints': endpoints}}
-        self.unmask_signals()
-
-
-class Manager(obmc.dbuslib.bindings.DbusObjectManager):
-    def __init__(self, bus, path):
-        super(Manager, self).__init__(conn=bus, object_path=path)
-
-
-class ObjectMapper(dbus.service.Object):
-    def __init__(
-            self, bus, path, namespaces, service_namespaces,
-            interface_namespaces, blacklist, service_blacklist,
-            interface_blacklist):
-        super(ObjectMapper, self).__init__(bus, path)
-        self.cache = obmc.utils.pathtree.PathTree()
-        self.bus = bus
-        self.service = None
-        self.index = {}
-        self.manager = Manager(bus, obmc.dbuslib.bindings.OBJ_PREFIX)
-        self.bus_map = {}
-        self.defer_signals = {}
-        self.namespaces = namespaces
-        self.service_namespaces = service_namespaces
-        self.interface_namespaces = interface_namespaces
-        self.blacklist = blacklist
-        self.blacklist.append(obmc.mapper.MAPPER_PATH)
-        self.service_blacklist = service_blacklist
-        self.interface_blacklist = interface_blacklist
-
-        # add my object mananger instance
-        self.add_new_objmgr(
-            obmc.dbuslib.bindings.OBJ_PREFIX, obmc.mapper.MAPPER_NAME)
-
-        self.bus.add_signal_receiver(
-            self.bus_handler,
-            dbus_interface=dbus.BUS_DAEMON_IFACE,
-            signal_name='NameOwnerChanged')
-        self.bus.add_signal_receiver(
-            self.interfaces_added_handler,
-            dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager',
-            signal_name='InterfacesAdded',
-            sender_keyword='sender',
-            path_keyword='sender_path')
-        self.bus.add_signal_receiver(
-            self.interfaces_removed_handler,
-            dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager',
-            signal_name='InterfacesRemoved',
-            sender_keyword='sender',
-            path_keyword='sender_path')
-        self.bus.add_signal_receiver(
-            self.properties_changed_handler,
-            dbus_interface=dbus.PROPERTIES_IFACE,
-            signal_name='PropertiesChanged',
-            arg0=obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE,
-            path_keyword='path',
-            sender_keyword='sender')
-
-        print("ObjectMapper startup complete.  Discovery in progress...")
-        self.discover()
-        gobject.idle_add(self.claim_name)
-
-    def claim_name(self):
-        if len(self.defer_signals):
-            return True
-        print("ObjectMapper discovery complete")
-        self.service = dbus.service.BusName(
-            obmc.mapper.MAPPER_NAME, self.bus)
-        self.manager.unmask_signals()
-        return False
-
-    def discovery_callback(self, owner, items):
-        if owner in self.defer_signals:
-            self.add_items(owner, items)
-            pending = self.defer_signals[owner]
-            del self.defer_signals[owner]
-
-            for x in pending:
-                x()
-            self.IntrospectionComplete(owner)
-
-    def discovery_error(self, owner, path, e):
-        '''Log a message and remove all traces of the service
-        we were attempting to introspect.'''
-
-        if owner in self.defer_signals:
-
-            # Safe to add a reference to the traceback here,
-            # since it cannot contain the discovery_error frame.
-            exctype, value, tb = sys.exc_info()
-            sys.stderr.write(
-                '{} discovery failure on {}\n'.format(owner, path))
-            if tb:
-                traceback.print_exception(exctype, value, tb, file=sys.stderr)
-            else:
-                sys.stderr.write('{}: {}\n'.format(e.__class__.__name__, e))
-
-            del self.defer_signals[owner]
-            del self.bus_map[owner]
-
-    def cache_get(self, path):
-        cache_entry = self.cache.get(path, {})
-        if cache_entry is None:
-            # hide path elements without any interfaces
-            cache_entry = {}
-        return cache_entry
-
-    def add_new_objmgr(self, path, owner):
-        # We don't get a signal for the ObjectManager
-        # interface itself, so if we see a signal from
-        # make sure its in our cache, and add it if not.
-        cache_entry = self.cache_get(path)
-        old = self.interfaces_get(cache_entry, owner)
-        new = set(old).union([dbus.BUS_DAEMON_IFACE + '.ObjectManager'])
-        self.update_interfaces(path, owner, old, new)
-
-    def defer_signal(self, owner, callback):
-        self.defer_signals.setdefault(owner, []).append(callback)
-
-    def interfaces_added_handler(self, path, iprops, **kw):
-        path = str(path)
-        owner = self.bus_normalize(str(kw['sender']))
-        if not owner:
-            return
-        interfaces = self.filter_signal_interfaces(iprops.keys())
-        if not interfaces:
-            return
-
-        if owner not in self.defer_signals:
-            self.add_new_objmgr(str(kw['sender_path']), owner)
-            cache_entry = self.cache_get(path)
-            old = self.interfaces_get(cache_entry, owner)
-            new = set(interfaces).union(old)
-            new = {x: iprops.get(x, {}) for x in new}
-            self.update_interfaces(path, owner, old, new)
-        else:
-            self.defer_signal(
-                owner,
-                lambda: self.interfaces_added_handler(
-                    path, iprops, **kw))
-
-    def interfaces_removed_handler(self, path, interfaces, **kw):
-        path = str(path)
-        owner = self.bus_normalize(str(kw['sender']))
-        if not owner:
-            return
-        interfaces = self.filter_signal_interfaces(interfaces)
-        if not interfaces:
-            return
-
-        if owner not in self.defer_signals:
-            self.add_new_objmgr(str(kw['sender_path']), owner)
-            cache_entry = self.cache_get(path)
-            old = self.interfaces_get(cache_entry, owner)
-            new = set(old).difference(interfaces)
-            self.update_interfaces(path, owner, old, new)
-        else:
-            self.defer_signal(
-                owner,
-                lambda: self.interfaces_removed_handler(
-                    path, interfaces, **kw))
-
-    def properties_changed_handler(self, interface, new, old, **kw):
-        owner = self.bus_normalize(str(kw['sender']))
-        path = str(kw['path'])
-        if not owner:
-            return
-        interfaces = self.filter_signal_interfaces([interface])
-        if not self.is_association(interfaces):
-            return
-        associations = new.get('associations', None)
-        if associations is None:
-            return
-
-        if owner not in self.defer_signals:
-            associations = [
-                (str(x), str(y), str(z)) for x, y, z in associations]
-            self.update_associations(
-                path, owner,
-                self.index_get_associations(path, [owner]),
-                associations)
-        else:
-            self.defer_signal(
-                owner,
-                lambda: self.properties_changed_handler(
-                    interface, new, old, **kw))
-
-    def process_new_owner(self, owned_name, owner):
-        # unique name
-        try:
-            if self.busname_match(owned_name):
-                self.discover([(owned_name, owner)])
-        except dbus.exceptions.DBusException as e:
-            if obmc.dbuslib.enums.DBUS_UNKNOWN_SERVICE \
-                    not in e.get_dbus_name():
-                raise
-
-    def process_old_owner(self, owned_name, owner):
-        if owner in self.bus_map:
-            del self.bus_map[owner]
-
-        for path, item in self.cache.dataitems():
-            old = self.interfaces_get(item, owned_name)
-            if old:
-                # remove all interfaces for this service
-                self.update_interfaces(
-                    path, owned_name, old=old, new=[])
-
-    def bus_handler(self, owned_name, old, new):
-        if obmc.dbuslib.bindings.is_unique(owned_name) or \
-                owned_name == obmc.mapper.MAPPER_NAME:
-            return
-
-        if new:
-            self.process_new_owner(owned_name, new)
-        if old:
-            # discard any unhandled signals
-            # or in progress discovery
-            if owned_name in self.defer_signals:
-                del self.defer_signals[owned_name]
-
-            self.process_old_owner(owned_name, old)
-
-    def update_interfaces(self, path, owner, old, new):
-        # __xx -> intf list
-        # xx -> intf dict
-        if isinstance(old, dict):
-            __old = old.keys()
-        else:
-            __old = old
-            old = {x: {} for x in old}
-        if isinstance(new, dict):
-            __new = new.keys()
-        else:
-            __new = new
-            new = {x: {} for x in new}
-
-        cache_entry = self.cache.setdefault(path, {})
-        created = [] if self.has_interfaces(cache_entry) else [path]
-        added = set(__new).difference(__old)
-        removed = set(__old).difference(__new)
-        self.interfaces_append(cache_entry, owner, added)
-        self.interfaces_remove(cache_entry, owner, removed, path)
-        destroyed = [] if self.has_interfaces(cache_entry) else [path]
-
-        # react to anything that requires association updates
-        new_assoc = []
-        old_assoc = []
-        if self.is_association(added):
-            iface = obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE
-            new_assoc = new[iface]['associations']
-        if self.is_association(removed):
-            old_assoc = self.index_get_associations(path, [owner])
-        self.update_associations(
-            path, owner, old_assoc, new_assoc, created, destroyed)
-
-    def add_items(self, owner, bus_items):
-        for path, items in bus_items.items():
-            self.update_interfaces(path, str(owner), old=[], new=items)
-
-    def busname_match(self, busname):
-        match = False
-
-        if not any([x for x in self.service_blacklist if x in busname]):
-            # not blacklisted
-
-            if any([x for x in self.service_namespaces if x in busname]):
-                # a watched busname contains the path
-                match = True
-            elif any([busname for x in self.service_namespaces
-                     if busname in x]):
-                # the busname contains a watched namespace
-                match = True
-
-        return match
-
-    def interface_match(self, interface):
-        match = True
-
-        if any([x for x in self.interface_blacklist if x in interface]):
-            # not blacklisted
-            match = False
-        elif not any([x for x in self.interface_namespaces if x in interface]):
-            # the interface contains a watched interface namespace
-            match = False
-
-        return match
-
-    def discovery_error_retry(self, owner, path, e):
-        sys.stderr.write(
-            '{} discovery failure on {} - retry\n'.format(owner, path))
-        find_dbus_interfaces(self.bus, owner, '/',
-                             self.discovery_callback,
-                             self.discovery_error,
-                             iface_match=self.interface_match)
-
-    def discover(self, owners=None):
-        if owners is None:
-            owners = []
-
-        def get_owner(name):
-            try:
-                return (name, self.bus.get_name_owner(name))
-            except Exception:
-                traceback.print_exception(*sys.exc_info())
-
-        if not owners:
-            owned_names = [
-                x for x in filter(self.busname_match, self.bus.list_names())
-                if not obmc.dbuslib.bindings.is_unique(x)]
-            owners = filter(bool, (get_owner(name) for name in owned_names))
-        for owned_name, o in owners:
-            if not self.bus_normalize(owned_name):
-                continue
-            self.bus_map[o] = owned_name
-            self.defer_signals[owned_name] = []
-            find_dbus_interfaces(
-                self.bus, owned_name, '/',
-                self.discovery_callback,
-                self.discovery_error_retry,
-                iface_match=self.interface_match)
-
-    def bus_normalize(self, name):
-        '''
-        Normalize on well-known names and filter signals
-        originating from the mapper.
-        '''
-
-        if obmc.dbuslib.bindings.is_unique(name):
-            name = self.bus_map.get(name)
-
-        if name == obmc.mapper.MAPPER_NAME:
-            return None
-
-        return name
-
-    def filter_signal_interfaces(self, interfaces):
-        return [str(x) for x in interfaces if self.interface_match(x)]
-
-    @staticmethod
-    def interfaces_get(item, owner, default=None):
-        if default is None:
-            default = []
-        return item.get(owner, default)
-
-    @staticmethod
-    def interfaces_append(item, owner, append):
-        interfaces = item.setdefault(owner, [])
-        item[owner] = list(set(append).union(interfaces))
-
-    def interfaces_remove(self, item, owner, remove, path):
-        interfaces = item.get(owner, [])
-        item[owner] = list(set(interfaces).difference(remove))
-
-        if not item[owner]:
-            # remove the owner if there aren't any interfaces left
-            del item[owner]
-
-        if item:
-            # other owners remain
-            return
-
-        if self.cache.get_children(path):
-            # there are still references to this path
-            # from objects further down the tree.
-            # mark it for removal if that changes
-            self.cache.demote(path)
-        else:
-            # delete the entire path if everything is gone
-            del self.cache[path]
-
-    @staticmethod
-    def filter_interfaces(item, ifaces):
-        return ObjectMapper._filter_interfaces(item, set(ifaces))
-
-    @staticmethod
-    def _filter_interfaces(item, ifaces):
-        if isinstance(item, dict):
-            # Called with a single object.
-            if not ifaces:
-                return item
-
-            filtered = dict()
-            for k, v in item.items():
-                isec = ifaces.intersection(v)
-                if isec:
-                    filtered[k] = isec
-
-            return filtered
-
-        # Called with a list of path/object tuples.
-        if not ifaces:
-            return dict(item)
-
-        if not item:
-            return dict()
-
-        filtered = dict()
-        for i in item:
-            children = ObjectMapper._filter_interfaces(i[1], ifaces)
-            if children:
-                filtered[i[0]] = children
-
-        return filtered
-
-    @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sas', 'a{sas}')
-    def GetObject(self, path, interfaces):
-        o = self.cache_get(path)
-        if not o:
-            raise MapperNotFoundException(path)
-
-        return self.filter_interfaces(o, interfaces)
-
-    @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sias', 'as')
-    def GetSubTreePaths(self, path, depth, interfaces):
-        try:
-            return self.filter_interfaces(
-                self.cache.iteritems(path, depth),
-                interfaces)
-        except KeyError:
-            raise MapperNotFoundException(path)
-
-    @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sias', 'a{sa{sas}}')
-    def GetSubTree(self, path, depth, interfaces):
-        try:
-            return self.filter_interfaces(
-                self.cache.dataitems(path, depth),
-                interfaces)
-        except KeyError:
-            raise MapperNotFoundException(path)
-
-    @staticmethod
-    def has_interfaces(item):
-        return any(item.values())
-
-    @staticmethod
-    def is_association(interfaces):
-        return obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE in interfaces
-
-    def index_get(self, index, path, owners):
-        items = []
-        item = self.index.get(index, {})
-        item = item.get(path, {})
-        for o in owners:
-            items.extend(item.get(o, []))
-        return items
-
-    def index_append(self, index, path, owner, assoc):
-        item = self.index.setdefault(index, {})
-        item = item.setdefault(path, {})
-        item = item.setdefault(owner, [])
-        item.append(assoc)
-
-    def index_remove(self, index, path, owner, assoc):
-        index = self.index.get(index, {})
-        owners = index.get(path, {})
-        items = owners.get(owner, [])
-        if assoc in items:
-            items.remove(assoc)
-        if not items:
-            del owners[owner]
-        if not owners:
-            del index[path]
-
-    def index_get_associations(self, path, owners=[], direction='forward'):
-        forward = 'forward' if direction == 'forward' else 'reverse'
-        reverse = 'reverse' if direction == 'forward' else 'forward'
-
-        associations = []
-        if not owners:
-            index = self.index.get(forward, {})
-            owners = index.get(path, {}).keys()
-
-        # f: forward
-        # r: reverse
-        for rassoc in self.index_get(forward, path, owners):
-            elements = rassoc.split('/')
-            rtype = ''.join(elements[-1:])
-            fendpoint = '/'.join(elements[:-1])
-            for fassoc in self.index_get(reverse, fendpoint, owners):
-                elements = fassoc.split('/')
-                ftype = ''.join(elements[-1:])
-                rendpoint = '/'.join(elements[:-1])
-                if rendpoint != path:
-                    continue
-                associations.append((ftype, rtype, fendpoint))
-
-        return associations
-
-    def update_association(self, path, removed, added):
-        iface = obmc.dbuslib.enums.OBMC_ASSOC_IFACE
-        assoc = self.manager.get(path, None)
-
-        old_endpoints = set(assoc.Get(iface, 'endpoints') if assoc else [])
-        new_endpoints = old_endpoints.union(added).difference(removed)
-
-        if old_endpoints == new_endpoints:
-            return
-
-        create = [] if old_endpoints else [iface]
-        delete = [] if new_endpoints else [iface]
-
-        if create:
-            self.manager.add(
-                path, Association(self.bus, path, list(new_endpoints)))
-        elif delete:
-            self.manager.remove(path)
-        else:
-            assoc.Set(iface, 'endpoints', list(new_endpoints))
-
-        if create != delete:
-            self.update_interfaces(
-                path, obmc.mapper.MAPPER_NAME, delete, create)
-
-    def update_associations(
-            self, path, owner, old, new, created=[], destroyed=[]):
-        added = set(new).difference(old)
-        removed = set(old).difference(new)
-        for forward, reverse, endpoint in added:
-            if not endpoint:
-                # skip associations without an endpoint
-                continue
-
-            # update the index
-            forward_path = str(path + '/' + forward)
-            reverse_path = str(endpoint + '/' + reverse)
-            self.index_append(
-                'forward', path, owner, reverse_path)
-            self.index_append(
-                'reverse', endpoint, owner, forward_path)
-
-            # create the association if the endpoint exists
-            if not self.cache_get(endpoint):
-                continue
-
-            self.update_association(forward_path, [], [endpoint])
-            self.update_association(reverse_path, [], [path])
-
-        for forward, reverse, endpoint in removed:
-            # update the index
-            forward_path = str(path + '/' + forward)
-            reverse_path = str(endpoint + '/' + reverse)
-            self.index_remove(
-                'forward', path, owner, reverse_path)
-            self.index_remove(
-                'reverse', endpoint, owner, forward_path)
-
-            # destroy the association if it exists
-            self.update_association(forward_path, [endpoint], [])
-            self.update_association(reverse_path, [path], [])
-
-        # If the associations interface endpoint comes
-        # or goes create or destroy the appropriate
-        # associations
-        for path in created:
-            for forward, reverse, endpoint in \
-                    self.index_get_associations(path, direction='reverse'):
-                forward_path = str(path + '/' + forward)
-                reverse_path = str(endpoint + '/' + reverse)
-                self.update_association(forward_path, [], [endpoint])
-                self.update_association(reverse_path, [], [path])
-
-        for path in destroyed:
-            for forward, reverse, endpoint in \
-                    self.index_get_associations(path, direction='reverse'):
-                forward_path = str(path + '/' + forward)
-                reverse_path = str(endpoint + '/' + reverse)
-                self.update_association(forward_path, [endpoint], [])
-                self.update_association(reverse_path, [path], [])
-
-    @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'sas', 'a{sa{sas}}')
-    def GetAncestors(self, path, interfaces):
-        if not self.cache_get(path):
-            raise MapperNotFoundException(path)
-
-        objs = {}
-
-        def parents(path):
-            yield "/"
-            parent = ""
-            for elem in (x for x in list(filter(bool, path.split('/')))[:-1]):
-                parent += "/" + elem
-                yield parent
-
-        for parent in parents(path):
-            obj = self.cache_get(parent)
-            if not obj:
-                continue
-            objs[parent] = obj
-
-        return self.filter_interfaces(objs.items(), interfaces)
-
-    @dbus.service.signal(obmc.mapper.MAPPER_IFACE + '.Private', 's')
-    def IntrospectionComplete(self, name):
-        pass
-
-
-def server_main(
-        path_namespaces,
-        service_namespaces,
-        interface_namespaces,
-        blacklists,
-        service_blacklists,
-        interface_blacklists):
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-    bus = dbus.SystemBus()
-    o = ObjectMapper(
-        bus,
-        obmc.mapper.MAPPER_PATH,
-        path_namespaces,
-        service_namespaces,
-        interface_namespaces,
-        blacklists,
-        service_blacklists,
-        interface_blacklists)
-    loop = gobject.MainLoop()
-
-    loop.run()
diff --git a/obmc/mapper/utils.py b/obmc/mapper/utils.py
deleted file mode 100644
index a7b93b2..0000000
--- a/obmc/mapper/utils.py
+++ /dev/null
@@ -1,130 +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 sys
-import dbus
-import dbus.mainloop.glib
-# TODO: openbmc/openbmc#2994 remove python 2 support
-try:  # python 2
-    import gobject
-except ImportError:  # python 3
-    from gi.repository import GObject as gobject
-import obmc.mapper
-
-
-class Wait(object):
-    def __init__(self, bus, waitlist, *a, **kw):
-        self.bus = bus
-        self.waitlist = dict(list(zip(waitlist, [None] * len(waitlist))))
-        mapper = bus.get_object(
-            obmc.mapper.MAPPER_NAME,
-            obmc.mapper.MAPPER_PATH,
-            introspect=False)
-        self.iface = dbus.Interface(
-            mapper, dbus_interface=obmc.mapper.MAPPER_IFACE)
-        self.done = False
-        self.callback = kw.pop('callback', None)
-        self.error_callback = kw.pop('error_callback', self.default_error)
-        self.busy_retries = kw.pop('busy_retries', 20)
-        self.busy_retry_delay_milliseconds = kw.pop(
-            'busy_retry_delay_milliseconds', 500)
-        self.waitlist_keyword = kw.pop('waitlist_keyword', None)
-
-        self.bus.add_signal_receiver(
-            self.introspection_handler,
-            dbus_interface=obmc.mapper.MAPPER_IFACE + '.Private',
-            signal_name='IntrospectionComplete')
-        self.bus.add_signal_receiver(
-            self.introspection_handler,
-            dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager')
-
-        self.introspection_handler()
-
-    @staticmethod
-    def default_error(e):
-        raise e
-
-    def force_done(self):
-        if self.done:
-            return
-
-        self.done = True
-        self.bus.remove_signal_receiver(
-            self.introspection_handler,
-            dbus_interface=obmc.mapper.MAPPER_IFACE + '.Private',
-            signal_name='IntrospectionComplete')
-        self.bus.remove_signal_receiver(
-            self.introspection_handler,
-            dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager',
-            signal_name='InterfacesAdded')
-
-    def check_done(self):
-        if not all(self.waitlist.values()) or self.done:
-            return
-
-        self.force_done()
-
-        if self.callback:
-            kwargs = {}
-            if self.waitlist_keyword:
-                kwargs[waitlist_keyword] = self.waitlist
-            self.callback(**kwargs)
-
-    def get_object_async(self, path, retry):
-        method = getattr(self.iface, 'GetObject')
-        method.call_async(
-            path,
-            [],
-            signature='sas',
-            reply_handler=lambda x: self.get_object_callback(
-                path, x),
-            error_handler=lambda x: self.get_object_error(
-                path, retry, x))
-        return False
-
-    def get_object_error(self, path, retry, e):
-        if self.done:
-            return
-
-        if e.get_dbus_name() == 'org.freedesktop.DBus.Error.FileNotFound':
-            pass
-        elif e.get_dbus_name() in \
-            ['org.freedesktop.DBus.Error.ObjectPathInUse',
-             'org.freedesktop.DBus.Error.LimitsExceeded']:
-            if retry > self.busy_retries:
-                self.force_done()
-                self.error_callback(e)
-            else:
-                gobject.timeout_add(
-                    self.busy_retry_delay_milliseconds,
-                    self.get_object_async,
-                    path,
-                    retry + 1)
-        else:
-            self.force_done()
-            self.error_callback(e)
-
-    def get_object_callback(self, path, info):
-        self.waitlist[path] = list(info)[0]
-        self.check_done()
-
-    def introspection_handler(self, *a, **kw):
-        if self.done:
-            return
-
-        for path in [
-                x for x in list(self.waitlist.keys()) if not self.waitlist[x]]:
-            self.get_object_async(path, 0)
diff --git a/phosphor-mapper b/phosphor-mapper
deleted file mode 100644
index 4303434..0000000
--- a/phosphor-mapper
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-
-# 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 sys
-import obmc.mapper.server
-from argparse import ArgumentParser
-
-if __name__ == '__main__':
-    parser = ArgumentParser()
-    parser.add_argument(
-        '-p', '--path_namespaces',
-        default="")
-    parser.add_argument(
-        '-s', '--service_namespaces',
-        required=True)
-    parser.add_argument(
-        '-i', '--interface_namespaces',
-        required=True)
-    parser.add_argument(
-        '-b', '--blacklists',
-        default="")
-    parser.add_argument(
-        '-x', '--service_blacklists',
-        default="")
-    parser.add_argument(
-        '-n', '--interface_blacklists',
-        default="")
-
-    args = parser.parse_args()
-
-    sys.exit(
-        obmc.mapper.server.server_main(
-            path_namespaces=args.path_namespaces.split(),
-            service_namespaces=args.service_namespaces.split(),
-            interface_namespaces=args.interface_namespaces.split(),
-            blacklists=args.blacklists.split(),
-            service_blacklists=args.service_blacklists.split(),
-            interface_blacklists=args.interface_blacklists.split()))
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index dedc13f..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-[pycodestyle]
-max-line-length = 80
-ignore = E731
diff --git a/setup.py.in b/setup.py.in
deleted file mode 100644
index b2f3907..0000000
--- a/setup.py.in
+++ /dev/null
@@ -1,7 +0,0 @@
-from distutils.core import setup
-setup(name='obmc.mapper',
-      version='1.0',
-      package_dir={'':'@top_srcdir@'},
-      packages=['obmc.mapper'],
-      scripts=['@top_srcdir@/phosphor-mapper']
-      )
