diff --git a/novaclient/base.py b/novaclient/base.py
index 3759320f5..92671348e 100644
--- a/novaclient/base.py
+++ b/novaclient/base.py
@@ -30,9 +30,12 @@ import threading
 import six
 
 from novaclient import exceptions
+from novaclient.openstack.common.apiclient import base
 from novaclient.openstack.common import strutils
 from novaclient import utils
 
+Resource = base.Resource
+
 
 def getid(obj):
     """
@@ -410,92 +413,3 @@ class BootingManagerWithFind(ManagerWithFind):
 
         return self._create(resource_url, body, response_key,
                             return_raw=return_raw, **kwargs)
-
-
-class Resource(object):
-    """
-    A resource represents a particular instance of an object (server, flavor,
-    etc). This is pretty much just a bag for attributes.
-
-    :param manager: Manager object
-    :param info: dictionary representing resource attributes
-    :param loaded: prevent lazy-loading if set to True
-    """
-    HUMAN_ID = False
-    NAME_ATTR = 'name'
-
-    def __init__(self, manager, info, loaded=False):
-        self.manager = manager
-        self._info = info
-        self._add_details(info)
-        self._loaded = loaded
-
-        # NOTE(sirp): ensure `id` is already present because if it isn't we'll
-        # enter an infinite loop of __getattr__ -> get -> __init__ ->
-        # __getattr__ -> ...
-        if 'id' in self.__dict__ and len(str(self.id)) == 36:
-            self.manager.write_to_completion_cache('uuid', self.id)
-
-        human_id = self.human_id
-        if human_id:
-            self.manager.write_to_completion_cache('human_id', human_id)
-
-    @property
-    def human_id(self):
-        """Subclasses may override this provide a pretty ID which can be used
-        for bash completion.
-        """
-        if self.NAME_ATTR in self.__dict__ and self.HUMAN_ID:
-            name = getattr(self, self.NAME_ATTR)
-            if name is not None:
-                return strutils.to_slug(name)
-        return None
-
-    def _add_details(self, info):
-        for (k, v) in six.iteritems(info):
-            try:
-                setattr(self, k, v)
-                self._info[k] = v
-            except AttributeError:
-                # In this case we already defined the attribute on the class
-                pass
-
-    def __getattr__(self, k):
-        if k not in self.__dict__:
-            #NOTE(bcwaldon): disallow lazy-loading if already loaded once
-            if not self.is_loaded():
-                self.get()
-                return self.__getattr__(k)
-
-            raise AttributeError(k)
-        else:
-            return self.__dict__[k]
-
-    def __repr__(self):
-        reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and
-                                                                k != 'manager')
-        info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
-        return "<%s %s>" % (self.__class__.__name__, info)
-
-    def get(self):
-        # set_loaded() first ... so if we have to bail, we know we tried.
-        self.set_loaded(True)
-        if not hasattr(self.manager, 'get'):
-            return
-
-        new = self.manager.get(self.id)
-        if new:
-            self._add_details(new._info)
-
-    def __eq__(self, other):
-        if not isinstance(other, self.__class__):
-            return False
-        if hasattr(self, 'id') and hasattr(other, 'id'):
-            return self.id == other.id
-        return self._info == other._info
-
-    def is_loaded(self):
-        return self._loaded
-
-    def set_loaded(self, val):
-        self._loaded = val