diff --git a/obmc-rest b/obmc-rest
new file mode 100644
index 0000000..f655599
--- /dev/null
+++ b/obmc-rest
@@ -0,0 +1,593 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import dbus
+import dbus.exceptions
+import json
+import logging
+from xml.etree import ElementTree
+from rocket import Rocket
+from bottle import Bottle, abort, request, response, JSONPlugin, HTTPError
+import OpenBMCMapper
+from OpenBMCMapper import Mapper, PathTree, IntrospectionNodeParser, ListMatch
+
+DBUS_UNKNOWN_INTERFACE = 'org.freedesktop.UnknownInterface'
+DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
+DBUS_INVALID_ARGS = 'org.freedesktop.DBus.Error.InvalidArgs'
+DELETE_IFACE = 'org.openbmc.object.Delete'
+
+_4034_msg = "The specified %s cannot be %s: '%s'"
+
+def find_case_insensitive(value, lst):
+	return next((x for x in lst if x.lower() == value.lower()), None)
+
+def makelist(data):
+	if isinstance(data, list):
+		return data
+	elif data:
+		return [data]
+	else:
+		return []
+
+class RouteHandler(object):
+	def __init__(self, app, bus, verbs, rules):
+		self.app = app
+		self.bus = bus
+		self.mapper = Mapper(bus)
+		self._verbs = makelist(verbs)
+		self._rules = rules
+
+	def _setup(self, **kw):
+		request.route_data = {}
+		if request.method in self._verbs:
+			return self.setup(**kw)
+		else:
+			self.find(**kw)
+			raise HTTPError(405, "Method not allowed.",
+					Allow=','.join(self._verbs))
+
+	def __call__(self, **kw):
+		return getattr(self, 'do_' + request.method.lower())(**kw)
+
+	def install(self):
+		self.app.route(self._rules, callback = self,
+				method = ['GET', 'PUT', 'PATCH', 'POST', 'DELETE'])
+
+	@staticmethod
+	def try_mapper_call(f, callback = None, **kw):
+		try:
+			return f(**kw)
+		except dbus.exceptions.DBusException, e:
+			if e.get_dbus_name() != OpenBMCMapper.MAPPER_NOT_FOUND:
+				raise
+			if callback is None:
+				def callback(e, **kw):
+					abort(404, str(e))
+
+			callback(e, **kw)
+
+	@staticmethod
+	def try_properties_interface(f, *a):
+		try:
+			return f(*a)
+		except dbus.exceptions.DBusException, e:
+			if DBUS_UNKNOWN_INTERFACE in e.get_dbus_message():
+				# interface doesn't have any properties
+				return None
+			if DBUS_UNKNOWN_METHOD == e.get_dbus_name():
+				# properties interface not implemented at all
+				return None
+			raise
+
+class DirectoryHandler(RouteHandler):
+	verbs = 'GET'
+	rules = '<path:path>/'
+
+	def __init__(self, app, bus):
+		super(DirectoryHandler, self).__init__(
+				app, bus, self.verbs, self.rules)
+
+	def find(self, path = '/'):
+		return self.try_mapper_call(
+				self.mapper.get_subtree_paths,
+				path = path, depth = 1)
+
+	def setup(self, path = '/'):
+		request.route_data['map'] = self.find(path)
+
+	def do_get(self, path = '/'):
+		return request.route_data['map']
+
+class ListNamesHandler(RouteHandler):
+	verbs = 'GET'
+	rules = ['/list', '<path:path>/list']
+
+	def __init__(self, app, bus):
+		super(ListNamesHandler, self).__init__(
+				app, bus, self.verbs, self.rules)
+
+	def find(self, path = '/'):
+		return self.try_mapper_call(
+				self.mapper.get_subtree, path = path).keys()
+
+	def setup(self, path = '/'):
+		request.route_data['map'] = self.find(path)
+
+	def do_get(self, path = '/'):
+		return request.route_data['map']
+
+class ListHandler(RouteHandler):
+	verbs = 'GET'
+	rules = ['/enumerate', '<path:path>/enumerate']
+
+	def __init__(self, app, bus):
+		super(ListHandler, self).__init__(
+				app, bus, self.verbs, self.rules)
+
+	def find(self, path = '/'):
+		return self.try_mapper_call(
+				self.mapper.get_subtree, path = path)
+
+	def setup(self, path = '/'):
+		request.route_data['map'] = self.find(path)
+
+	def do_get(self, path = '/'):
+		objs = {}
+		mapper_data = request.route_data['map']
+		tree = PathTree()
+		for x,y in mapper_data.iteritems():
+			tree[x] = y
+
+		try:
+			# Check to see if the root path implements
+			# enumerate in addition to any sub tree
+			# objects.
+			root = self.try_mapper_call(self.mapper.get_object,
+					path = path)
+			mapper_data[path] = root
+		except:
+			pass
+
+		have_enumerate = [ (x[0], self.enumerate_capable(*x)) \
+				for x in mapper_data.iteritems() \
+					if self.enumerate_capable(*x) ]
+
+		for x,y in have_enumerate:
+			objs.update(self.call_enumerate(x, y))
+			tmp = tree[x]
+			# remove the subtree
+			del tree[x]
+			# add the new leaf back since enumerate results don't
+			# include the object enumerate is being invoked on
+			tree[x] = tmp
+
+		# make dbus calls for any remaining objects
+		for x,y in tree.dataitems():
+			objs[x] = self.app.instance_handler.do_get(x)
+
+		return objs
+
+	@staticmethod
+	def enumerate_capable(path, bus_data):
+		busses = []
+		for name, ifaces in bus_data.iteritems():
+			if OpenBMCMapper.ENUMERATE_IFACE in ifaces:
+				busses.append(name)
+		return busses
+
+	def call_enumerate(self, path, busses):
+		objs = {}
+		for b in busses:
+			obj = self.bus.get_object(b, path, introspect = False)
+			iface = dbus.Interface(obj, OpenBMCMapper.ENUMERATE_IFACE)
+			objs.update(iface.enumerate())
+		return objs
+
+class MethodHandler(RouteHandler):
+	verbs = 'POST'
+	rules = '<path:path>/action/<method>'
+	request_type = list
+
+	def __init__(self, app, bus):
+		super(MethodHandler, self).__init__(
+				app, bus, self.verbs, self.rules)
+
+	def find(self, path, method):
+		busses = self.try_mapper_call(self.mapper.get_object,
+				path = path)
+		for items in busses.iteritems():
+			m = self.find_method_on_bus(path, method, *items)
+			if m:
+				return m
+
+		abort(404, _4034_msg %('method', 'found', method))
+
+	def setup(self, path, method):
+		request.route_data['method'] = self.find(path, method)
+
+	def do_post(self, path, method):
+		try:
+			if request.parameter_list:
+				return request.route_data['method'](*request.parameter_list)
+			else:
+				return request.route_data['method']()
+
+		except dbus.exceptions.DBusException, e:
+			if e.get_dbus_name() == DBUS_INVALID_ARGS:
+				abort(400, str(e))
+			raise
+
+	@staticmethod
+	def find_method_in_interface(method, obj, interface, methods):
+		if methods is None:
+			return None
+
+		method = find_case_insensitive(method, methods.keys())
+		if method is not None:
+			iface = dbus.Interface(obj, interface)
+			return iface.get_dbus_method(method)
+
+	def find_method_on_bus(self, path, method, bus, interfaces):
+		obj = self.bus.get_object(bus, path, introspect = False)
+		iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
+		data = iface.Introspect()
+		parser = IntrospectionNodeParser(
+				ElementTree.fromstring(data),
+				intf_match = ListMatch(interfaces))
+		for x,y in parser.get_interfaces().iteritems():
+			m = self.find_method_in_interface(method, obj, x,
+					y.get('method'))
+			if m:
+				return m
+
+class PropertyHandler(RouteHandler):
+	verbs = ['PUT', 'GET']
+	rules = '<path:path>/attr/<prop>'
+
+	def __init__(self, app, bus):
+		super(PropertyHandler, self).__init__(
+				app, bus, self.verbs, self.rules)
+
+	def find(self, path, prop):
+		self.app.instance_handler.setup(path)
+		obj = self.app.instance_handler.do_get(path)
+		try:
+			obj[prop]
+		except KeyError, e:
+			if request.method == 'PUT':
+				abort(403, _4034_msg %('property', 'created', str(e)))
+			else:
+				abort(404, _4034_msg %('property', 'found', str(e)))
+
+		return { path: obj }
+
+	def setup(self, path, prop):
+		request.route_data['obj'] = self.find(path, prop)
+
+	def do_get(self, path, prop):
+		return request.route_data['obj'][path][prop]
+
+	def do_put(self, path, prop, value = None):
+		if value is None:
+			value = request.parameter_list
+
+		prop, iface, properties_iface = self.get_host_interface(
+				path, prop, request.route_data['map'][path])
+		try:
+			properties_iface.Set(iface, prop, value)
+		except ValueError, e:
+			abort(400, str(e))
+		except dbus.exceptions.DBusException, e:
+			if e.get_dbus_name() == DBUS_INVALID_ARGS:
+				abort(403, str(e))
+			raise
+
+	def get_host_interface(self, path, prop, bus_info):
+		for bus, interfaces in bus_info.iteritems():
+			obj = self.bus.get_object(bus, path, introspect = True)
+			properties_iface = dbus.Interface(
+				obj, dbus_interface=dbus.PROPERTIES_IFACE)
+
+			info = self.get_host_interface_on_bus(
+					path, prop, properties_iface,
+					bus, interfaces)
+			if info is not None:
+				prop, iface = info
+				return prop, iface, properties_iface
+
+	def get_host_interface_on_bus(self, path, prop, iface, bus, interfaces):
+		for i in interfaces:
+			properties = self.try_properties_interface(iface.GetAll, i)
+			if properties is None:
+				continue
+			prop = find_case_insensitive(prop, properties.keys())
+			if prop is None:
+				continue
+			return prop, i
+
+class InstanceHandler(RouteHandler):
+	verbs = ['GET', 'PUT', 'DELETE']
+	rules = '<path:path>'
+	request_type = dict
+
+	def __init__(self, app, bus):
+		super(InstanceHandler, self).__init__(
+				app, bus, self.verbs, self.rules)
+
+	def find(self, path, callback = None):
+		return { path: self.try_mapper_call(
+			self.mapper.get_object,
+			callback,
+			path = path) }
+
+	def setup(self, path):
+		callback = None
+		if request.method == 'PUT':
+			def callback(e, **kw):
+				abort(403, _4034_msg %('resource',
+					'created', path))
+
+		if request.route_data.get('map') is None:
+			request.route_data['map'] = self.find(path, callback)
+
+	def do_get(self, path):
+		properties = {}
+		for item in request.route_data['map'][path].iteritems():
+			properties.update(self.get_properties_on_bus(
+				path, *item))
+
+		return properties
+
+	@staticmethod
+	def get_properties_on_iface(properties_iface, iface):
+		properties = InstanceHandler.try_properties_interface(
+				properties_iface.GetAll, iface)
+		if properties is None:
+			return {}
+		return properties
+
+	def get_properties_on_bus(self, path, bus, interfaces):
+		properties = {}
+		obj = self.bus.get_object(bus, path, introspect = False)
+		properties_iface = dbus.Interface(
+				obj, dbus_interface=dbus.PROPERTIES_IFACE)
+		for i in interfaces:
+			properties.update(self.get_properties_on_iface(
+				properties_iface, i))
+
+		return properties
+
+	def do_put(self, path):
+		# make sure all properties exist in the request
+		obj = set(self.do_get(path).keys())
+		req = set(request.parameter_list.keys())
+
+		diff = list(obj.difference(req))
+		if diff:
+			abort(403, _4034_msg %('resource', 'removed',
+				'%s/attr/%s' %(path, diff[0])))
+
+		diff = list(req.difference(obj))
+		if diff:
+			abort(403, _4034_msg %('resource', 'created',
+				'%s/attr/%s' %(path, diff[0])))
+
+		for p,v in request.parameter_list.iteritems():
+			self.app.property_handler.do_put(
+					path, p, v)
+
+	def do_delete(self, path):
+		for bus_info in request.route_data['map'][path].iteritems():
+			if self.bus_missing_delete(path, *bus_info):
+				abort(403, _4034_msg %('resource', 'removed',
+					path))
+
+		for bus in request.route_data['map'][path].iterkeys():
+			self.delete_on_bus(path, bus)
+
+	def bus_missing_delete(self, path, bus, interfaces):
+		return DELETE_IFACE not in interfaces
+
+	def delete_on_bus(self, path, bus):
+		obj = self.bus.get_object(bus, path, introspect = False)
+		delete_iface = dbus.Interface(
+				obj, dbus_interface = DELETE_IFACE)
+		delete_iface.Delete()
+
+class JsonApiRequestPlugin(object):
+	''' Ensures request content satisfies the OpenBMC json api format. '''
+	name = 'json_api_request'
+	api = 2
+
+	error_str = "Expecting request format { 'data': <value> }, got '%s'"
+	type_error_str = "Unsupported Content-Type: '%s'"
+	json_type = "application/json"
+	request_methods = ['PUT', 'POST', 'PATCH']
+
+	@staticmethod
+	def content_expected():
+		return request.method in JsonApiRequestPlugin.request_methods
+
+	def validate_request(self):
+		if request.content_length > 0 and \
+				request.content_type != self.json_type:
+			abort(415, self.type_error_str %(request.content_type))
+
+		try:
+			request.parameter_list = request.json.get('data')
+		except ValueError, e:
+			abort(400, str(e))
+		except (AttributeError, KeyError, TypeError):
+			abort(400, self.error_str %(request.json))
+
+	def apply(self, callback, route):
+		verbs = getattr(route.get_undecorated_callback(),
+				'_verbs', None)
+		if verbs is None:
+			return callback
+
+		if not set(self.request_methods).intersection(verbs):
+			return callback
+
+		def wrap(*a, **kw):
+			if self.content_expected():
+				self.validate_request()
+			return callback(*a, **kw)
+
+		return wrap
+
+class JsonApiRequestTypePlugin(object):
+	''' Ensures request content type satisfies the OpenBMC json api format. '''
+	name = 'json_api_method_request'
+	api = 2
+
+	error_str = "Expecting request format { 'data': %s }, got '%s'"
+
+	def apply(self, callback, route):
+		request_type = getattr(route.get_undecorated_callback(),
+				'request_type', None)
+		if request_type is None:
+			return callback
+
+		def validate_request():
+			if not isinstance(request.parameter_list, request_type):
+				abort(400, self.error_str %(str(request_type), request.json))
+
+		def wrap(*a, **kw):
+			if JsonApiRequestPlugin.content_expected():
+				validate_request()
+			return callback(*a, **kw)
+
+		return wrap
+
+class JsonApiResponsePlugin(object):
+	''' Emits normal responses in the OpenBMC json api format. '''
+	name = 'json_api_response'
+	api = 2
+
+	def apply(self, callback, route):
+		def wrap(*a, **kw):
+			resp = { 'data': callback(*a, **kw) }
+			resp['status'] = 'ok'
+			resp['message'] = response.status_line
+			return resp
+		return wrap
+
+class JsonApiErrorsPlugin(object):
+	''' Emits error responses in the OpenBMC json api format. '''
+	name = 'json_api_errors'
+	api = 2
+
+	def __init__(self, **kw):
+		self.app = None
+		self.function_type = None
+		self.original = None
+		self.json_opts = { x:y for x,y in kw.iteritems() \
+			if x in ['indent','sort_keys'] }
+
+	def setup(self, app):
+		self.app = app
+		self.function_type = type(app.default_error_handler)
+		self.original = app.default_error_handler
+		self.app.default_error_handler = self.function_type(
+			self.json_errors, app, Bottle)
+
+	def apply(self, callback, route):
+		return callback
+
+	def close(self):
+		self.app.default_error_handler = self.function_type(
+				self.original, self.app, Bottle)
+
+	def json_errors(self, res, error):
+		response_object = {'status': 'error', 'data': {} }
+		response_object['message'] = error.status_line
+		response_object['data']['description'] = str(error.body)
+		if error.status_code == 500:
+			response_object['data']['exception'] = repr(error.exception)
+			response_object['data']['traceback'] = error.traceback.splitlines()
+
+		json_response = json.dumps(response_object, **self.json_opts)
+		res.content_type = 'application/json'
+		return json_response
+
+class RestApp(Bottle):
+	def __init__(self, bus):
+		super(RestApp, self).__init__(autojson = False)
+		self.bus = bus
+		self.mapper = Mapper(bus)
+
+		self.install_hooks()
+		self.install_plugins()
+		self.create_handlers()
+		self.install_handlers()
+
+	def install_plugins(self):
+		# install json api plugins
+		json_kw = {'indent': 2, 'sort_keys': True}
+		self.install(JSONPlugin(**json_kw))
+		self.install(JsonApiErrorsPlugin(**json_kw))
+		self.install(JsonApiResponsePlugin())
+		self.install(JsonApiRequestPlugin())
+		self.install(JsonApiRequestTypePlugin())
+
+	def install_hooks(self):
+		self.real_router_match = self.router.match
+		self.router.match = self.custom_router_match
+		self.add_hook('before_request', self.strip_extra_slashes)
+
+	def create_handlers(self):
+		# create route handlers
+		self.directory_handler = DirectoryHandler(self, self.bus)
+		self.list_names_handler = ListNamesHandler(self, self.bus)
+		self.list_handler = ListHandler(self, self.bus)
+		self.method_handler = MethodHandler(self, self.bus)
+		self.property_handler = PropertyHandler(self, self.bus)
+		self.instance_handler = InstanceHandler(self, self.bus)
+
+	def install_handlers(self):
+		self.directory_handler.install()
+		self.list_names_handler.install()
+		self.list_handler.install()
+		self.method_handler.install()
+		self.property_handler.install()
+		# this has to come last, since it matches everything
+		self.instance_handler.install()
+
+	def custom_router_match(self, environ):
+		''' The built-in Bottle algorithm for figuring out if a 404 or 405 is
+                    needed doesn't work for us since the instance rules match everything.
+                    This monkey-patch lets the route handler figure out which response is
+                    needed.  This could be accomplished with a hook but that would require
+		    calling the router match function twice.
+		'''
+		route, args = self.real_router_match(environ)
+		if isinstance(route.callback, RouteHandler):
+			route.callback._setup(**args)
+
+		return route, args
+
+	@staticmethod
+	def strip_extra_slashes():
+		path = request.environ['PATH_INFO']
+		trailing = ("","/")[path[-1] == '/']
+		parts = filter(bool, path.split('/'))
+		request.environ['PATH_INFO'] = '/' + '/'.join(parts) + trailing
+
+if __name__ == '__main__':
+	log = logging.getLogger('Rocket.Errors')
+	log.setLevel(logging.INFO)
+	log.addHandler(logging.StreamHandler(sys.stdout))
+
+	bus = dbus.SystemBus()
+	app = RestApp(bus)
+	default_cert = os.path.join(sys.prefix, 'share',
+			os.path.basename(__file__), 'cert.pem')
+
+	server = Rocket(('0.0.0.0',
+			443,
+			default_cert,
+			default_cert),
+		'wsgi', {'wsgi_app': app})
+	server.start()
diff --git a/phosphor-rest b/phosphor-rest
deleted file mode 100644
index 026eb74..0000000
--- a/phosphor-rest
+++ /dev/null
@@ -1,370 +0,0 @@
-#!/usr/bin/env python
-
-# Contributors Listed Below - COPYRIGHT 2015
-# [+] 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 BaseHTTPServer
-import SocketServer
-import json
-import dbus
-from OpenBMCMapper import Path, Mapper, PathTree
-import OpenBMCMapper
-
-class RestException(Exception):
-	def __init__(self, msg, http_status=403):
-		self.status = http_status
-		super(RestException, self).__init__(msg)
-
-class Response(object):
-	def render(self, handler):
-		raise NotImplemented()
-
-class ErrorResponse(Response):
-	def __init__(self, ex):
-		self.ex = ex
-
-	def render(self, handler):
-		err = {'status': 'error', 'error': self.ex.message,}
-		handler.send_response(self.ex.status)
-		handler.send_header('Content-Type', 'application/json')
-		handler.end_headers()
-		handler.wfile.write(json.dumps(err, indent=2, sort_keys=True))
-
-class JSONResponse(Response):
-	def __init__(self, data):
-		self.data = data
-
-	def render(self, handler):
-		handler.send_response(200)
-		handler.send_header('Content-Type', 'application/json')
-		handler.end_headers()
-		handler.wfile.write(json.dumps(self.data, indent=2, sort_keys=True))
-
-class RequestHandler(object):
-	def __init__(self, req, path, data):
-		self.req = req
-		self.path = path
-		self.bus = req.server.bus
-		self.mapper = req.server.mapper
-		self.data = data
-
-	def do_command(self):
-		f = getattr(self, 'do_' + self.req.command)
-		return f()
-
-	def do_GET(self):
-		raise RestException("Not Implemented", 501)
-
-	def do_PUT(self):
-		raise RestException("Not Implemented", 501)
-
-	def do_POST(self):
-		raise RestException("Not Implemented", 501)
-
-	def do_PATCH(self):
-		raise RestException("Not Implemented", 501)
-
-	def do_DELETE(self):
-		raise RestException("Not Implemented", 501)
-
-class MethodHandler(RequestHandler):
-	def __init__(self, req, path, data):
-		super(MethodHandler, self).__init__(req, path, data)
-		self.method = Path(self.req.path).rel(first = -1)
-
-	def find_method_in_interface(self, obj, interface):
-		try:
-			iface = dbus.Interface(obj, interface)
-			return getattr(iface, self.method)
-		except dbus.DBusException:
-			return None
-
-	def find_method_on_bus(self, bus, interfaces):
-		obj = self.bus.get_object(bus, self.path)
-		for i in interfaces:
-			m = self.find_method_in_interface(obj, i)
-			if not m:
-				continue
-		return m
-
-	def find_method(self):
-		busses = self.mapper.get_object(
-				self.path)
-		for items in busses.iteritems():
-			m = self.find_method_on_bus(*items)
-			if not m:
-				continue
-
-		return m
-
-	def do_POST(self):
-		try:
-			method = self.find_method()
-		except:
-			raise RestException("Not Found", 404)
-		try:
-			d = { 'result': method(*self.data),
-					'status': 'OK'}
-		except Exception, e:
-			d = { 'error': str(e),
-					'status': 'error'}
-		return d
-
-class InstanceHandler(RequestHandler):
-	def __init__(self, req, path, data, busses):
-		super(InstanceHandler, self).__init__(req, path, data)
-		self.busses = busses
-
-	def get_one_iface(self, properties_iface, iface):
-		try:
-			return properties_iface.GetAll(iface)
-		except:
-			# interface doesn't have any properties
-			return {}
-
-	def get_one_bus(self, bus, interfaces):
-		properties = {}
-		obj = self.bus.get_object(bus, self.path)
-		properties_iface = dbus.Interface(
-				obj, dbus_interface=dbus.PROPERTIES_IFACE)
-		for i in interfaces:
-			properties.update(self.get_one_iface(properties_iface, i))
-
-		return properties
-
-	def do_GET(self):
-		properties = {}
-		for item in self.busses.iteritems():
-			properties.update(self.get_one_bus(*item))
-
-		return properties
-
-	def try_set_one_interface(self, prop, value, properties_iface, interface):
-		try:
-			properties_iface.Set(interface, prop, value)
-			return True
-		except:
-			# property doesn't live on this interface/bus
-			return False
-
-	def try_set_one_bus(self, prop, value, bus, interfaces):
-		obj = self.bus.get_object(bus, self.path)
-		properties_iface = dbus.Interface(
-				obj, dbus_interface=dbus.PROPERTIES_IFACE)
-
-		for iface in interfaces:
-			if self.try_set_one_interface(prop, value,
-					properties_iface, iface):
-				return True
-
-		return False
-
-	def set_one_property(self, prop, value):
-		for item in self.busses.iteritems():
-			if not self.try_set_one_bus(prop, value, *item):
-				raise RestException("Not Found", 404)
-
-	def validate_json(self):
-		if type(self.data) != dict:
-			raise RestException("Bad Request", 400)
-
-		obj = self.do_GET()
-		if len(self.data) != len(obj):
-			raise RestException("Bad Request", 400)
-		for x in obj.iterkeys():
-			if x not in self.data:
-				raise RestException("Bad Request", 400)
-
-	def do_PUT(self):
-		try:
-			self.validate_json()
-			for p in self.data.iteritems():
-				self.set_one_property(*p)
-
-			d = { 'status': 'OK'}
-		except Exception, e:
-			d = { 'error': str(e),
-					'status': 'error'}
-		return d
-
-	def do_POST(self):
-		for p in self.data.iteritems():
-			self.set_one_property(*p)
-
-class AttrHandler(RequestHandler):
-	def __init__(self, req, path, data):
-		super(AttrHandler, self).__init__(req, path, data)
-		try:
-			self.inst = InstanceHandler(req, path, data,
-					self.mapper.get_object(path))
-		except KeyError:
-			raise RestException("Not Found", 404)
-		self.attr = Path(self.req.path).rel(first = -1)
-
-	def do_GET(self):
-		obj = self.inst.do_GET()
-		try:
-			return obj[self.attr]
-		except KeyError:
-			raise RestException("Not Found", 404)
-
-	def do_PUT(self):
-		self.inst.set_one_property(self.attr, self.data)
-
-class TypesHandler(RequestHandler):
-	def __init__(self, req, path, data):
-		super(TypesHandler, self).__init__(req, path, data)
-
-	def do_GET(self):
-		types = self.mapper.get_subtree_paths(self.path, 1)
-		if not types:
-			raise RestException("Not Found", 404)
-
-		return types
-
-class ListHandler(RequestHandler):
-	def __init__(self, req, path, data):
-		super(ListHandler, self).__init__(req, path, data)
-
-	def do_GET(self):
-		objs = self.mapper.get_subtree(self.path)
-		if not objs:
-			raise RestException("Not Found", 404)
-
-		return objs.keys()
-
-class EnumerateHandler(RequestHandler):
-	def __init__(self, req, path, data):
-		super(EnumerateHandler, self).__init__(req, path, data)
-
-	def get_enumerate(self, path, data):
-		busses = []
-		for s, i in data.iteritems():
-			if OpenBMCMapper.ENUMERATE_IFACE in i:
-				busses.append(s)
-		return busses
-
-	def call_enumerate(self, path, busses):
-		objs = {}
-		for b in busses:
-			obj = self.bus.get_object(b, path)
-			iface = dbus.Interface(obj, OpenBMCMapper.ENUMERATE_IFACE)
-			objs.update(iface.enumerate())
-		return objs
-
-	def do_GET(self):
-		objs = {}
-		mapper_data = self.mapper.get_subtree(self.path)
-		tree = PathTree()
-		for x,y in mapper_data.iteritems():
-			tree[x] = y
-
-		try:
-			# Check to see if the root path implements
-			# enumerate in addition to any sub tree
-			# objects.
-			root = self.mapper.get_object(self.path)
-			mapper_data[self.path] = root
-		except:
-			pass
-
-		have_enumerate = [ (x[0], self.get_enumerate(*x)) for x in mapper_data.iteritems() \
-				if self.get_enumerate(*x) ]
-
-		for x,y in have_enumerate:
-			objs.update(self.call_enumerate(x, y))
-			tmp = tree[x]
-			del tree[x]
-			tree[x] = tmp
-
-		for x,y in tree.dataitems():
-			objs[x] = InstanceHandler(self.req, x, self.data, y).do_GET()
-
-		if not objs:
-			raise RestException("Not Found", 404)
-
-		return objs
-
-class DBusRestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
-	def get_real_handler(self, data):
-		path = Path(self.path)
-
-		if self.path[-1] == '/':
-			return TypesHandler(self, path.fq(), data)
-
-		if path.parts[-1] == 'list':
-			return ListHandler(self, path.fq(last = -1), data)
-
-		if path.parts[-1] == 'enumerate':
-			return EnumerateHandler(self, path.fq(last = -1), data)
-
-		if path.depth() > 1 and path.parts[-2] == 'attr':
-			return AttrHandler(self, path.fq(last = -2), data)
-
-		if path.depth() > 1 and path.parts[-2] == 'action':
-			return MethodHandler(self, path.fq(last = -2), data)
-
-		# have to do an objectmapper query at this point
-		mapper_entry = self.server.mapper.get_object(path.fq())
-		if mapper_entry:
-			return InstanceHandler(self, path.fq(), data,
-					mapper_entry)
-
-		raise RestException("Not Found", 404)
-
-	def do_command(self):
-		data = None
-		try:
-			if self.command in ['POST', 'PUT', 'PATCH']:
-       		 		length = int(self.headers.getheader(
-					'content-length'))
-			        data = json.loads(self.rfile.read(length))
-
-			resp = self.get_real_handler(data).do_command()
-			if not resp:
-				resp = {'status': 'OK' }
-			response = JSONResponse(resp)
-		except RestException, ex:
-			response = ErrorResponse(ex)
-
-		response.render(self)
-		self.wfile.close()
-
-	def do_GET(self):
-		return self.do_command()
-
-	def do_POST(self):
-		return self.do_command()
-
-	def do_PATCH(self):
-		return self.do_command()
-
-	def do_PUT(self):
-		return self.do_command()
-
-	def do_DELETE(self):
-		return self.do_command()
-
-class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
-	def __init__(self, bind, handler, bus):
-		BaseHTTPServer.HTTPServer.__init__(self, bind, handler)
-		self.bus = bus
-		self.mapper = Mapper(self.bus)
-
-if __name__ == '__main__':
-	bus = dbus.SystemBus()
-	server = HTTPServer(('', 80), DBusRestHandler, bus)
-	server.serve_forever()
diff --git a/setup.py b/setup.py
index f5f25e9..473e3a0 100644
--- a/setup.py
+++ b/setup.py
@@ -2,6 +2,6 @@
 
 setup(name='obmc-rest',
       version='1.0',
-      scripts=['phosphor-rest'],
+      scripts=['obmc-rest'],
       data_files=[('obmc-rest', ['cert.pem'])],
       )
