diff --git a/src/cmislib/__init__.py b/src/cmislib/__init__.py
index 553b333..08ee007 100644
--- a/src/cmislib/__init__.py
+++ b/src/cmislib/__init__.py
@@ -20,6 +20,7 @@
 Define package contents so that they are easy to import.
 """
 
-from model import CmisClient, Repository, Folder
+from model import CmisClient
+from domain import Repository, Folder
 
 __all__ = ["CmisClient", "Repository", "Folder"]
diff --git a/src/cmislib/atompub_binding.py b/src/cmislib/atompub_binding.py
new file mode 100644
index 0000000..886d0ea
--- /dev/null
+++ b/src/cmislib/atompub_binding.py
@@ -0,0 +1,4348 @@
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you 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.
+#
+"""
+Module containing the Atom Pub binding-specific objects used to work with a CMIS
+provider.
+"""
+from cmis_services import RepositoryServiceIfc
+from cmis_services import Binding
+from domain import CmisId, CmisObject, Repository, Relationship, Policy, ObjectType, Property, Folder, Document, ACL, ACE, ChangeEntry, ResultSet, ChangeEntryResultSet, Rendition
+from net import RESTService as Rest
+from exceptions import CmisException, RuntimeException, \
+    ObjectNotFoundException, InvalidArgumentException, \
+    PermissionDeniedException, NotSupportedException, \
+    UpdateConflictException
+from util import parseDateTimeValue
+import messages
+
+from urllib import quote
+from urllib2 import HTTPError
+from urlparse import urlparse, urlunparse
+import re
+import mimetypes
+from xml.parsers.expat import ExpatError
+import datetime
+import time
+import iso8601
+import StringIO
+import logging
+from xml.dom import minidom
+from util import multiple_replace, parsePropValue, parseBoolValue, toCMISValue
+
+moduleLogger = logging.getLogger('cmislib.atompubbinding')
+
+# Namespaces
+ATOM_NS = 'http://www.w3.org/2005/Atom'
+APP_NS = 'http://www.w3.org/2007/app'
+CMISRA_NS = 'http://docs.oasis-open.org/ns/cmis/restatom/200908/'
+CMIS_NS = 'http://docs.oasis-open.org/ns/cmis/core/200908/'
+
+# Content types
+# Not all of these patterns have variability, but some do. It seemed cleaner
+# just to treat them all like patterns to simplify the matching logic
+ATOM_XML_TYPE = 'application/atom+xml'
+ATOM_XML_ENTRY_TYPE = 'application/atom+xml;type=entry'
+ATOM_XML_ENTRY_TYPE_P = re.compile('^application/atom\+xml.*type.*entry')
+ATOM_XML_FEED_TYPE = 'application/atom+xml;type=feed'
+ATOM_XML_FEED_TYPE_P = re.compile('^application/atom\+xml.*type.*feed')
+CMIS_TREE_TYPE = 'application/cmistree+xml'
+CMIS_TREE_TYPE_P = re.compile('^application/cmistree\+xml')
+CMIS_QUERY_TYPE = 'application/cmisquery+xml'
+CMIS_ACL_TYPE = 'application/cmisacl+xml'
+
+# Standard rels
+DOWN_REL = 'down'
+FIRST_REL = 'first'
+LAST_REL = 'last'
+NEXT_REL = 'next'
+PREV_REL = 'prev'
+SELF_REL = 'self'
+UP_REL = 'up'
+TYPE_DESCENDANTS_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/typedescendants'
+VERSION_HISTORY_REL = 'version-history'
+FOLDER_TREE_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/foldertree'
+RELATIONSHIPS_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/relationships'
+ACL_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/acl'
+CHANGE_LOG_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/changes'
+POLICIES_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/policies'
+RENDITION_REL = 'alternate'
+
+# Collection types
+QUERY_COLL = 'query'
+TYPES_COLL = 'types'
+CHECKED_OUT_COLL = 'checkedout'
+UNFILED_COLL = 'unfiled'
+ROOT_COLL = 'root'
+
+class AtomPubBinding(Binding):
+    def __init__(self, **kwargs):
+        self.extArgs = kwargs
+
+    def getRepositoryService(self):
+        return RepositoryService()
+
+    def get(self, url, username, password, **kwargs):
+
+        """
+        Does a get against the CMIS service. More than likely, you will not
+        need to call this method. Instead, let the other objects do it for you.
+
+        For example, if you need to get a specific object by object id, try
+        :class:`Repository.getObject`. If you have a path instead of an object
+        id, use :class:`Repository.getObjectByPath`. Or, you could start with
+        the root folder (:class:`Repository.getRootFolder`) and drill down from
+        there.
+        """
+
+        # merge the cmis client extended args with the ones that got passed in
+        if (len(self.extArgs) > 0):
+            kwargs.update(self.extArgs)
+
+        result = Rest().get(url,
+                            username=username,
+                            password=password,
+                            **kwargs)
+        if type(result) == HTTPError:
+            self._processCommonErrors(result)
+            return result
+        else:
+            try:
+                return minidom.parse(result)
+            except ExpatError:
+                raise CmisException('Could not parse server response', url)
+
+    def delete(self, url, username, password, **kwargs):
+
+        """
+        Does a delete against the CMIS service. More than likely, you will not
+        need to call this method. Instead, let the other objects do it for you.
+
+        For example, to delete a folder you'd call :class:`Folder.delete` and
+        to delete a document you'd call :class:`Document.delete`.
+        """
+
+        # merge the cmis client extended args with the ones that got passed in
+        if (len(self.extArgs) > 0):
+            kwargs.update(self.extArgs)
+
+        result = Rest().delete(url,
+                               username=username,
+                               password=password,
+                               **kwargs)
+        if type(result) == HTTPError:
+            self._processCommonErrors(result)
+            return result
+        else:
+            pass
+
+    def post(self, url, username, password, payload, contentType, **kwargs):
+
+        """
+        Does a post against the CMIS service. More than likely, you will not
+        need to call this method. Instead, let the other objects do it for you.
+
+        For example, to update the properties on an object, you'd call
+        :class:`CmisObject.updateProperties`. Or, to check in a document that's
+        been checked out, you'd call :class:`Document.checkin` on the PWC.
+        """
+
+        # merge the cmis client extended args with the ones that got passed in
+        if (len(self.extArgs) > 0):
+            kwargs.update(self.extArgs)
+
+        result = Rest().post(url,
+                             payload,
+                             contentType,
+                             username=username,
+                             password=password,
+                             **kwargs)
+        if type(result) != HTTPError:
+            try:
+                return minidom.parse(result)
+            except ExpatError:
+                raise CmisException('Could not parse server response', url)
+        elif result.code == 201:
+            try:
+                return minidom.parse(result)
+            except ExpatError:
+                raise CmisException('Could not parse server response', url)
+        else:
+            self._processCommonErrors(result)
+            return result
+
+    def put(self, url, username, password, payload, contentType, **kwargs):
+
+        """
+        Does a put against the CMIS service. More than likely, you will not
+        need to call this method. Instead, let the other objects do it for you.
+
+        For example, to update the properties on an object, you'd call
+        :class:`CmisObject.updateProperties`. Or, to check in a document that's
+        been checked out, you'd call :class:`Document.checkin` on the PWC.
+        """
+
+        # merge the cmis client extended args with the ones that got passed in
+        if (len(self.extArgs) > 0):
+            kwargs.update(self.extArgs)
+
+        result = Rest().put(url,
+                            payload,
+                            contentType,
+                            username=username,
+                            password=password,
+                            **kwargs)
+        if type(result) == HTTPError:
+            self._processCommonErrors(result)
+            return result
+        else:
+            #if result.headers['content-length'] != '0':
+            try:
+                return minidom.parse(result)
+            except ExpatError:
+                # This may happen and is normal
+                return None
+
+
+class RepositoryService(RepositoryServiceIfc):
+    def __init__(self):
+        self._uriTemplates = {}
+
+    def reload(self, obj):
+        self.logger.debug('Reload called on object')
+        obj.xmlDoc = obj._cmisClient.binding.get(obj._cmisClient.repositoryUrl.encode('utf-8'),
+                                         obj._cmisClient.username,
+                                         obj._cmisClient.password)
+        obj._initData()
+        
+    def getRepository(self, client, repositoryId):
+        doc = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
+        workspaceElements = doc.getElementsByTagNameNS(APP_NS, 'workspace')
+
+        for workspaceElement in workspaceElements:
+            idElement = workspaceElement.getElementsByTagNameNS(CMIS_NS, 'repositoryId')
+            if idElement[0].childNodes[0].data == repositoryId:
+                return AtomPubRepository(self, workspaceElement)
+
+        raise ObjectNotFoundException(url=client.repositoryUrl)
+
+    def getRepositories(self, client):
+        result = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
+        if (type(result) == HTTPError):
+            raise RuntimeException()
+
+        workspaceElements = result.getElementsByTagNameNS(APP_NS, 'workspace')
+        # instantiate a Repository object using every workspace element
+        # in the service URL then ask the repository object for its ID
+        # and name, and return that back
+
+        repositories = []
+        for node in [e for e in workspaceElements if e.nodeType == e.ELEMENT_NODE]:
+            repository = AtomPubRepository(client, node)
+            repositories.append({'repositoryId': repository.getRepositoryId(),
+                                 'repositoryName': repository.getRepositoryInfo()['repositoryName']})
+        return repositories
+
+    def getDefaultRepository(self, client):
+        doc = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
+        workspaceElements = doc.getElementsByTagNameNS(APP_NS, 'workspace')
+        # instantiate a Repository object with the first workspace
+        # element we find
+        repository = AtomPubRepository(client, [e for e in workspaceElements if e.nodeType == e.ELEMENT_NODE][0])
+        return repository
+
+
+class UriTemplate(dict):
+
+    """
+    Simple dictionary to represent the data stored in
+    a URI template entry.
+    """
+
+    def __init__(self, template, templateType, mediaType):
+
+        """
+        Constructor
+        """
+
+        dict.__init__(self)
+        self['template'] = template
+        self['type'] = templateType
+        self['mediaType'] = mediaType
+
+
+class AtomPubCmisObject(CmisObject):
+
+    def __init__(self, cmisClient, repository, objectId=None, xmlDoc=None, **kwargs):
+        """ Constructor """
+        self._cmisClient = cmisClient
+        self._repository = repository
+        self._objectId = objectId
+        self._name = None
+        self._properties = {}
+        self._allowableActions = {}
+        self.xmlDoc = xmlDoc
+        self._kwargs = kwargs
+        self.logger = logging.getLogger('cmislib.model.CmisObject')
+        self.logger.info('Creating an instance of CmisObject')
+
+    def __str__(self):
+        """To string"""
+        return self.getObjectId()
+
+    def reload(self, **kwargs):
+
+        """
+        Fetches the latest representation of this object from the CMIS service.
+        Some methods, like :class:`^Document.checkout` do this for you.
+
+        If you call reload with a properties filter, the filter will be in
+        effect on subsequent calls until the filter argument is changed. To
+        reset to the full list of properties, call reload with filter set to
+        '*'.
+        """
+
+        self.logger.debug('Reload called on CmisObject')
+        if kwargs:
+            if self._kwargs:
+                self._kwargs.update(kwargs)
+            else:
+                self._kwargs = kwargs
+
+        templates = self._repository.getUriTemplates()
+        template = templates['objectbyid']['template']
+
+        # Doing some refactoring here. Originally, we snagged the template
+        # and then "filled in" the template based on the args passed in.
+        # However, some servers don't provide a full template which meant
+        # supported optional args wouldn't get passed in using the fill-the-
+        # template approach. What's going on now is that the template gets
+        # filled in where it can, but if additional, non-templated args are
+        # passed in, those will get tacked on to the query string as
+        # "additional" options.
+
+        params = {
+              '{id}': self.getObjectId(),
+              '{filter}': '',
+              '{includeAllowableActions}': 'false',
+              '{includePolicyIds}': 'false',
+              '{includeRelationships}': '',
+              '{includeACL}': 'false',
+              '{renditionFilter}': ''}
+
+        options = {}
+        addOptions = {}  # args specified, but not in the template
+        for k, v in self._kwargs.items():
+            pKey = "{" + k + "}"
+            if template.find(pKey) >= 0:
+                options[pKey] = toCMISValue(v)
+            else:
+                addOptions[k] = toCMISValue(v)
+
+        # merge the templated args with the default params
+        params.update(options)
+
+        # fill in the template
+        byObjectIdUrl = multiple_replace(params, template)
+
+        self.xmlDoc = self._cmisClient.binding.get(byObjectIdUrl.encode('utf-8'),
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password,
+                                                   **addOptions)
+        self._initData()
+
+        # if a returnVersion arg was passed in, it is possible we got back
+        # a different object ID than the value we started with, so it needs
+        # to be cleared out as well
+        if options.has_key('returnVersion') or addOptions.has_key('returnVersion'):
+            self._objectId = None
+
+    def _initData(self):
+
+        """
+        An internal method used to clear out any member variables that
+        might be out of sync if we were to fetch new XML from the
+        service.
+        """
+
+        self._properties = {}
+        self._name = None
+        self._allowableActions = {}
+
+    def getObjectId(self):
+
+        """
+        Returns the object ID for this object.
+
+        >>> doc = resultSet.getResults()[0]
+        >>> doc.getObjectId()
+        u'workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339'
+        """
+
+        if self._objectId == None:
+            if self.xmlDoc == None:
+                self.logger.debug('Both objectId and xmlDoc were None, reloading')
+                self.reload()
+            props = self.getProperties()
+            self._objectId = CmisId(props['cmis:objectId'])
+        return self._objectId
+
+    def getObjectParents(self, **kwargs):
+        """
+        Gets the parents of this object as a :class:`ResultSet`.
+
+        The following optional arguments are supported:
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includeRelativePathSegment
+        """
+        # get the appropriate 'up' link
+        parentUrl = self._getLink(UP_REL)
+
+        if parentUrl == None:
+            raise NotSupportedException('Root folder does not support getObjectParents')
+
+        # invoke the URL
+        result = self._cmisClient.binding.get(parentUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self._repository, result)
+
+    def getPaths(self):
+        """
+        Returns the object's paths as a list of strings.
+        """
+        # see sub-classes for implementation
+        pass
+
+    def getAllowableActions(self):
+
+        """
+        Returns a dictionary of allowable actions, keyed off of the action name.
+
+        >>> actions = doc.getAllowableActions()
+        >>> for a in actions:
+        ...     print "%s:%s" % (a,actions[a])
+        ...
+        canDeleteContentStream:True
+        canSetContentStream:True
+        canCreateRelationship:True
+        canCheckIn:False
+        canApplyACL:False
+        canDeleteObject:True
+        canGetAllVersions:True
+        canGetObjectParents:True
+        canGetProperties:True
+        """
+
+        if self._allowableActions == {}:
+            self.reload(includeAllowableActions=True)
+            allowElements = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'allowableActions')
+            assert len(allowElements) == 1, "Expected response to have exactly one allowableActions element"
+            allowElement = allowElements[0]
+            for node in [e for e in allowElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
+                actionName = node.localName
+                actionValue = parseBoolValue(node.childNodes[0].data)
+                self._allowableActions[actionName] = actionValue
+
+        return self._allowableActions
+
+    def getTitle(self):
+
+        """
+        Returns the value of the object's cmis:title property.
+        """
+
+        if self.xmlDoc == None:
+            self.reload()
+
+        titleElement = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'title')[0]
+
+        if titleElement and titleElement.childNodes:
+            return titleElement.childNodes[0].data
+
+    def getProperties(self):
+
+        """
+        Returns a dict of the object's properties. If CMIS returns an
+        empty element for a property, the property will be in the
+        dict with a value of None.
+
+        >>> props = doc.getProperties()
+        >>> for p in props:
+        ...     print "%s: %s" % (p, props[p])
+        ...
+        cmis:contentStreamMimeType: text/html
+        cmis:creationDate: 2009-12-15T09:45:35.369-06:00
+        cmis:baseTypeId: cmis:document
+        cmis:isLatestMajorVersion: false
+        cmis:isImmutable: false
+        cmis:isMajorVersion: false
+        cmis:objectId: workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339
+
+        The optional filter argument is not yet implemented.
+        """
+
+        #TODO implement filter
+        if self._properties == {}:
+            if self.xmlDoc == None:
+                self.reload()
+            propertiesElement = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'properties')[0]
+            #cpattern = re.compile(r'^property([\w]*)')
+            for node in [e for e in propertiesElement.childNodes if e.nodeType == e.ELEMENT_NODE and e.namespaceURI == CMIS_NS]:
+                #propertyId, propertyString, propertyDateTime
+                #propertyType = cpattern.search(node.localName).groups()[0]
+                propertyName = node.attributes['propertyDefinitionId'].value
+                if node.childNodes and \
+                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0] and \
+                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes:
+                    valNodeList = node.getElementsByTagNameNS(CMIS_NS, 'value')
+                    if (len(valNodeList) == 1):
+                        propertyValue = parsePropValue(valNodeList[0].
+                                                       childNodes[0].data,
+                                                       node.localName)
+                    else:
+                        propertyValue = []
+                        for valNode in valNodeList:
+                            propertyValue.append(parsePropValue(valNode.
+                                                       childNodes[0].data,
+                                                       node.localName))
+                else:
+                    propertyValue = None
+                self._properties[propertyName] = propertyValue
+
+            for node in [e for e in self.xmlDoc.childNodes if e.nodeType == e.ELEMENT_NODE and e.namespaceURI == CMISRA_NS]:
+                propertyName = node.nodeName
+                if node.childNodes:
+                    propertyValue = node.firstChild.nodeValue
+                else:
+                    propertyValue = None
+                self._properties[propertyName] = propertyValue
+
+        return self._properties
+
+    def getName(self):
+
+        """
+        Returns the value of cmis:name from the getProperties() dictionary.
+        We don't need a getter for every standard CMIS property, but name
+        is a pretty common one so it seems to make sense.
+
+        >>> doc.getName()
+        u'system-overview.html'
+        """
+
+        if self._name == None:
+            self._name = self.getProperties()['cmis:name']
+        return self._name
+
+    def updateProperties(self, properties):
+
+        """
+        Updates the properties of an object with the properties provided.
+        Only provide the set of properties that need to be updated.
+
+        >>> folder = repo.getObjectByPath('/someFolder2')
+        >>> folder.getName()
+        u'someFolder2'
+        >>> props = {'cmis:name': 'someFolderFoo'}
+        >>> folder.updateProperties(props)
+        <cmislib.model.Folder object at 0x103ab1210>
+        >>> folder.getName()
+        u'someFolderFoo'
+
+        """
+
+        self.logger.debug('Inside updateProperties')
+
+        # get the self link
+        selfUrl = self._getSelfLink()
+
+        # if we have a change token, we must pass it back, per the spec
+        args = {}
+        if (self.properties.has_key('cmis:changeToken') and
+            self.properties['cmis:changeToken'] != None):
+            self.logger.debug('Change token present, adding it to args')
+            args = {"changeToken": self.properties['cmis:changeToken']}
+
+        # the getEntryXmlDoc function may need the object type
+        objectTypeId = None
+        if (self.properties.has_key('cmis:objectTypeId') and
+            not properties.has_key('cmis:objectTypeId')):
+            objectTypeId = self.properties['cmis:objectTypeId']
+            self.logger.debug('This object type is:%s' % objectTypeId)
+
+        # build the entry based on the properties provided
+        xmlEntryDoc = getEntryXmlDoc(self._repository, objectTypeId, properties)
+
+        self.logger.debug('xmlEntryDoc:' + xmlEntryDoc.toxml())
+
+        # do a PUT of the entry
+        updatedXmlDoc = self._cmisClient.binding.put(selfUrl.encode('utf-8'),
+                                             self._cmisClient.username,
+                                             self._cmisClient.password,
+                                             xmlEntryDoc.toxml(encoding='utf-8'),
+                                             ATOM_XML_TYPE,
+                                             **args)
+
+        # reset the xmlDoc for this object with what we got back from
+        # the PUT, then call initData we dont' want to call
+        # self.reload because we've already got the parsed XML--
+        # there's no need to fetch it again
+        self.xmlDoc = updatedXmlDoc
+        self._initData()
+        return self
+
+    def move(self, sourceFolder, targetFolder):
+
+        """
+        Moves an object from the source folder to the target folder.
+
+        >>> sub1 = repo.getObjectByPath('/cmislib/sub1')
+        >>> sub2 = repo.getObjectByPath('/cmislib/sub2')
+        >>> doc = repo.getObjectByPath('/cmislib/sub1/testdoc1')
+        >>> doc.move(sub1, sub2)
+        """
+
+        postUrl = targetFolder.getChildrenLink()
+
+        args = {"sourceFolderId": sourceFolder.id}
+
+        # post the Atom entry
+        result = self._cmisClient.binding.post(postUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               self.xmlDoc.toxml(encoding='utf-8'),
+                                               ATOM_XML_ENTRY_TYPE,
+                                               **args)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+    def delete(self, **kwargs):
+
+        """
+        Deletes this :class:`CmisObject` from the repository. Note that in the
+        case of a :class:`Folder` object, some repositories will refuse to
+        delete it if it contains children and some will delete it without
+        complaint. If what you really want to do is delete the folder and all
+        of its descendants, use :meth:`~Folder.deleteTree` instead.
+
+        >>> folder.delete()
+
+        The optional allVersions argument is supported.
+        """
+
+        url = self._getSelfLink()
+        result = self._cmisClient.binding.delete(url.encode('utf-8'),
+                                         self._cmisClient.username,
+                                         self._cmisClient.password,
+                                         **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+    def applyPolicy(self, policyId):
+
+        """
+        This is not yet implemented.
+        """
+
+        # depends on this object's canApplyPolicy allowable action
+        if self.getAllowableActions()['canApplyPolicy']:
+            raise NotImplementedError
+        else:
+            raise CmisException('This object has canApplyPolicy set to false')
+
+    def createRelationship(self, targetObj, relTypeId):
+
+        """
+        Creates a relationship between this object and a specified target
+        object using the relationship type specified. Returns the new
+        :class:`Relationship` object.
+
+        >>> rel = tstDoc1.createRelationship(tstDoc2, 'R:cmiscustom:assoc')
+        >>> rel.getProperties()
+        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
+
+        """
+
+        if isinstance(relTypeId, str):
+            relTypeId = CmisId(relTypeId)
+
+        props = {}
+        props['cmis:sourceId'] = self.getObjectId()
+        props['cmis:targetId'] = targetObj.getObjectId()
+        props['cmis:objectTypeId'] = relTypeId
+        xmlDoc = getEntryXmlDoc(self._repository, properties=props)
+
+        url = self._getLink(RELATIONSHIPS_REL)
+        assert url != None, 'Could not determine relationships URL'
+
+        result = self._cmisClient.binding.post(url.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               xmlDoc.toxml(encoding='utf-8'),
+                                               ATOM_XML_TYPE)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # instantiate CmisObject objects with the results and return the list
+        entryElements = result.getElementsByTagNameNS(ATOM_NS, 'entry')
+        assert(len(entryElements) == 1), "Expected entry element in result from relationship URL post"
+        return getSpecializedObject(AtomPubCmisObject(self._cmisClient, self, xmlDoc=entryElements[0]))
+
+    def getRelationships(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` of :class:`Relationship` objects for each
+        relationship where the source is this object.
+
+        >>> rels = tstDoc1.getRelationships()
+        >>> len(rels.getResults())
+        1
+        >>> rel = rels.getResults().values()[0]
+        >>> rel.getProperties()
+        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
+
+        The following optional arguments are supported:
+         - includeSubRelationshipTypes
+         - relationshipDirection
+         - typeId
+         - maxItems
+         - skipCount
+         - filter
+         - includeAllowableActions
+        """
+
+        url = self._getLink(RELATIONSHIPS_REL)
+        assert url != None, 'Could not determine relationships URL'
+
+        result = self._cmisClient.binding.get(url.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self._repository, result)
+
+    def removePolicy(self, policyId):
+
+        """
+        This is not yet implemented.
+        """
+
+        # depends on this object's canRemovePolicy allowable action
+        if self.getAllowableActions()['canRemovePolicy']:
+            raise NotImplementedError
+        else:
+            raise CmisException('This object has canRemovePolicy set to false')
+
+    def getAppliedPolicies(self):
+
+        """
+        This is not yet implemented.
+        """
+
+        # depends on this object's canGetAppliedPolicies allowable action
+        if self.getAllowableActions()['canGetAppliedPolicies']:
+            raise NotImplementedError
+        else:
+            raise CmisException('This object has canGetAppliedPolicies set to false')
+
+    def getACL(self):
+
+        """
+        Repository.getCapabilities['ACL'] must return manage or discover.
+
+        >>> acl = folder.getACL()
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
+
+        The optional onlyBasicPermissions argument is currently not supported.
+        """
+
+        if self._repository.getCapabilities()['ACL']:
+            # if the ACL capability is discover or manage, this must be
+            # supported
+            aclUrl = self._getLink(ACL_REL)
+            result = self._cmisClient.binding.get(aclUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password)
+            if type(result) == HTTPError:
+                raise CmisException(result.code)
+            return AtomPubACL(xmlDoc=result)
+        else:
+            raise NotSupportedException
+
+    def applyACL(self, acl):
+
+        """
+        Updates the object with the provided :class:`ACL`.
+        Repository.getCapabilities['ACL'] must return manage to invoke this
+        call.
+
+        >>> acl = folder.getACL()
+        >>> acl.addEntry(ACE('jdoe', 'cmis:write', 'true'))
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
+        """
+
+        if self._repository.getCapabilities()['ACL'] == 'manage':
+            # if the ACL capability is manage, this must be
+            # supported
+            # but it also depends on the canApplyACL allowable action
+            # for this object
+            if not isinstance(acl, ACL):
+                raise CmisException('The ACL to apply must be an instance of the ACL class.')
+            aclUrl = self._getLink(ACL_REL)
+            assert aclUrl, "Could not determine the object's ACL URL."
+            result = self._cmisClient.binding.put(aclUrl.encode('utf-8'),
+                                          self._cmisClient.username,
+                                          self._cmisClient.password,
+                                          acl.getXmlDoc().toxml(encoding='utf-8'),
+                                          CMIS_ACL_TYPE)
+            if type(result) == HTTPError:
+                raise CmisException(result.code)
+            return AtomPubACL(xmlDoc=result)
+        else:
+            raise NotSupportedException
+
+    def _getSelfLink(self):
+
+        """
+        Returns the URL used to retrieve this object.
+        """
+
+        url = self._getLink(SELF_REL)
+
+        assert len(url) > 0, "Could not determine the self link."
+
+        return url
+
+    def _getLink(self, rel, ltype=None):
+
+        """
+        Returns the HREF attribute of an Atom link element for the
+        specified rel.
+        """
+
+        if self.xmlDoc == None:
+            self.reload()
+        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        for linkElement in linkElements:
+
+            if ltype:
+                if linkElement.attributes.has_key('rel'):
+                    relAttr = linkElement.attributes['rel'].value
+
+                    if ltype and linkElement.attributes.has_key('type'):
+                        typeAttr = linkElement.attributes['type'].value
+
+                        if relAttr == rel and ltype.match(typeAttr):
+                            return linkElement.attributes['href'].value
+            else:
+                if linkElement.attributes.has_key('rel'):
+                    relAttr = linkElement.attributes['rel'].value
+
+                    if relAttr == rel:
+                        return linkElement.attributes['href'].value
+
+    allowableActions = property(getAllowableActions)
+    name = property(getName)
+    id = property(getObjectId)
+    properties = property(getProperties)
+    title = property(getTitle)
+    ACL = property(getACL)
+
+
+class AtomPubRepository(object):
+
+    """
+    Represents a CMIS repository. Will lazily populate itself by
+    calling the repository CMIS service URL.
+
+    You must pass in an instance of a CmisClient when creating an
+    instance of this class.
+    """
+
+    def __init__(self, cmisClient, xmlDoc=None):
+        """ Constructor """
+        self._cmisClient = cmisClient
+        self.xmlDoc = xmlDoc
+        self._repositoryId = None
+        self._repositoryName = None
+        self._repositoryInfo = {}
+        self._capabilities = {}
+        self._uriTemplates = {}
+        self._permDefs = {}
+        self._permMap = {}
+        self._permissions = None
+        self._propagation = None
+        self.logger = logging.getLogger('cmislib.model.Repository')
+        self.logger.info('Creating an instance of Repository')
+
+    def __str__(self):
+        """To string"""
+        return self.getRepositoryName()
+
+    def reload(self):
+        """
+        This method will re-fetch the repository's XML data from the CMIS
+        repository.
+        """
+        self.logger.debug('Reload called on object')
+        self.xmlDoc = self._cmisClient.binding.get(self._cmisClient.repositoryUrl.encode('utf-8'),
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password)
+        self._initData()
+
+    def _initData(self):
+        """
+        This method clears out any local variables that would be out of sync
+        when data is re-fetched from the server.
+        """
+        self._repositoryId = None
+        self._repositoryName = None
+        self._repositoryInfo = {}
+        self._capabilities = {}
+        self._uriTemplates = {}
+        self._permDefs = {}
+        self._permMap = {}
+        self._permissions = None
+        self._propagation = None
+
+    def getSupportedPermissions(self):
+
+        """
+        Returns the value of the cmis:supportedPermissions element. Valid
+        values are:
+
+         - basic: indicates that the CMIS Basic permissions are supported
+         - repository: indicates that repository specific permissions are supported
+         - both: indicates that both CMIS basic permissions and repository specific permissions are supported
+
+        >>> repo.supportedPermissions
+        u'both'
+        """
+
+        if not self.getCapabilities()['ACL']:
+            raise NotSupportedException(messages.NO_ACL_SUPPORT)
+
+        if not self._permissions:
+            if self.xmlDoc == None:
+                self.reload()
+            suppEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'supportedPermissions')
+            assert len(suppEls) == 1, 'Expected the repository service document to have one element named supportedPermissions'
+            self._permissions = suppEls[0].childNodes[0].data
+
+        return self._permissions
+
+    def getPermissionDefinitions(self):
+
+        """
+        Returns a dictionary of permission definitions for this repository. The
+        key is the permission string or technical name of the permission
+        and the value is the permission description.
+
+        >>> for permDef in repo.permissionDefinitions:
+        ...     print permDef
+        ...
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.LinkChildren
+        {http://www.alfresco.org/model/content/1.0}folder.Consumer
+        {http://www.alfresco.org/model/security/1.0}All.All
+        {http://www.alfresco.org/model/system/1.0}base.CreateAssociations
+        {http://www.alfresco.org/model/system/1.0}base.FullControl
+        {http://www.alfresco.org/model/system/1.0}base.AddChildren
+        {http://www.alfresco.org/model/system/1.0}base.ReadAssociations
+        {http://www.alfresco.org/model/content/1.0}folder.Editor
+        {http://www.alfresco.org/model/content/1.0}cmobject.Editor
+        {http://www.alfresco.org/model/system/1.0}base.DeleteAssociations
+        cmis:read
+        cmis:write
+        """
+
+        if not self.getCapabilities()['ACL']:
+            raise NotSupportedException(messages.NO_ACL_SUPPORT)
+
+        if self._permDefs == {}:
+            if self.xmlDoc == None:
+                self.reload()
+            aclEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'aclCapability')
+            assert len(aclEls) == 1, 'Expected the repository service document to have one element named aclCapability'
+            aclEl = aclEls[0]
+            perms = {}
+            for e in aclEl.childNodes:
+                if e.localName == 'permissions':
+                    permEls = e.getElementsByTagNameNS(CMIS_NS, 'permission')
+                    assert len(permEls) == 1, 'Expected permissions element to have a child named permission'
+                    descEls = e.getElementsByTagNameNS(CMIS_NS, 'description')
+                    assert len(descEls) == 1, 'Expected permissions element to have a child named description'
+                    perm = permEls[0].childNodes[0].data
+                    desc = descEls[0].childNodes[0].data
+                    perms[perm] = desc
+            self._permDefs = perms
+
+        return self._permDefs
+
+    def getPermissionMap(self):
+
+        """
+        Returns a dictionary representing the permission mapping table where
+        each key is a permission key string and each value is a list of one or
+        more permissions the principal must have to perform the operation.
+
+        >>> for (k,v) in repo.permissionMap.items():
+        ...     print 'To do this: %s, you must have these perms:' % k
+        ...     for perm in v:
+        ...             print perm
+        ...
+        To do this: canCreateFolder.Folder, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
+        To do this: canAddToFolder.Folder, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
+        To do this: canDelete.Object, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.DeleteNode
+        To do this: canCheckin.Document, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/content/1.0}lockable.CheckIn
+        """
+
+        if not self.getCapabilities()['ACL']:
+            raise NotSupportedException(messages.NO_ACL_SUPPORT)
+
+        if self._permMap == {}:
+            if self.xmlDoc == None:
+                self.reload()
+            aclEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'aclCapability')
+            assert len(aclEls) == 1, 'Expected the repository service document to have one element named aclCapability'
+            aclEl = aclEls[0]
+            permMap = {}
+            for e in aclEl.childNodes:
+                permList = []
+                if e.localName == 'mapping':
+                    keyEls = e.getElementsByTagNameNS(CMIS_NS, 'key')
+                    assert len(keyEls) == 1, 'Expected mapping element to have a child named key'
+                    permEls = e.getElementsByTagNameNS(CMIS_NS, 'permission')
+                    assert len(permEls) >= 1, 'Expected mapping element to have at least one permission element'
+                    key = keyEls[0].childNodes[0].data
+                    for permEl in permEls:
+                        permList.append(permEl.childNodes[0].data)
+                    permMap[key] = permList
+            self._permMap = permMap
+
+        return self._permMap
+
+    def getPropagation(self):
+
+        """
+        Returns the value of the cmis:propagation element. Valid values are:
+          - objectonly: indicates that the repository is able to apply ACEs
+            without changing the ACLs of other objects
+          - propagate: indicates that the repository is able to apply ACEs to a
+            given object and propagate this change to all inheriting objects
+
+        >>> repo.propagation
+        u'propagate'
+        """
+
+        if not self.getCapabilities()['ACL']:
+            raise NotSupportedException(messages.NO_ACL_SUPPORT)
+
+        if not self._propagation:
+            if self.xmlDoc == None:
+                self.reload()
+            propEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'propagation')
+            assert len(propEls) == 1, 'Expected the repository service document to have one element named propagation'
+            self._propagation = propEls[0].childNodes[0].data
+
+        return self._propagation
+
+    def getRepositoryId(self):
+
+        """
+        Returns this repository's unique identifier
+
+        >>> repo = client.getDefaultRepository()
+        >>> repo.getRepositoryId()
+        u'83beb297-a6fa-4ac5-844b-98c871c0eea9'
+        """
+
+        if self._repositoryId == None:
+            if self.xmlDoc == None:
+                self.reload()
+            self._repositoryId = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'repositoryId')[0].firstChild.data
+        return self._repositoryId
+
+    def getRepositoryName(self):
+
+        """
+        Returns this repository's name
+
+        >>> repo = client.getDefaultRepository()
+        >>> repo.getRepositoryName()
+        u'Main Repository'
+        """
+
+        if self._repositoryName == None:
+            if self.xmlDoc == None:
+                self.reload()
+            self._repositoryName = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'repositoryName')[0].firstChild.data
+        return self._repositoryName
+
+    def getRepositoryInfo(self):
+
+        """
+        Returns a dict of repository information.
+
+        >>> repo = client.getDefaultRepository()>>> repo.getRepositoryName()
+        u'Main Repository'
+        >>> info = repo.getRepositoryInfo()
+        >>> for k,v in info.items():
+        ...     print "%s:%s" % (k,v)
+        ...
+        cmisSpecificationTitle:Version 1.0 Committee Draft 04
+        cmisVersionSupported:1.0
+        repositoryDescription:None
+        productVersion:3.2.0 (r2 2440)
+        rootFolderId:workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348
+        repositoryId:83beb297-a6fa-4ac5-844b-98c871c0eea9
+        repositoryName:Main Repository
+        vendorName:Alfresco
+        productName:Alfresco Repository (Community)
+        """
+
+        if not self._repositoryInfo:
+            if self.xmlDoc == None:
+                self.reload()
+            repoInfoElement = self.xmlDoc.getElementsByTagNameNS(CMISRA_NS, 'repositoryInfo')[0]
+            for node in repoInfoElement.childNodes:
+                if node.nodeType == node.ELEMENT_NODE and node.localName != 'capabilities':
+                    try:
+                        data = node.childNodes[0].data
+                    except:
+                        data = None
+                    self._repositoryInfo[node.localName] = data
+        return self._repositoryInfo
+
+    def getCapabilities(self):
+
+        """
+        Returns a dict of repository capabilities.
+
+        >>> caps = repo.getCapabilities()
+        >>> for k,v in caps.items():
+        ...     print "%s:%s" % (k,v)
+        ...
+        PWCUpdatable:True
+        VersionSpecificFiling:False
+        Join:None
+        ContentStreamUpdatability:anytime
+        AllVersionsSearchable:False
+        Renditions:None
+        Multifiling:True
+        GetFolderTree:True
+        GetDescendants:True
+        ACL:None
+        PWCSearchable:True
+        Query:bothcombined
+        Unfiling:False
+        Changes:None
+        """
+
+        if not self._capabilities:
+            if self.xmlDoc == None:
+                self.reload()
+            capabilitiesElement = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'capabilities')[0]
+            for node in [e for e in capabilitiesElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
+                key = node.localName.replace('capability', '')
+                value = parseBoolValue(node.childNodes[0].data)
+                self._capabilities[key] = value
+        return self._capabilities
+
+    def getRootFolder(self):
+        """
+        Returns the root folder of the repository
+
+        >>> root = repo.getRootFolder()
+        >>> root.getObjectId()
+        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
+        """
+        # get the root folder id
+        rootFolderId = self.getRepositoryInfo()['rootFolderId']
+        # instantiate a Folder object using the ID
+        folder = AtomPubFolder(self._cmisClient, self, rootFolderId)
+        # return it
+        return folder
+
+    def getFolder(self, folderId):
+
+        """
+        Returns a :class:`Folder` object for a specified folderId
+
+        >>> someFolder = repo.getFolder('workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348')
+        >>> someFolder.getObjectId()
+        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
+        """
+
+        retObject = self.getObject(folderId)
+        return AtomPubFolder(self._cmisClient, self, xmlDoc=retObject.xmlDoc)
+
+    def getTypeChildren(self,
+                        typeId=None):
+
+        """
+        Returns a list of :class:`ObjectType` objects corresponding to the
+        child types of the type specified by the typeId.
+
+        If no typeId is provided, the result will be the same as calling
+        `self.getTypeDefinitions`
+
+        These optional arguments are current unsupported:
+         - includePropertyDefinitions
+         - maxItems
+         - skipCount
+
+        >>> baseTypes = repo.getTypeChildren()
+        >>> for baseType in baseTypes:
+        ...     print baseType.getTypeId()
+        ...
+        cmis:folder
+        cmis:relationship
+        cmis:document
+        cmis:policy
+        """
+
+        # Unfortunately, the spec does not appear to present a way to
+        # know how to get the children of a specific type without first
+        # retrieving the type, then asking it for one of its navigational
+        # links.
+
+        # if a typeId is specified, get it, then get its "down" link
+        if typeId:
+            targetType = self.getTypeDefinition(typeId)
+            childrenUrl = targetType.getLink(DOWN_REL, ATOM_XML_FEED_TYPE_P)
+            typesXmlDoc = self._cmisClient.binding.get(childrenUrl.encode('utf-8'),
+                                                       self._cmisClient.username,
+                                                       self._cmisClient.password)
+            entryElements = typesXmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
+            types = []
+            for entryElement in entryElements:
+                objectType = ObjectType(self._cmisClient,
+                                        self,
+                                        xmlDoc=entryElement)
+                types.append(objectType)
+        # otherwise, if a typeId is not specified, return
+        # the list of base types
+        else:
+            types = self.getTypeDefinitions()
+        return types
+
+    def getTypeDescendants(self, typeId=None, **kwargs):
+
+        """
+        Returns a list of :class:`ObjectType` objects corresponding to the
+        descendant types of the type specified by the typeId.
+
+        If no typeId is provided, the repository's "typesdescendants" URL
+        will be called to determine the list of descendant types.
+
+        >>> allTypes = repo.getTypeDescendants()
+        >>> for aType in allTypes:
+        ...     print aType.getTypeId()
+        ...
+        cmis:folder
+        F:cm:systemfolder
+        F:act:savedactionfolder
+        F:app:configurations
+        F:fm:forums
+        F:wcm:avmfolder
+        F:wcm:avmplainfolder
+        F:wca:webfolder
+        F:wcm:avmlayeredfolder
+        F:st:site
+        F:app:glossary
+        F:fm:topic
+
+        These optional arguments are supported:
+         - depth
+         - includePropertyDefinitions
+
+        >>> types = alfRepo.getTypeDescendants('cmis:folder')
+        >>> len(types)
+        17
+        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=1)
+        >>> len(types)
+        12
+        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=2)
+        >>> len(types)
+        17
+        """
+
+        # Unfortunately, the spec does not appear to present a way to
+        # know how to get the children of a specific type without first
+        # retrieving the type, then asking it for one of its navigational
+        # links.
+        if typeId:
+            targetType = self.getTypeDefinition(typeId)
+            descendUrl = targetType.getLink(DOWN_REL, CMIS_TREE_TYPE_P)
+
+        else:
+            descendUrl = self.getLink(TYPE_DESCENDANTS_REL)
+
+        if not descendUrl:
+            raise NotSupportedException("Could not determine the type descendants URL")
+
+        typesXmlDoc = self._cmisClient.binding.get(descendUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+        entryElements = typesXmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
+        types = []
+        for entryElement in entryElements:
+            objectType = AtomPubObjectType(self._cmisClient,
+                                    self,
+                                    xmlDoc=entryElement)
+            types.append(objectType)
+        return types
+
+    def getTypeDefinitions(self, **kwargs):
+
+        """
+        Returns a list of :class:`ObjectType` objects representing
+        the base types in the repository.
+
+        >>> baseTypes = repo.getTypeDefinitions()
+        >>> for baseType in baseTypes:
+        ...     print baseType.getTypeId()
+        ...
+        cmis:folder
+        cmis:relationship
+        cmis:document
+        cmis:policy
+        """
+
+        typesUrl = self.getCollectionLink(TYPES_COLL)
+        typesXmlDoc = self._cmisClient.binding.get(typesUrl,
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password,
+                                                   **kwargs)
+        entryElements = typesXmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
+        types = []
+        for entryElement in entryElements:
+            objectType = AtomPubObjectType(self._cmisClient,
+                                    self,
+                                    xmlDoc=entryElement)
+            types.append(objectType)
+        # return the result
+        return types
+
+    def getTypeDefinition(self, typeId):
+
+        """
+        Returns an :class:`ObjectType` object for the specified object type id.
+
+        >>> folderType = repo.getTypeDefinition('cmis:folder')
+        """
+
+        objectType = AtomPubObjectType(self._cmisClient, self, typeId)
+        objectType.reload()
+        return objectType
+
+    def getLink(self, rel):
+        """
+        Returns the HREF attribute of an Atom link element for the
+        specified rel.
+        """
+        if self.xmlDoc == None:
+            self.reload()
+
+        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        for linkElement in linkElements:
+
+            if linkElement.attributes.has_key('rel'):
+                relAttr = linkElement.attributes['rel'].value
+
+                if relAttr == rel:
+                    return linkElement.attributes['href'].value
+
+    def getCheckedOutDocs(self, **kwargs):
+
+        """
+        Returns a ResultSet of :class:`CmisObject` objects that
+        are currently checked out.
+
+        >>> rs = repo.getCheckedOutDocs()
+        >>> len(rs.getResults())
+        2
+        >>> for doc in repo.getCheckedOutDocs().getResults():
+        ...     doc.getTitle()
+        ...
+        u'sample-a (Working Copy).pdf'
+        u'sample-b (Working Copy).pdf'
+
+        These optional arguments are supported:
+         - folderId
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+        """
+
+        return self.getCollection(CHECKED_OUT_COLL, **kwargs)
+
+    def getUnfiledDocs(self, **kwargs):
+
+        """
+        Returns a ResultSet of :class:`CmisObject` objects that
+        are currently unfiled.
+
+        >>> rs = repo.getUnfiledDocs()
+        >>> len(rs.getResults())
+        2
+        >>> for doc in repo.getUnfiledDocs().getResults():
+        ...     doc.getTitle()
+        ...
+        u'sample-a.pdf'
+        u'sample-b.pdf'
+
+        These optional arguments are supported:
+         - folderId
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+        """
+
+        return self.getCollection(UNFILED_COLL, **kwargs)
+
+    def getObject(self,
+                  objectId,
+                  **kwargs):
+
+        """
+        Returns an object given the specified object ID.
+
+        >>> doc = repo.getObject('workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808')
+        >>> doc.getTitle()
+        u'sample-b.pdf'
+
+        The following optional arguments are supported:
+         - returnVersion
+         - filter
+         - includeRelationships
+         - includePolicyIds
+         - renditionFilter
+         - includeACL
+         - includeAllowableActions
+        """
+
+        return getSpecializedObject(AtomPubCmisObject(self._cmisClient, self, objectId, **kwargs), **kwargs)
+
+    def getObjectByPath(self, path, **kwargs):
+
+        """
+        Returns an object given the path to the object.
+
+        >>> doc = repo.getObjectByPath('/jeff test/sample-b.pdf')
+        >>> doc.getTitle()
+        u'sample-b.pdf'
+
+        The following optional arguments are not currently supported:
+         - filter
+         - includeAllowableActions
+        """
+
+        # get the uritemplate
+        template = self.getUriTemplates()['objectbypath']['template']
+
+        # fill in the template with the path provided
+        params = {
+              '{path}': quote(path, '/'),
+              '{filter}': '',
+              '{includeAllowableActions}': 'false',
+              '{includePolicyIds}': 'false',
+              '{includeRelationships}': '',
+              '{includeACL}': 'false',
+              '{renditionFilter}': ''}
+
+        options = {}
+        addOptions = {}  # args specified, but not in the template
+        for k, v in kwargs.items():
+            pKey = "{" + k + "}"
+            if template.find(pKey) >= 0:
+                options[pKey] = toCMISValue(v)
+            else:
+                addOptions[k] = toCMISValue(v)
+
+        # merge the templated args with the default params
+        params.update(options)
+
+        byObjectPathUrl = multiple_replace(params, template)
+
+        # do a GET against the URL
+        result = self._cmisClient.binding.get(byObjectPathUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **addOptions)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # instantiate CmisObject objects with the results and return the list
+        entryElements = result.getElementsByTagNameNS(ATOM_NS, 'entry')
+        assert(len(entryElements) == 1), "Expected entry element in result from calling %s" % byObjectPathUrl
+        return getSpecializedObject(AtomPubCmisObject(self._cmisClient, self, xmlDoc=entryElements[0], **kwargs), **kwargs)
+
+    def query(self, statement, **kwargs):
+
+        """
+        Returns a list of :class:`CmisObject` objects based on the CMIS
+        Query Language passed in as the statement. The actual objects
+        returned will be instances of the appropriate child class based
+        on the object's base type ID.
+
+        In order for the results to be properly instantiated as objects,
+        make sure you include 'cmis:objectId' as one of the fields in
+        your select statement, or just use "SELECT \*".
+
+        If you want the search results to automatically be instantiated with
+        the appropriate sub-class of :class:`CmisObject` you must either
+        include cmis:baseTypeId as one of the fields in your select statement
+        or just use "SELECT \*".
+
+        >>> q = "select * from cmis:document where cmis:name like '%test%'"
+        >>> resultSet = repo.query(q)
+        >>> len(resultSet.getResults())
+        1
+        >>> resultSet.hasNext()
+        False
+
+        The following optional arguments are supported:
+         - searchAllVersions
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - maxItems
+         - skipCount
+
+        >>> q = 'select * from cmis:document'
+        >>> rs = repo.query(q)
+        >>> len(rs.getResults())
+        148
+        >>> rs = repo.query(q, maxItems='5')
+        >>> len(rs.getResults())
+        5
+        >>> rs.hasNext()
+        True
+        """
+
+        if self.xmlDoc == None:
+            self.reload()
+
+        # get the URL this repository uses to accept query POSTs
+        queryUrl = self.getCollectionLink(QUERY_COLL)
+
+        # build the CMIS query XML that we're going to POST
+        xmlDoc = self._getQueryXmlDoc(statement, **kwargs)
+
+        # do the POST
+        #print 'posting:%s' % xmlDoc.toxml(encoding='utf-8')
+        result = self._cmisClient.binding.post(queryUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               xmlDoc.toxml(encoding='utf-8'),
+                                               CMIS_QUERY_TYPE)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self, result)
+
+    def getContentChanges(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` containing :class:`ChangeEntry` objects.
+
+        >>> for changeEntry in rs:
+        ...     changeEntry.objectId
+        ...     changeEntry.id
+        ...     changeEntry.changeType
+        ...     changeEntry.changeTime
+        ...
+        'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+        u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+        u'created'
+        datetime.datetime(2010, 2, 11, 12, 55, 14)
+        'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+        u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+        u'updated'
+        datetime.datetime(2010, 2, 11, 12, 55, 13)
+        'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+        u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+        u'updated'
+
+        The following optional arguments are supported:
+         - changeLogToken
+         - includeProperties
+         - includePolicyIDs
+         - includeACL
+         - maxItems
+
+        You can get the latest change log token by inspecting the repository
+        info via :meth:`Repository.getRepositoryInfo`.
+
+        >>> repo.info['latestChangeLogToken']
+        u'2692'
+        >>> rs = repo.getContentChanges(changeLogToken='2692')
+        >>> len(rs)
+        1
+        >>> rs[0].id
+        u'urn:uuid:8e88f694-93ef-44c5-9f70-f12fff824be9'
+        >>> rs[0].changeType
+        u'updated'
+        >>> rs[0].changeTime
+        datetime.datetime(2010, 2, 16, 20, 6, 37)
+        """
+
+        if self.getCapabilities()['Changes'] == None:
+            raise NotSupportedException(messages.NO_CHANGE_LOG_SUPPORT)
+
+        changesUrl = self.getLink(CHANGE_LOG_REL)
+        result = self._cmisClient.binding.get(changesUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubChangeEntryResultSet(self._cmisClient, self, result)
+
+    def createDocumentFromString(self,
+                                 name,
+                                 properties={},
+                                 parentFolder=None,
+                                 contentString=None,
+                                 contentType=None,
+                                 contentEncoding=None):
+
+        """
+        Creates a new document setting the content to the string provided. If
+        the repository supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        This method is essentially a convenience method that wraps your string
+        with a StringIO and then calls createDocument.
+
+        >>> repo.createDocumentFromString('testdoc5', parentFolder=testFolder, contentString='Hello, World!', contentType='text/plain')
+        <cmislib.model.Document object at 0x101352ed0>
+        """
+
+        # if you didn't pass in a parent folder
+        if parentFolder == None:
+            # if the repository doesn't require fileable objects to be filed
+            if self.getCapabilities()['Unfiling']:
+                # has not been implemented
+                #postUrl = self.getCollectionLink(UNFILED_COLL)
+                raise NotImplementedError
+            else:
+                # this repo requires fileable objects to be filed
+                raise InvalidArgumentException
+
+        return parentFolder.createDocument(name, properties, StringIO.StringIO(contentString),
+            contentType, contentEncoding)
+
+    def createDocument(self,
+                       name,
+                       properties={},
+                       parentFolder=None,
+                       contentFile=None,
+                       contentType=None,
+                       contentEncoding=None):
+
+        """
+        Creates a new :class:`Document` object. If the repository
+        supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        To create a document with an associated contentFile, pass in a
+        File object. The method will attempt to guess the appropriate content
+        type and encoding based on the file. To specify it yourself, pass them
+        in via the contentType and contentEncoding arguments.
+
+        >>> f = open('sample-a.pdf', 'rb')
+        >>> doc = folder.createDocument('sample-a.pdf', contentFile=f)
+        <cmislib.model.Document object at 0x105be5e10>
+        >>> f.close()
+        >>> doc.getTitle()
+        u'sample-a.pdf'
+
+        The following optional arguments are not currently supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        postUrl = ''
+        # if you didn't pass in a parent folder
+        if parentFolder == None:
+            # if the repository doesn't require fileable objects to be filed
+            if self.getCapabilities()['Unfiling']:
+                # has not been implemented
+                #postUrl = self.getCollectionLink(UNFILED_COLL)
+                raise NotImplementedError
+            else:
+                # this repo requires fileable objects to be filed
+                raise InvalidArgumentException
+        else:
+            postUrl = parentFolder.getChildrenLink()
+
+        # make sure a name is set
+        properties['cmis:name'] = name
+
+        # hardcoding to cmis:document if it wasn't
+        # passed in via props
+        if not properties.has_key('cmis:objectTypeId'):
+            properties['cmis:objectTypeId'] = CmisId('cmis:document')
+        # and if it was passed in, making sure it is a CmisId
+        elif not isinstance(properties['cmis:objectTypeId'], CmisId):
+            properties['cmis:objectTypeId'] = CmisId(properties['cmis:objectTypeId'])
+
+        # build the Atom entry
+        xmlDoc = getEntryXmlDoc(self, None, properties, contentFile,
+                                contentType, contentEncoding)
+
+        # post the Atom entry
+        result = self._cmisClient.binding.post(postUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               xmlDoc.toxml(encoding='utf-8'),
+                                               ATOM_XML_ENTRY_TYPE)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # what comes back is the XML for the new document,
+        # so use it to instantiate a new document
+        # then return it
+        return AtomPubDocument(self._cmisClient, self, xmlDoc=result)
+
+    def createDocumentFromSource(self,
+                                 sourceId,
+                                 properties={},
+                                 parentFolder=None):
+        """
+        This is not yet implemented.
+
+        The following optional arguments are not yet supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+        # TODO: To be implemented
+        raise NotImplementedError
+
+    def createFolder(self,
+                     parentFolder,
+                     name,
+                     properties={}):
+
+        """
+        Creates a new :class:`Folder` object in the specified parentFolder.
+
+        >>> root = repo.getRootFolder()
+        >>> folder = repo.createFolder(root, 'someFolder2')
+        >>> folder.getTitle()
+        u'someFolder2'
+        >>> folder.getObjectId()
+        u'workspace://SpacesStore/2224a63c-350b-438c-be72-8f425e79ce1f'
+
+        The following optional arguments are not yet supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        return parentFolder.createFolder(name, properties)
+
+    def createRelationship(self, sourceObj, targetObj, relType):
+        """
+        Creates a relationship of the specific type between a source object
+        and a target object and returns the new :class:`Relationship` object.
+
+        The following optional arguments are not currently supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+        return sourceObj.createRelationship(targetObj, relType)
+
+    def createPolicy(self, properties):
+        """
+        This has not yet been implemented.
+
+        The following optional arguments are not currently supported:
+         - folderId
+         - policies
+         - addACEs
+         - removeACEs
+        """
+        # TODO: To be implemented
+        raise NotImplementedError
+
+    def getUriTemplates(self):
+
+        """
+        Returns a list of the URI templates the repository service knows about.
+
+        >>> templates = repo.getUriTemplates()
+        >>> templates['typebyid']['mediaType']
+        u'application/atom+xml;type=entry'
+        >>> templates['typebyid']['template']
+        u'http://localhost:8080/alfresco/s/cmis/type/{id}'
+        """
+
+        if self._uriTemplates == {}:
+
+            if self.xmlDoc == None:
+                self.reload()
+
+            uriTemplateElements = self.xmlDoc.getElementsByTagNameNS(CMISRA_NS, 'uritemplate')
+
+            for uriTemplateElement in uriTemplateElements:
+                template = None
+                templType = None
+                mediatype = None
+
+                for node in [e for e in uriTemplateElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
+                    if node.localName == 'template':
+                        template = node.childNodes[0].data
+                    elif node.localName == 'type':
+                        templType = node.childNodes[0].data
+                    elif node.localName == 'mediatype':
+                        mediatype = node.childNodes[0].data
+
+                self._uriTemplates[templType] = UriTemplate(template,
+                                                       templType,
+                                                       mediatype)
+
+        return self._uriTemplates
+
+    def getCollection(self, collectionType, **kwargs):
+
+        """
+        Returns a list of objects returned for the specified collection.
+
+        If the query collection is requested, an exception will be raised.
+        That collection isn't meant to be retrieved.
+
+        If the types collection is specified, the method returns the result of
+        `getTypeDefinitions` and ignores any optional params passed in.
+
+        >>> from cmislib.model import TYPES_COLL
+        >>> types = repo.getCollection(TYPES_COLL)
+        >>> len(types)
+        4
+        >>> types[0].getTypeId()
+        u'cmis:folder'
+
+        Otherwise, the collection URL is invoked, and a :class:`ResultSet` is
+        returned.
+
+        >>> from cmislib.model import CHECKED_OUT_COLL
+        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
+        >>> len(resultSet.getResults())
+        1
+        """
+
+        if collectionType == QUERY_COLL:
+            raise NotSupportedException
+        elif collectionType == TYPES_COLL:
+            return self.getTypeDefinitions()
+
+        result = self._cmisClient.binding.get(self.getCollectionLink(collectionType).encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+        if (type(result) == HTTPError):
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self, result)
+
+    def getCollectionLink(self, collectionType):
+
+        """
+        Returns the link HREF from the specified collectionType
+        ('checkedout', for example).
+
+        >>> from cmislib.model import CHECKED_OUT_COLL
+        >>> repo.getCollectionLink(CHECKED_OUT_COLL)
+        u'http://localhost:8080/alfresco/s/cmis/checkedout'
+
+        """
+
+        collectionElements = self.xmlDoc.getElementsByTagNameNS(APP_NS, 'collection')
+        for collectionElement in collectionElements:
+            link = collectionElement.attributes['href'].value
+            for node in [e for e in collectionElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
+                if node.localName == 'collectionType':
+                    if node.childNodes[0].data == collectionType:
+                        return link
+
+    def _getQueryXmlDoc(self, query, **kwargs):
+
+        """
+        Utility method that knows how to build CMIS query xml around the
+        specified query statement.
+        """
+
+        cmisXmlDoc = minidom.Document()
+        queryElement = cmisXmlDoc.createElementNS(CMIS_NS, "query")
+        queryElement.setAttribute('xmlns', CMIS_NS)
+        cmisXmlDoc.appendChild(queryElement)
+
+        statementElement = cmisXmlDoc.createElementNS(CMIS_NS, "statement")
+        cdataSection = cmisXmlDoc.createCDATASection(query)
+        statementElement.appendChild(cdataSection)
+        queryElement.appendChild(statementElement)
+
+        for (k, v) in kwargs.items():
+            optionElement = cmisXmlDoc.createElementNS(CMIS_NS, k)
+            optionText = cmisXmlDoc.createTextNode(v)
+            optionElement.appendChild(optionText)
+            queryElement.appendChild(optionElement)
+
+        return cmisXmlDoc
+
+    capabilities = property(getCapabilities)
+    id = property(getRepositoryId)
+    info = property(getRepositoryInfo)
+    name = property(getRepositoryName)
+    rootFolder = property(getRootFolder)
+    permissionDefinitions = property(getPermissionDefinitions)
+    permissionMap = property(getPermissionMap)
+    propagation = property(getPropagation)
+    supportedPermissions = property(getSupportedPermissions)
+
+
+class AtomPubResultSet(ResultSet):
+
+    """
+    Represents a paged result set. In CMIS, this is most often an Atom feed.
+    """
+
+    def __init__(self, cmisClient, repository, xmlDoc):
+        ''' Constructor '''
+        self._cmisClient = cmisClient
+        self._repository = repository
+        self._xmlDoc = xmlDoc
+        self._results = []
+        self.logger = logging.getLogger('cmislib.model.ResultSet')
+        self.logger.info('Creating an instance of ResultSet')
+
+    def __iter__(self):
+        ''' Iterator for the result set '''
+        return iter(self.getResults())
+
+    def __getitem__(self, index):
+        ''' Getter for the result set '''
+        return self.getResults()[index]
+
+    def __len__(self):
+        ''' Len method for the result set '''
+        return len(self.getResults())
+
+    def _getLink(self, rel):
+        '''
+        Returns the link found in the feed's XML for the specified rel.
+        '''
+        linkElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        for linkElement in linkElements:
+
+            if linkElement.attributes.has_key('rel'):
+                relAttr = linkElement.attributes['rel'].value
+
+                if relAttr == rel:
+                    return linkElement.attributes['href'].value
+
+    def _getPageResults(self, rel):
+        '''
+        Given a specified rel, does a get using that link (if one exists)
+        and then converts the resulting XML into a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type.
+
+        The results are kept around to facilitate repeated calls without moving
+        the cursor.
+        '''
+        link = self._getLink(rel)
+        if link:
+            result = self._cmisClient.binding.get(link.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password)
+            if (type(result) == HTTPError):
+                raise CmisException(result.code)
+
+            # return the result
+            self._xmlDoc = result
+            self._results = []
+            return self.getResults()
+
+    def reload(self):
+
+        '''
+        Re-invokes the self link for the current set of results.
+
+        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
+        >>> resultSet.reload()
+
+        '''
+
+        self.logger.debug('Reload called on result set')
+        self._getPageResults(SELF_REL)
+
+    def getResults(self):
+
+        '''
+        Returns the results that were fetched and cached by the get*Page call.
+
+        >>> resultSet = repo.getCheckedOutDocs()
+        >>> resultSet.hasNext()
+        False
+        >>> for result in resultSet.getResults():
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x104851810>
+        '''
+        if self._results:
+            return self._results
+
+        if self._xmlDoc:
+            entryElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
+            entries = []
+            for entryElement in entryElements:
+                cmisObject = getSpecializedObject(AtomPubCmisObject(self._cmisClient,
+                                                                    self._repository,
+                                                                    xmlDoc=entryElement))
+                entries.append(cmisObject)
+
+            self._results = entries
+
+        return self._results
+
+    def hasObject(self, objectId):
+
+        '''
+        Returns True if the specified objectId is found in the list of results,
+        otherwise returns False.
+        '''
+
+        for obj in self.getResults():
+            if obj.id == objectId:
+                return True
+        return False
+
+    def getFirst(self):
+
+        '''
+        Returns the first page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server returns a "first" link. Not all of them do.
+
+        >>> resultSet.hasFirst()
+        True
+        >>> results = resultSet.getFirst()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        return self._getPageResults(FIRST_REL)
+
+    def getPrev(self):
+
+        '''
+        Returns the prev page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server returns a "prev" link. Not all of them do.
+        >>> resultSet.hasPrev()
+        True
+        >>> results = resultSet.getPrev()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        return self._getPageResults(PREV_REL)
+
+    def getNext(self):
+
+        '''
+        Returns the next page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type.
+        >>> resultSet.hasNext()
+        True
+        >>> results = resultSet.getNext()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        return self._getPageResults(NEXT_REL)
+
+    def getLast(self):
+
+        '''
+        Returns the last page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server is returning a "last" link. Not all of them do.
+
+        >>> resultSet.hasLast()
+        True
+        >>> results = resultSet.getLast()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        return self._getPageResults(LAST_REL)
+
+    def hasNext(self):
+
+        '''
+        Returns True if this page contains a next link.
+
+        >>> resultSet.hasNext()
+        True
+        '''
+
+        if self._getLink(NEXT_REL):
+            return True
+        else:
+            return False
+
+    def hasPrev(self):
+
+        '''
+        Returns True if this page contains a prev link. Not all CMIS providers
+        implement prev links consistently.
+
+        >>> resultSet.hasPrev()
+        True
+        '''
+
+        if self._getLink(PREV_REL):
+            return True
+        else:
+            return False
+
+    def hasFirst(self):
+
+        '''
+        Returns True if this page contains a first link. Not all CMIS providers
+        implement first links consistently.
+
+        >>> resultSet.hasFirst()
+        True
+        '''
+
+        if self._getLink(FIRST_REL):
+            return True
+        else:
+            return False
+
+    def hasLast(self):
+
+        '''
+        Returns True if this page contains a last link. Not all CMIS providers
+        implement last links consistently.
+
+        >>> resultSet.hasLast()
+        True
+        '''
+
+        if self._getLink(LAST_REL):
+            return True
+        else:
+            return False
+
+
+class AtomPubDocument(AtomPubCmisObject):
+
+    """
+    An object typically associated with file content.
+    """
+
+    def checkout(self):
+
+        """
+        Performs a checkout on the :class:`Document` and returns the
+        Private Working Copy (PWC), which is also an instance of
+        :class:`Document`
+
+        >>> doc.getObjectId()
+        u'workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808;1.0'
+        >>> doc.isCheckedOut()
+        False
+        >>> pwc = doc.checkout()
+        >>> doc.isCheckedOut()
+        True
+        """
+
+        # get the checkedout collection URL
+        checkoutUrl = self._repository.getCollectionLink(CHECKED_OUT_COLL)
+        assert len(checkoutUrl) > 0, "Could not determine the checkedout collection url."
+
+        # get this document's object ID
+        # build entry XML with it
+        properties = {'cmis:objectId': self.getObjectId()}
+        entryXmlDoc = getEntryXmlDoc(self._repository, properties=properties)
+
+        # post it to to the checkedout collection URL
+        result = self._cmisClient.binding.post(checkoutUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               entryXmlDoc.toxml(encoding='utf-8'),
+                                               ATOM_XML_ENTRY_TYPE)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # now that the doc is checked out, we need to refresh the XML
+        # to pick up the prop updates related to a checkout
+        self.reload()
+
+        return AtomPubDocument(self._cmisClient, self._repository, xmlDoc=result)
+
+    def cancelCheckout(self):
+        """
+        Cancels the checkout of this object by retrieving the Private Working
+        Copy (PWC) and then deleting it. After the PWC is deleted, this object
+        will be reloaded to update properties related to a checkout.
+
+        >>> doc.isCheckedOut()
+        True
+        >>> doc.cancelCheckout()
+        >>> doc.isCheckedOut()
+        False
+        """
+
+        pwcDoc = self.getPrivateWorkingCopy()
+        if pwcDoc:
+            pwcDoc.delete()
+            self.reload()
+
+    def getPrivateWorkingCopy(self):
+
+        """
+        Retrieves the object using the object ID in the property:
+        cmis:versionSeriesCheckedOutId then uses getObject to instantiate
+        the object.
+
+        >>> doc.isCheckedOut()
+        False
+        >>> doc.checkout()
+        <cmislib.model.Document object at 0x103a25ad0>
+        >>> pwc = doc.getPrivateWorkingCopy()
+        >>> pwc.getTitle()
+        u'sample-b (Working Copy).pdf'
+        """
+
+        # reloading the document just to make sure we've got the latest
+        # and greatest PWC ID
+        self.reload()
+        pwcDocId = self.getProperties()['cmis:versionSeriesCheckedOutId']
+        if pwcDocId:
+            return self._repository.getObject(pwcDocId)
+
+    def isCheckedOut(self):
+
+        """
+        Returns true if the document is checked out.
+
+        >>> doc.isCheckedOut()
+        True
+        >>> doc.cancelCheckout()
+        >>> doc.isCheckedOut()
+        False
+        """
+
+        # reloading the document just to make sure we've got the latest
+        # and greatest checked out prop
+        self.reload()
+        return parseBoolValue(self.getProperties()['cmis:isVersionSeriesCheckedOut'])
+
+    def getCheckedOutBy(self):
+
+        """
+        Returns the ID who currently has the document checked out.
+        >>> pwc = doc.checkout()
+        >>> pwc.getCheckedOutBy()
+        u'admin'
+        """
+
+        # reloading the document just to make sure we've got the latest
+        # and greatest checked out prop
+        self.reload()
+        return self.getProperties()['cmis:versionSeriesCheckedOutBy']
+
+    def checkin(self, checkinComment=None, **kwargs):
+
+        """
+        Checks in this :class:`Document` which must be a private
+        working copy (PWC).
+
+        >>> doc.isCheckedOut()
+        False
+        >>> pwc = doc.checkout()
+        >>> doc.isCheckedOut()
+        True
+        >>> pwc.checkin()
+        <cmislib.model.Document object at 0x103a8ae90>
+        >>> doc.isCheckedOut()
+        False
+
+        The following optional arguments are supported:
+         - major
+         - properties
+         - contentStream
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        # Add checkin to kwargs and checkinComment, if it exists
+        kwargs['checkin'] = 'true'
+        kwargs['checkinComment'] = checkinComment
+
+        # Build an empty ATOM entry
+        entryXmlDoc = getEmptyXmlDoc()
+
+        # Get the self link
+        # Do a PUT of the empty ATOM to the self link
+        url = self._getSelfLink()
+        result = self._cmisClient.binding.put(url.encode('utf-8'),
+                                      self._cmisClient.username,
+                                      self._cmisClient.password,
+                                      entryXmlDoc.toxml(encoding='utf-8'),
+                                      ATOM_XML_TYPE,
+                                      **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        return AtomPubDocument(self._cmisClient, self._repository, xmlDoc=result)
+
+    def getLatestVersion(self, **kwargs):
+
+        """
+        Returns a :class:`Document` object representing the latest version in
+        the version series.
+
+        The following optional arguments are supported:
+         - major
+         - filter
+         - includeRelationships
+         - includePolicyIds
+         - renditionFilter
+         - includeACL
+         - includeAllowableActions
+
+        >>> latestDoc = doc.getLatestVersion()
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.1'
+        >>> latestDoc = doc.getLatestVersion(major='false')
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.1'
+        >>> latestDoc = doc.getLatestVersion(major='true')
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.0'
+        """
+
+        doc = None
+        if kwargs.has_key('major') and kwargs['major'] == 'true':
+            doc = self._repository.getObject(self.getObjectId(), returnVersion='latestmajor')
+        else:
+            doc = self._repository.getObject(self.getObjectId(), returnVersion='latest')
+
+        return doc
+
+    def getPropertiesOfLatestVersion(self, **kwargs):
+
+        """
+        Like :class:`^CmisObject.getProperties`, returns a dict of properties
+        from the latest version of this object in the version series.
+
+        The optional major and filter arguments are supported.
+        """
+
+        latestDoc = self.getLatestVersion(**kwargs)
+
+        return latestDoc.getProperties()
+
+    def getAllVersions(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` of document objects for the entire
+        version history of this object, including any PWC's.
+
+        The optional filter and includeAllowableActions are
+        supported.
+        """
+
+        # get the version history link
+        versionsUrl = self._getLink(VERSION_HISTORY_REL)
+
+        # invoke the URL
+        result = self._cmisClient.binding.get(versionsUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self._repository, result)
+
+    def getContentStream(self):
+
+        """
+        Returns the CMIS service response from invoking the 'enclosure' link.
+
+        >>> doc.getName()
+        u'sample-b.pdf'
+        >>> o = open('tmp.pdf', 'wb')
+        >>> result = doc.getContentStream()
+        >>> o.write(result.read())
+        >>> result.close()
+        >>> o.close()
+        >>> import os.path
+        >>> os.path.getsize('tmp.pdf')
+        117248
+
+        The optional streamId argument is not yet supported.
+        """
+
+        # TODO: Need to implement the streamId
+
+        contentElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'content')
+
+        assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
+
+        # if the src element exists, follow that
+        if contentElements[0].attributes.has_key('src'):
+            srcUrl = contentElements[0].attributes['src'].value
+
+            # the cmis client class parses non-error responses
+            result = Rest().get(srcUrl.encode('utf-8'),
+                                username=self._cmisClient.username,
+                                password=self._cmisClient.password,
+                                **self._cmisClient.extArgs)
+            if result.code != 200:
+                raise CmisException(result.code)
+            return result
+        else:
+            # otherwise, try to return the value of the content element
+            if contentElements[0].childNodes:
+                return contentElements[0].childNodes[0].data
+
+    def setContentStream(self, contentFile, contentType=None):
+
+        """
+        Sets the content stream on this object.
+
+        The following optional arguments are not yet supported:
+         - overwriteFlag=None
+        """
+
+        # get this object's content stream link
+        contentElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'content')
+
+        assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
+
+        # if the src element exists, follow that
+        if contentElements[0].attributes.has_key('src'):
+            srcUrl = contentElements[0].attributes['src'].value
+
+        # there may be times when this URL is absent, but I'm not sure how to
+        # set the content stream when that is the case
+        assert(srcUrl), 'Unable to determine content stream URL.'
+
+        # need to determine the mime type
+        mimetype = contentType
+        if not mimetype and hasattr(contentFile, 'name'):
+            mimetype, encoding = mimetypes.guess_type(contentFile.name)
+
+        if not mimetype:
+            mimetype = 'application/binary'
+
+        # if we have a change token, we must pass it back, per the spec
+        args = {}
+        if (self.properties.has_key('cmis:changeToken') and
+            self.properties['cmis:changeToken'] != None):
+            self.logger.debug('Change token present, adding it to args')
+            args = {"changeToken": self.properties['cmis:changeToken']}
+
+        # put the content file
+        result = self._cmisClient.binding.put(srcUrl.encode('utf-8'),
+                                      self._cmisClient.username,
+                                      self._cmisClient.password,
+                                      contentFile.read(),
+                                      mimetype,
+                                      **args)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # what comes back is the XML for the updated document,
+        # which is not required by the spec to be the same document
+        # we just updated, so use it to instantiate a new document
+        # then return it
+        return AtomPubDocument(self._cmisClient, self._repository, xmlDoc=result)
+
+    def deleteContentStream(self):
+
+        """
+        Delete's the content stream associated with this object.
+        """
+
+        # get this object's content stream link
+        contentElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'content')
+
+        assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
+
+        # if the src element exists, follow that
+        if contentElements[0].attributes.has_key('src'):
+            srcUrl = contentElements[0].attributes['src'].value
+
+        # there may be times when this URL is absent, but I'm not sure how to
+        # delete the content stream when that is the case
+        assert(srcUrl), 'Unable to determine content stream URL.'
+
+        # if we have a change token, we must pass it back, per the spec
+        args = {}
+        if (self.properties.has_key('cmis:changeToken') and
+            self.properties['cmis:changeToken'] != None):
+            self.logger.debug('Change token present, adding it to args')
+            args = {"changeToken": self.properties['cmis:changeToken']}
+
+        # delete the content stream
+        result = self._cmisClient.binding.delete(srcUrl.encode('utf-8'),
+                                         self._cmisClient.username,
+                                         self._cmisClient.password,
+                                         **args)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+    def getRenditions(self):
+
+        """
+        Returns an array of :class:`Rendition` objects. The repository
+        must support the Renditions capability.
+
+        The following optional arguments are not currently supported:
+         - renditionFilter
+         - maxItems
+         - skipCount
+        """
+
+        # if Renditions capability is None, return notsupported
+        if self._repository.getCapabilities()['Renditions']:
+            pass
+        else:
+            raise NotSupportedException
+
+        if self.xmlDoc == None:
+            self.reload()
+
+        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        renditions = []
+        for linkElement in linkElements:
+
+            if linkElement.attributes.has_key('rel'):
+                relAttr = linkElement.attributes['rel'].value
+
+                if relAttr == RENDITION_REL:
+                    renditions.append(AtomPubRendition(linkElement))
+        return renditions
+
+    checkedOut = property(isCheckedOut)
+
+    def getPaths(self):
+        """
+        Returns the Document's paths by asking for the parents with the
+        includeRelativePathSegment flag set to true, then concats the value
+        of cmis:path with the relativePathSegment.
+        """
+        # get the appropriate 'up' link
+        parentUrl = self._getLink(UP_REL)
+
+        if parentUrl == None:
+            raise NotSupportedException('Root folder does not support getObjectParents')
+
+        # invoke the URL
+        result = self._cmisClient.binding.get(parentUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              filter='cmis:path',
+                                              includeRelativePathSegment=True)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        paths = []
+        rs = AtomPubResultSet(self._cmisClient, self._repository, result)
+        for res in rs:
+            path = res.properties['cmis:path']
+            relativePathSegment = res.properties['cmisra:relativePathSegment']
+
+            # concat with a slash
+            # add it to the list
+            paths.append(path + '/' + relativePathSegment)
+
+        return paths
+
+
+class AtomPubFolder(AtomPubCmisObject):
+
+    """
+    A container object that can hold other :class:`CmisObject` objects
+    """
+
+    def createFolder(self, name, properties={}):
+
+        """
+        Creates a new :class:`Folder` using the properties provided.
+        Right now I expect a property called 'cmis:name' but I don't
+        complain if it isn't there (although the CMIS provider will). If a
+        cmis:name property isn't provided, the value passed in to the name
+        argument will be used.
+
+        To specify a custom folder type, pass in a property called
+        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
+        of the instance you want to create. If you do not pass in an object
+        type ID, an instance of 'cmis:folder' will be created.
+
+        >>> subFolder = folder.createFolder('someSubfolder')
+        >>> subFolder.getName()
+        u'someSubfolder'
+
+        The following optional arguments are not supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        # get the folder represented by folderId.
+        # we'll use his 'children' link post the new child
+        postUrl = self.getChildrenLink()
+
+        # make sure the name property gets set
+        properties['cmis:name'] = name
+
+        # hardcoding to cmis:folder if it wasn't passed in via props
+        if not properties.has_key('cmis:objectTypeId'):
+            properties['cmis:objectTypeId'] = CmisId('cmis:folder')
+        # and checking to make sure the object type ID is an instance of CmisId
+        elif not isinstance(properties['cmis:objectTypeId'], CmisId):
+            properties['cmis:objectTypeId'] = CmisId(properties['cmis:objectTypeId'])
+
+        # build the Atom entry
+        entryXml = getEntryXmlDoc(self._repository, properties=properties)
+
+        # post the Atom entry
+        result = self._cmisClient.binding.post(postUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               entryXml.toxml(encoding='utf-8'),
+                                               ATOM_XML_ENTRY_TYPE)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # what comes back is the XML for the new folder,
+        # so use it to instantiate a new folder then return it
+        return AtomPubFolder(self._cmisClient, self._repository, xmlDoc=result)
+
+    def createDocumentFromString(self,
+                                 name,
+                                 properties={},
+                                 contentString=None,
+                                 contentType=None,
+                                 contentEncoding=None):
+
+        """
+        Creates a new document setting the content to the string provided. If
+        the repository supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        This method is essentially a convenience method that wraps your string
+        with a StringIO and then calls createDocument.
+
+        >>> testFolder.createDocumentFromString('testdoc3', contentString='hello, world', contentType='text/plain')
+        """
+
+        return self._repository.createDocumentFromString(name, properties,
+            self, contentString, contentType, contentEncoding)
+
+    def createDocument(self, name, properties={}, contentFile=None,
+            contentType=None, contentEncoding=None):
+
+        """
+        Creates a new Document object in the repository using
+        the properties provided.
+
+        Right now this is basically the same as createFolder,
+        but this deals with contentStreams. The common logic should
+        probably be moved to CmisObject.createObject.
+
+        The method will attempt to guess the appropriate content
+        type and encoding based on the file. To specify it yourself, pass them
+        in via the contentType and contentEncoding arguments.
+
+        >>> f = open('250px-Cmis_logo.png', 'rb')
+        >>> subFolder.createDocument('logo.png', contentFile=f)
+        <cmislib.model.Document object at 0x10410fa10>
+        >>> f.close()
+
+        If you wanted to set one or more properties when creating the doc, pass
+        in a dict, like this:
+
+        >>> props = {'cmis:someProp':'someVal'}
+        >>> f = open('250px-Cmis_logo.png', 'rb')
+        >>> subFolder.createDocument('logo.png', props, contentFile=f)
+        <cmislib.model.Document object at 0x10410fa10>
+        >>> f.close()
+
+        To specify a custom object type, pass in a property called
+        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
+        of the instance you want to create. If you do not pass in an object
+        type ID, an instance of 'cmis:document' will be created.
+
+        The following optional arguments are not yet supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        return self._repository.createDocument(name,
+                                               properties,
+                                               self,
+                                               contentFile,
+                                               contentType,
+                                               contentEncoding)
+
+    def getChildren(self, **kwargs):
+
+        """
+        Returns a paged :class:`ResultSet`. The result set contains a list of
+        :class:`CmisObject` objects for each child of the Folder. The actual
+        type of the object returned depends on the object's CMIS base type id.
+        For example, the method might return a list that contains both
+        :class:`Document` objects and :class:`Folder` objects.
+
+        >>> childrenRS = subFolder.getChildren()
+        >>> children = childrenRS.getResults()
+
+        The following optional arguments are supported:
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+        """
+
+        # get the appropriate 'down' link
+        childrenUrl = self.getChildrenLink()
+        # invoke the URL
+        result = self._cmisClient.binding.get(childrenUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self._repository, result)
+
+    def getChildrenLink(self):
+
+        """
+        Gets the Atom link that knows how to return this object's children.
+        """
+
+        url = self._getLink(DOWN_REL, ATOM_XML_FEED_TYPE_P)
+
+        assert len(url) > 0, "Could not find the children url"
+
+        return url
+
+    def getDescendantsLink(self):
+
+        """
+        Returns the 'down' link of type `CMIS_TREE_TYPE`
+
+        >>> folder.getDescendantsLink()
+        u'http://localhost:8080/alfresco/s/cmis/s/workspace:SpacesStore/i/86f6bf54-f0e8-4a72-8cb1-213599ba086c/descendants'
+        """
+
+        url = self._getLink(DOWN_REL, CMIS_TREE_TYPE_P)
+
+        assert len(url) > 0, "Could not find the descendants url"
+
+        # some servers return a depth arg as part of this URL
+        # so strip it off but keep other args
+        if url.find("?") >= 0:
+            u = list(urlparse(url))
+            u[4] = '&'.join([p for p in u[4].split('&') if not p.startswith('depth=')])
+            url = urlunparse(u)
+
+        return url
+
+    def getDescendants(self, **kwargs):
+
+        """
+        Gets the descendants of this folder. The descendants are returned as
+        a paged :class:`ResultSet` object. The result set contains a list of
+        :class:`CmisObject` objects where the actual type of each object
+        returned will vary depending on the object's base type id. For example,
+        the method might return a list that contains both :class:`Document`
+        objects and :class:`Folder` objects.
+
+        The following optional argument is supported:
+         - depth. Use depth=-1 for all descendants, which is the default if no
+           depth is specified.
+
+        >>> resultSet = folder.getDescendants()
+        >>> len(resultSet.getResults())
+        105
+        >>> resultSet = folder.getDescendants(depth=1)
+        >>> len(resultSet.getResults())
+        103
+
+        The following optional arguments *may* also work but haven't been
+        tested:
+
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+
+        """
+
+        if not self._repository.getCapabilities()['GetDescendants']:
+            raise NotSupportedException('This repository does not support getDescendants')
+
+        # default the depth to -1, which is all descendants
+        if "depth" not in kwargs:
+            kwargs['depth'] = -1
+
+        # get the appropriate 'down' link
+        descendantsUrl = self.getDescendantsLink()
+
+        # invoke the URL
+        result = self._cmisClient.binding.get(descendantsUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self._repository, result)
+
+    def getTree(self, **kwargs):
+
+        """
+        Unlike :class:`Folder.getChildren` or :class:`Folder.getDescendants`,
+        this method returns only the descendant objects that are folders. The
+        results do not include the current folder.
+
+        The following optional arguments are supported:
+         - depth
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+
+         >>> rs = folder.getTree(depth='2')
+         >>> len(rs.getResults())
+         3
+         >>> for folder in rs.getResults().values():
+         ...     folder.getTitle()
+         ...
+         u'subfolder2'
+         u'parent test folder'
+         u'subfolder'
+        """
+
+        # Get the descendants link and do a GET against it
+        url = self._getLink(FOLDER_TREE_REL)
+        assert url != None, 'Unable to determine folder tree link'
+        result = self._cmisClient.binding.get(url.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubResultSet(self._cmisClient, self, result)
+
+    def getParent(self):
+
+        """
+        This is not yet implemented.
+
+        The optional filter argument is not yet supported.
+        """
+        # get the appropriate 'up' link
+        parentUrl = self._getLink(UP_REL)
+        # invoke the URL
+        result = self._cmisClient.binding.get(parentUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # return the result set
+        return AtomPubFolder(self._cmisClient, self._repository, xmlDoc=result)
+
+    def deleteTree(self, **kwargs):
+
+        """
+        Deletes the folder and all of its descendant objects.
+
+        >>> resultSet = subFolder.getDescendants()
+        >>> len(resultSet.getResults())
+        2
+        >>> subFolder.deleteTree()
+
+        The following optional arguments are supported:
+         - allVersions
+         - unfileObjects
+         - continueOnFailure
+        """
+
+        # Per the spec, the repo must have the GetDescendants capability
+        # to support deleteTree
+        if not self._repository.getCapabilities()['GetDescendants']:
+            raise NotSupportedException('This repository does not support deleteTree')
+
+        # Get the descendants link and do a DELETE against it
+        url = self._getLink(DOWN_REL, CMIS_TREE_TYPE_P)
+        result = self._cmisClient.binding.delete(url.encode('utf-8'),
+                                         self._cmisClient.username,
+                                         self._cmisClient.password,
+                                         **kwargs)
+
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+    def addObject(self, cmisObject, **kwargs):
+
+        """
+        Adds the specified object as a child of this object. No new object is
+        created. The repository must support multifiling for this to work.
+
+        >>> sub1 = repo.getObjectByPath("/cmislib/sub1")
+        >>> sub2 = repo.getObjectByPath("/cmislib/sub2")
+        >>> doc = sub1.createDocument("testdoc1")
+        >>> len(sub1.getChildren())
+        1
+        >>> len(sub2.getChildren())
+        0
+        >>> sub2.addObject(doc)
+        >>> len(sub2.getChildren())
+        1
+        >>> sub2.getChildren()[0].name
+        u'testdoc1'
+
+        The following optional arguments are supported:
+         - allVersions
+        """
+
+        if not self._repository.getCapabilities()['Multifiling']:
+            raise NotSupportedException('This repository does not support multifiling')
+
+        postUrl = self.getChildrenLink()
+
+        # post the Atom entry
+        result = self._cmisClient.binding.post(postUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               cmisObject.xmlDoc.toxml(encoding='utf-8'),
+                                               ATOM_XML_ENTRY_TYPE,
+                                               **kwargs)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+    def removeObject(self, cmisObject):
+
+        """
+        Removes the specified object from this folder. The repository must
+        support unfiling for this to work.
+        """
+
+        if not self._repository.getCapabilities()['Unfiling']:
+            raise NotSupportedException('This repository does not support unfiling')
+
+        postUrl = self._repository.getCollectionLink(UNFILED_COLL)
+
+        args = {"removeFrom": self.getObjectId()}
+
+        # post the Atom entry to the unfiled collection
+        result = self._cmisClient.binding.post(postUrl.encode('utf-8'),
+                                               self._cmisClient.username,
+                                               self._cmisClient.password,
+                                               cmisObject.xmlDoc.toxml(encoding='utf-8'),
+                                               ATOM_XML_ENTRY_TYPE,
+                                               **args)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+    def getPaths(self):
+        """
+        Returns the paths as a list of strings. The spec says folders cannot
+        be multi-filed, so this should always be one value. We return a list
+        to be symmetric with the same method in :class:`Document`.
+        """
+        return [self.properties['cmis:path']]
+
+
+class AtomPubRelationship(AtomPubCmisObject):
+
+    """
+    Defines a relationship object between two :class:`CmisObjects` objects
+    """
+
+    def getSourceId(self):
+
+        """
+        Returns the :class:`CmisId` on the source side of the relationship.
+        """
+
+        if self.xmlDoc == None:
+            self.reload()
+        props = self.getProperties()
+        return AtomPubCmisId(props['cmis:sourceId'])
+
+    def getTargetId(self):
+
+        """
+        Returns the :class:`CmisId` on the target side of the relationship.
+        """
+
+        if self.xmlDoc == None:
+            self.reload()
+        props = self.getProperties()
+        return AtomPubCmisId(props['cmis:targetId'])
+
+    def getSource(self):
+
+        """
+        Returns an instance of the appropriate child-type of :class:`CmisObject`
+        for the source side of the relationship.
+        """
+
+        sourceId = self.getSourceId()
+        return getSpecializedObject(self._repository.getObject(sourceId))
+
+    def getTarget(self):
+
+        """
+        Returns an instance of the appropriate child-type of :class:`CmisObject`
+        for the target side of the relationship.
+        """
+
+        targetId = self.getTargetId()
+        return getSpecializedObject(self._repository.getObject(targetId))
+
+    sourceId = property(getSourceId)
+    targetId = property(getTargetId)
+    source = property(getSource)
+    target = property(getTarget)
+
+
+class AtomPubPolicy(AtomPubCmisObject):
+
+    """
+    An arbirary object that can 'applied' to objects that the
+    repository identifies as being 'controllable'.
+    """
+
+    pass
+
+
+class AtomPubObjectType(ObjectType):
+
+    """
+    Represents the CMIS object type such as 'cmis:document' or 'cmis:folder'.
+    Contains metadata about the type.
+    """
+
+    def __init__(self, cmisClient, repository, typeId=None, xmlDoc=None):
+        """ Constructor """
+        self._cmisClient = cmisClient
+        self._repository = repository
+        self._kwargs = None
+        self._typeId = typeId
+        self.xmlDoc = xmlDoc
+        self.logger = logging.getLogger('cmislib.model.ObjectType')
+        self.logger.info('Creating an instance of ObjectType')
+
+    def __str__(self):
+        """To string"""
+        return self.getTypeId()
+
+    def getTypeId(self):
+
+        """
+        Returns the type ID for this object.
+
+        >>> docType = repo.getTypeDefinition('cmis:document')
+        >>> docType.getTypeId()
+        'cmis:document'
+        """
+
+        if self._typeId == None:
+            if self.xmlDoc == None:
+                self.reload()
+            self._typeId = CmisId(self._getElementValue(CMIS_NS, 'id'))
+
+        return self._typeId
+
+    def _getElementValue(self, namespace, elementName):
+
+        """
+        Helper method to retrieve child element values from type XML.
+        """
+
+        if self.xmlDoc == None:
+            self.reload()
+        #typeEls = self.xmlDoc.getElementsByTagNameNS(CMISRA_NS, 'type')
+        #assert len(typeEls) == 1, "Expected to find exactly one type element but instead found %d" % len(typeEls)
+        #typeEl = typeEls[0]
+        typeEl = None
+        for e in self.xmlDoc.childNodes:
+            if e.nodeType == e.ELEMENT_NODE and e.localName == "type":
+                typeEl = e
+                break
+
+        assert typeEl, "Expected to find one child element named type"
+        els = typeEl.getElementsByTagNameNS(namespace, elementName)
+        if len(els) >= 1:
+            el = els[0]
+            if el and len(el.childNodes) >= 1:
+                return el.childNodes[0].data
+
+    def getLocalName(self):
+        """Getter for cmis:localName"""
+        return self._getElementValue(CMIS_NS, 'localName')
+
+    def getLocalNamespace(self):
+        """Getter for cmis:localNamespace"""
+        return self._getElementValue(CMIS_NS, 'localNamespace')
+
+    def getDisplayName(self):
+        """Getter for cmis:displayName"""
+        return self._getElementValue(CMIS_NS, 'displayName')
+
+    def getQueryName(self):
+        """Getter for cmis:queryName"""
+        return self._getElementValue(CMIS_NS, 'queryName')
+
+    def getDescription(self):
+        """Getter for cmis:description"""
+        return self._getElementValue(CMIS_NS, 'description')
+
+    def getBaseId(self):
+        """Getter for cmis:baseId"""
+        return AtomPubCmisId(self._getElementValue(CMIS_NS, 'baseId'))
+
+    def isCreatable(self):
+        """Getter for cmis:creatable"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'creatable'))
+
+    def isFileable(self):
+        """Getter for cmis:fileable"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'fileable'))
+
+    def isQueryable(self):
+        """Getter for cmis:queryable"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'queryable'))
+
+    def isFulltextIndexed(self):
+        """Getter for cmis:fulltextIndexed"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'fulltextIndexed'))
+
+    def isIncludedInSupertypeQuery(self):
+        """Getter for cmis:includedInSupertypeQuery"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'includedInSupertypeQuery'))
+
+    def isControllablePolicy(self):
+        """Getter for cmis:controllablePolicy"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'controllablePolicy'))
+
+    def isControllableACL(self):
+        """Getter for cmis:controllableACL"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'controllableACL'))
+
+    def getLink(self, rel, linkType):
+
+        """
+        Gets the HREF for the link element with the specified rel and linkType.
+
+        >>> from cmislib.model import ATOM_XML_FEED_TYPE
+        >>> docType.getLink('down', ATOM_XML_FEED_TYPE)
+        u'http://localhost:8080/alfresco/s/cmis/type/cmis:document/children'
+        """
+
+        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        for linkElement in linkElements:
+
+            if linkElement.attributes.has_key('rel') and linkElement.attributes.has_key('type'):
+                relAttr = linkElement.attributes['rel'].value
+                typeAttr = linkElement.attributes['type'].value
+
+                if relAttr == rel and linkType.match(typeAttr):
+                    return linkElement.attributes['href'].value
+
+    def getProperties(self):
+
+        """
+        Returns a list of :class:`Property` objects representing each property
+        defined for this type.
+
+        >>> objType = repo.getTypeDefinition('cmis:relationship')
+        >>> for prop in objType.properties:
+        ...    print 'Id:%s' % prop.id
+        ...    print 'Cardinality:%s' % prop.cardinality
+        ...    print 'Description:%s' % prop.description
+        ...    print 'Display name:%s' % prop.displayName
+        ...    print 'Local name:%s' % prop.localName
+        ...    print 'Local namespace:%s' % prop.localNamespace
+        ...    print 'Property type:%s' % prop.propertyType
+        ...    print 'Query name:%s' % prop.queryName
+        ...    print 'Updatability:%s' % prop.updatability
+        ...    print 'Inherited:%s' % prop.inherited
+        ...    print 'Orderable:%s' % prop.orderable
+        ...    print 'Queryable:%s' % prop.queryable
+        ...    print 'Required:%s' % prop.required
+        ...    print 'Open choice:%s' % prop.openChoice
+        """
+
+        if self.xmlDoc == None:
+            self.reload(includePropertyDefinitions='true')
+        # Currently, property defs don't have an enclosing element. And, the
+        # element name varies depending on type. Until that changes, I'm going
+        # to find all elements unique to a prop, then grab its parent node.
+        propTypeElements = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'propertyType')
+        if len(propTypeElements) <= 0:
+            self.reload(includePropertyDefinitions='true')
+            propTypeElements = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'propertyType')
+            assert len(propTypeElements) > 0, 'Could not retrieve object type property definitions'
+        props = {}
+        for typeEl in propTypeElements:
+            prop = AtomPubProperty(typeEl.parentNode)
+            props[prop.id] = prop
+        return props
+
+    def reload(self, **kwargs):
+        """
+        This method will reload the object's data from the CMIS service.
+        """
+        if kwargs:
+            if self._kwargs:
+                self._kwargs.update(kwargs)
+            else:
+                self._kwargs = kwargs
+        templates = self._repository.getUriTemplates()
+        template = templates['typebyid']['template']
+        params = {'{id}': self._typeId}
+        byTypeIdUrl = multiple_replace(params, template)
+        result = self._cmisClient.binding.get(byTypeIdUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password,
+                                              **kwargs)
+        if type(result) == HTTPError:
+            raise CmisException(result.code)
+
+        # instantiate CmisObject objects with the results and return the list
+        entryElements = result.getElementsByTagNameNS(ATOM_NS, 'entry')
+        assert(len(entryElements) == 1), "Expected entry element in result from calling %s" % byTypeIdUrl
+        self.xmlDoc = entryElements[0]
+
+    id = property(getTypeId)
+    localName = property(getLocalName)
+    localNamespace = property(getLocalNamespace)
+    displayName = property(getDisplayName)
+    queryName = property(getQueryName)
+    description = property(getDescription)
+    baseId = property(getBaseId)
+    creatable = property(isCreatable)
+    fileable = property(isFileable)
+    queryable = property(isQueryable)
+    fulltextIndexed = property(isFulltextIndexed)
+    includedInSupertypeQuery = property(isIncludedInSupertypeQuery)
+    controllablePolicy = property(isControllablePolicy)
+    controllableACL = property(isControllableACL)
+    properties = property(getProperties)
+
+
+class AtomPubProperty(Property):
+
+    """
+    This class represents an attribute or property definition of an object
+    type.
+    """
+
+    def __init__(self, propNode):
+        """Constructor"""
+        self.xmlDoc = propNode
+        self.logger = logging.getLogger('cmislib.model.Property')
+        self.logger.info('Creating an instance of Property')
+
+    def __str__(self):
+        """To string"""
+        return self.getId()
+
+    def _getElementValue(self, namespace, elementName):
+
+        """
+        Utility method for retrieving element values from the object type XML.
+        """
+
+        els = self.xmlDoc.getElementsByTagNameNS(namespace, elementName)
+        if len(els) >= 1:
+            el = els[0]
+            if el and len(el.childNodes) >= 1:
+                return el.childNodes[0].data
+
+    def getId(self):
+        """Getter for cmis:id"""
+        return self._getElementValue(CMIS_NS, 'id')
+
+    def getLocalName(self):
+        """Getter for cmis:localName"""
+        return self._getElementValue(CMIS_NS, 'localName')
+
+    def getLocalNamespace(self):
+        """Getter for cmis:localNamespace"""
+        return self._getElementValue(CMIS_NS, 'localNamespace')
+
+    def getDisplayName(self):
+        """Getter for cmis:displayName"""
+        return self._getElementValue(CMIS_NS, 'displayName')
+
+    def getQueryName(self):
+        """Getter for cmis:queryName"""
+        return self._getElementValue(CMIS_NS, 'queryName')
+
+    def getDescription(self):
+        """Getter for cmis:description"""
+        return self._getElementValue(CMIS_NS, 'description')
+
+    def getPropertyType(self):
+        """Getter for cmis:propertyType"""
+        return self._getElementValue(CMIS_NS, 'propertyType')
+
+    def getCardinality(self):
+        """Getter for cmis:cardinality"""
+        return self._getElementValue(CMIS_NS, 'cardinality')
+
+    def getUpdatability(self):
+        """Getter for cmis:updatability"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'updatability'))
+
+    def isInherited(self):
+        """Getter for cmis:inherited"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'inherited'))
+
+    def isRequired(self):
+        """Getter for cmis:required"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'required'))
+
+    def isQueryable(self):
+        """Getter for cmis:queryable"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'queryable'))
+
+    def isOrderable(self):
+        """Getter for cmis:orderable"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'orderable'))
+
+    def isOpenChoice(self):
+        """Getter for cmis:openChoice"""
+        return parseBoolValue(self._getElementValue(CMIS_NS, 'openChoice'))
+
+    id = property(getId)
+    localName = property(getLocalName)
+    localNamespace = property(getLocalNamespace)
+    displayName = property(getDisplayName)
+    queryName = property(getQueryName)
+    description = property(getDescription)
+    propertyType = property(getPropertyType)
+    cardinality = property(getCardinality)
+    updatability = property(getUpdatability)
+    inherited = property(isInherited)
+    required = property(isRequired)
+    queryable = property(isQueryable)
+    orderable = property(isOrderable)
+    openChoice = property(isOpenChoice)
+
+
+class AtomPubACL(ACL):
+
+    """
+    Represents the Access Control List for an object.
+    """
+
+    def __init__(self, aceList=None, xmlDoc=None):
+
+        """
+        Constructor. Pass in either a list of :class:`ACE` objects or the XML
+        representation of the ACL. If you have only one ACE, don't worry about
+        the list--the constructor will convert it to a list for you.
+        """
+
+        if aceList:
+            self._entries = aceList
+        else:
+            self._entries = {}
+        if xmlDoc:
+            self._xmlDoc = xmlDoc
+            self._entries = self._getEntriesFromXml()
+        else:
+            self._xmlDoc = None
+
+        self.logger = logging.getLogger('cmislib.model.ACL')
+        self.logger.info('Creating an instance of ACL')
+
+    def addEntry(self, principalId, access, direct):
+
+        """
+        Adds an :class:`ACE` entry to the ACL.
+
+        >>> acl = folder.getACL()
+        >>> acl.addEntry('jpotts', 'cmis:read', 'true')
+        >>> acl.addEntry('jsmith', 'cmis:write', 'true')
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
+        """
+        ace = AtomPubACE(principalId, access, direct)
+        self._entries[ace.principalId] = ace
+
+    def removeEntry(self, principalId):
+
+        """
+        Removes the :class:`ACE` entry given a specific principalId.
+
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
+        >>> acl.removeEntry('jsmith')
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>}
+        """
+
+        if self._entries.has_key(principalId):
+            del(self._entries[principalId])
+
+    def clearEntries(self):
+
+        """
+        Clears all :class:`ACE` entries from the ACL and removes the internal
+        XML representation of the ACL.
+
+        >>> acl = ACL()
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
+        >>> acl.entries
+        {'jpotts': <cmislib.model.ACE object at 0x1012c7310>, 'jsmith': <cmislib.model.ACE object at 0x100528490>}
+        >>> acl.getXmlDoc()
+        <xml.dom.minidom.Document instance at 0x1012cbb90>
+        >>> acl.clearEntries()
+        >>> acl.entries
+        >>> acl.getXmlDoc()
+        """
+
+        self._entries.clear()
+        self._xmlDoc = None
+
+    def getEntries(self):
+
+        """
+        Returns a dictionary of :class:`ACE` objects for each Access Control
+        Entry in the ACL. The key value is the ACE principalid.
+
+        >>> acl = ACL()
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
+        >>> for ace in acl.entries.values():
+        ...     print 'principal:%s has the following permissions...' % ace.principalId
+        ...     for perm in ace.permissions:
+        ...             print perm
+        ...
+        principal:jpotts has the following permissions...
+        cmis:write
+        principal:jsmith has the following permissions...
+        cmis:write
+        """
+
+        if self._entries:
+            return self._entries
+        else:
+            if self._xmlDoc:
+                # parse XML doc and build entry list
+                self._entries = self._getEntriesFromXml()
+                # then return it
+                return self._entries
+
+    def _getEntriesFromXml(self):
+
+        """
+        Helper method for getting the :class:`ACE` entries from an XML
+        representation of the ACL.
+        """
+
+        if not self._xmlDoc:
+            return
+        result = {}
+        # first child is the root node, cmis:acl
+        for e in self._xmlDoc.childNodes[0].childNodes:
+            if e.localName == 'permission':
+                # grab the principal/principalId element value
+                prinEl = e.getElementsByTagNameNS(CMIS_NS, 'principal')[0]
+                if prinEl and prinEl.childNodes:
+                    prinIdEl = prinEl.getElementsByTagNameNS(CMIS_NS, 'principalId')[0]
+                    if prinIdEl and prinIdEl.childNodes:
+                        principalId = prinIdEl.childNodes[0].data
+                # grab the permission values
+                permEls = e.getElementsByTagNameNS(CMIS_NS, 'permission')
+                perms = []
+                for permEl in permEls:
+                    if permEl and permEl.childNodes:
+                        perms.append(permEl.childNodes[0].data)
+                # grab the direct value
+                dirEl = e.getElementsByTagNameNS(CMIS_NS, 'direct')[0]
+                if dirEl and dirEl.childNodes:
+                    direct = dirEl.childNodes[0].data
+                # create an ACE
+                if (len(perms) > 0):
+                    ace = AtomPubACE(principalId, perms, direct)
+                    # append it to the dictionary
+                    result[principalId] = ace
+        return result
+
+    def getXmlDoc(self):
+
+        """
+        This method rebuilds the local XML representation of the ACL based on
+        the :class:`ACE` objects in the entries list and returns the resulting
+        XML Document.
+        """
+
+        if not self.getEntries():
+            return
+
+        xmlDoc = minidom.Document()
+        aclEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:acl')
+        aclEl.setAttribute('xmlns:cmis', CMIS_NS)
+        for ace in self.getEntries().values():
+            permEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:permission')
+            #principalId
+            prinEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:principal')
+            prinIdEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:principalId')
+            prinIdElText = xmlDoc.createTextNode(ace.principalId)
+            prinIdEl.appendChild(prinIdElText)
+            prinEl.appendChild(prinIdEl)
+            permEl.appendChild(prinEl)
+            #direct
+            directEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:direct')
+            directElText = xmlDoc.createTextNode(ace.direct)
+            directEl.appendChild(directElText)
+            permEl.appendChild(directEl)
+            #permissions
+            for perm in ace.permissions:
+                permItemEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:permission')
+                permItemElText = xmlDoc.createTextNode(perm)
+                permItemEl.appendChild(permItemElText)
+                permEl.appendChild(permItemEl)
+            aclEl.appendChild(permEl)
+        xmlDoc.appendChild(aclEl)
+        self._xmlDoc = xmlDoc
+        return self._xmlDoc
+
+    entries = property(getEntries)
+
+
+class AtomPubACE(ACE):
+
+    """
+    Represents an individual Access Control Entry.
+    """
+
+    def __init__(self, principalId=None, permissions=None, direct=None):
+        """Constructor"""
+        self._principalId = principalId
+        if permissions:
+            if isinstance(permissions, str):
+                self._permissions = [permissions]
+            else:
+                self._permissions = permissions
+        self._direct = direct
+
+        self.logger = logging.getLogger('cmislib.model.ACE')
+        self.logger.info('Creating an instance of ACE')
+
+    @property
+    def principalId(self):
+        """Getter for principalId"""
+        return self._principalId
+
+    @property
+    def direct(self):
+        """Getter for direct"""
+        return self._direct
+
+    @property
+    def permissions(self):
+        """Getter for permissions"""
+        return self._permissions
+
+
+class AtomPubChangeEntry(ChangeEntry):
+
+    """
+    Represents a change log entry. Retrieve a list of change entries via
+    :meth:`Repository.getContentChanges`.
+
+    >>> for changeEntry in rs:
+    ...     changeEntry.objectId
+    ...     changeEntry.id
+    ...     changeEntry.changeType
+    ...     changeEntry.changeTime
+    ...
+    'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'created'
+    datetime.datetime(2010, 2, 11, 12, 55, 14)
+    'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'updated'
+    datetime.datetime(2010, 2, 11, 12, 55, 13)
+    'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'updated'
+    """
+
+    def __init__(self, cmisClient, repository, xmlDoc):
+        """Constructor"""
+        self._cmisClient = cmisClient
+        self._repository = repository
+        self._xmlDoc = xmlDoc
+        self._properties = {}
+        self._objectId = None
+        self._changeEntryId = None
+        self._changeType = None
+        self._changeTime = None
+        self.logger = logging.getLogger('cmislib.model.ChangeEntry')
+        self.logger.info('Creating an instance of ChangeEntry')
+
+    def getId(self):
+        """
+        Returns the unique ID of the change entry.
+        """
+        if self._changeEntryId == None:
+            self._changeEntryId = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'id')[0].firstChild.data
+        return self._changeEntryId
+
+    def getObjectId(self):
+        """
+        Returns the object ID of the object that changed.
+        """
+        if self._objectId == None:
+            props = self.getProperties()
+            self._objectId = CmisId(props['cmis:objectId'])
+        return self._objectId
+
+    def getChangeType(self):
+
+        """
+        Returns the type of change that occurred. The resulting value must be
+        one of:
+
+         - created
+         - updated
+         - deleted
+         - security
+        """
+
+        if self._changeType == None:
+            self._changeType = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeType')[0].firstChild.data
+        return self._changeType
+
+    def getACL(self):
+
+        """
+        Gets the :class:`ACL` object that is included with this Change Entry.
+        """
+
+        # if you call getContentChanges with includeACL=true, you will get a
+        # cmis:ACL entry. change entries don't appear to have a self URL so
+        # instead of doing a reload with includeACL set to true, we'll either
+        # see if the XML already has an ACL element and instantiate an ACL with
+        # it, or we'll get the ACL_REL link, invoke that, and return the result
+        if not self._repository.getCapabilities()['ACL']:
+            return
+        aclEls = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'acl')
+        aclUrl = self._getLink(ACL_REL)
+        if (len(aclEls) == 1):
+            return AtomPubACL(self._cmisClient, self._repository, aclEls[0])
+        elif aclUrl:
+            result = self._cmisClient.binding.get(aclUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password)
+            if type(result) == HTTPError:
+                raise CmisException(result.code)
+            return AtomPubACL(xmlDoc=result)
+
+    def getChangeTime(self):
+
+        """
+        Returns a datetime object representing the time the change occurred.
+        """
+
+        if self._changeTime == None:
+            self._changeTime = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeTime')[0].firstChild.data
+        return parseDateTimeValue(self._changeTime)
+
+    def getProperties(self):
+
+        """
+        Returns the properties of the change entry. Note that depending on the
+        capabilities of the repository ("capabilityChanges") the list may not
+        include the actual property values that changed.
+        """
+
+        if self._properties == {}:
+            propertiesElement = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'properties')[0]
+            for node in [e for e in propertiesElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
+                propertyName = node.attributes['propertyDefinitionId'].value
+                if node.childNodes and \
+                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0] and \
+                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes:
+                    propertyValue = parsePropValue(
+                       node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes[0].data,
+                       node.localName)
+                else:
+                    propertyValue = None
+                self._properties[propertyName] = propertyValue
+        return self._properties
+
+    def _getLink(self, rel):
+
+        """
+        Returns the HREF attribute of an Atom link element for the
+        specified rel.
+        """
+
+        linkElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        for linkElement in linkElements:
+            if linkElement.attributes.has_key('rel'):
+                relAttr = linkElement.attributes['rel'].value
+
+                if relAttr == rel:
+                    return linkElement.attributes['href'].value
+
+    id = property(getId)
+    objectId = property(getObjectId)
+    changeTime = property(getChangeTime)
+    changeType = property(getChangeType)
+    properties = property(getProperties)
+
+
+    """
+    Represents a change log entry. Retrieve a list of change entries via
+    :meth:`Repository.getContentChanges`.
+
+    >>> for changeEntry in rs:
+    ...     changeEntry.objectId
+    ...     changeEntry.id
+    ...     changeEntry.changeType
+    ...     changeEntry.changeTime
+    ...
+    'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'created'
+    datetime.datetime(2010, 2, 11, 12, 55, 14)
+    'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'updated'
+    datetime.datetime(2010, 2, 11, 12, 55, 13)
+    'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'updated'
+    """
+
+    def __init__(self, cmisClient, repository, xmlDoc):
+        """Constructor"""
+        self._cmisClient = cmisClient
+        self._repository = repository
+        self._xmlDoc = xmlDoc
+        self._properties = {}
+        self._objectId = None
+        self._changeEntryId = None
+        self._changeType = None
+        self._changeTime = None
+        self.logger = logging.getLogger('cmislib.model.ChangeEntry')
+        self.logger.info('Creating an instance of ChangeEntry')
+
+    def getId(self):
+        """
+        Returns the unique ID of the change entry.
+        """
+        if self._changeEntryId == None:
+            self._changeEntryId = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'id')[0].firstChild.data
+        return self._changeEntryId
+
+    def getObjectId(self):
+        """
+        Returns the object ID of the object that changed.
+        """
+        if self._objectId == None:
+            props = self.getProperties()
+            self._objectId = CmisId(props['cmis:objectId'])
+        return self._objectId
+
+    def getChangeType(self):
+
+        """
+        Returns the type of change that occurred. The resulting value must be
+        one of:
+
+         - created
+         - updated
+         - deleted
+         - security
+        """
+
+        if self._changeType == None:
+            self._changeType = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeType')[0].firstChild.data
+        return self._changeType
+
+    def getACL(self):
+
+        """
+        Gets the :class:`ACL` object that is included with this Change Entry.
+        """
+
+        # if you call getContentChanges with includeACL=true, you will get a
+        # cmis:ACL entry. change entries don't appear to have a self URL so
+        # instead of doing a reload with includeACL set to true, we'll either
+        # see if the XML already has an ACL element and instantiate an ACL with
+        # it, or we'll get the ACL_REL link, invoke that, and return the result
+        if not self._repository.getCapabilities()['ACL']:
+            return
+        aclEls = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'acl')
+        aclUrl = self._getLink(ACL_REL)
+        if (len(aclEls) == 1):
+            return AtomPubACL(self._cmisClient, self._repository, aclEls[0])
+        elif aclUrl:
+            result = self._cmisClient.binding.get(aclUrl.encode('utf-8'),
+                                              self._cmisClient.username,
+                                              self._cmisClient.password)
+            if type(result) == HTTPError:
+                raise CmisException(result.code)
+            return AtomPubACL(xmlDoc=result)
+
+    def getChangeTime(self):
+
+        """
+        Returns a datetime object representing the time the change occurred.
+        """
+
+        if self._changeTime == None:
+            self._changeTime = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeTime')[0].firstChild.data
+        return parseDateTimeValue(self._changeTime)
+
+    def getProperties(self):
+
+        """
+        Returns the properties of the change entry. Note that depending on the
+        capabilities of the repository ("capabilityChanges") the list may not
+        include the actual property values that changed.
+        """
+
+        if self._properties == {}:
+            propertiesElement = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'properties')[0]
+            for node in [e for e in propertiesElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
+                propertyName = node.attributes['propertyDefinitionId'].value
+                if node.childNodes and \
+                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0] and \
+                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes:
+                    propertyValue = parsePropValue(
+                       node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes[0].data,
+                       node.localName)
+                else:
+                    propertyValue = None
+                self._properties[propertyName] = propertyValue
+        return self._properties
+
+    def _getLink(self, rel):
+
+        """
+        Returns the HREF attribute of an Atom link element for the
+        specified rel.
+        """
+
+        linkElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
+
+        for linkElement in linkElements:
+            if linkElement.attributes.has_key('rel'):
+                relAttr = linkElement.attributes['rel'].value
+
+                if relAttr == rel:
+                    return linkElement.attributes['href'].value
+
+    id = property(getId)
+    objectId = property(getObjectId)
+    changeTime = property(getChangeTime)
+    changeType = property(getChangeType)
+    properties = property(getProperties)
+
+
+class AtomPubChangeEntryResultSet(AtomPubResultSet):
+
+    """
+    A specialized type of :class:`ResultSet` that knows how to instantiate
+    :class:`ChangeEntry` objects. The parent class assumes children of
+    :class:`CmisObject` which doesn't work for ChangeEntries.
+    """
+
+    def __iter__(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return iter(self.getResults())
+
+    def __getitem__(self, index):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return self.getResults()[index]
+
+    def __len__(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return len(self.getResults())
+
+    def getResults(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        if self._results:
+            return self._results
+
+        if self._xmlDoc:
+            entryElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
+            entries = []
+            for entryElement in entryElements:
+                changeEntry = AtomPubChangeEntry(self._cmisClient, self._repository, entryElement)
+                entries.append(changeEntry)
+
+            self._results = entries
+
+        return self._results
+
+
+class AtomPubRendition(Rendition):
+
+    """
+    This class represents a Rendition.
+    """
+
+    def __init__(self, propNode):
+        """Constructor"""
+        self.xmlDoc = propNode
+        self.logger = logging.getLogger('cmislib.model.Rendition')
+        self.logger.info('Creating an instance of Rendition')
+
+    def __str__(self):
+        """To string"""
+        return self.getStreamId()
+
+    def getStreamId(self):
+        """Getter for the rendition's stream ID"""
+        if self.xmlDoc.attributes.has_key('streamId'):
+            return self.xmlDoc.attributes['streamId'].value
+
+    def getMimeType(self):
+        """Getter for the rendition's mime type"""
+        if self.xmlDoc.attributes.has_key('type'):
+            return self.xmlDoc.attributes['type'].value
+
+    def getLength(self):
+        """Getter for the renditions's length"""
+        if self.xmlDoc.attributes.has_key('length'):
+            return self.xmlDoc.attributes['length'].value
+
+    def getTitle(self):
+        """Getter for the renditions's title"""
+        if self.xmlDoc.attributes.has_key('title'):
+            return self.xmlDoc.attributes['title'].value
+
+    def getKind(self):
+        """Getter for the renditions's kind"""
+        if self.xmlDoc.hasAttributeNS(CMISRA_NS, 'renditionKind'):
+            return self.xmlDoc.getAttributeNS(CMISRA_NS, 'renditionKind')
+
+    def getHeight(self):
+        """Getter for the renditions's height"""
+        if self.xmlDoc.attributes.has_key('height'):
+            return self.xmlDoc.attributes['height'].value
+
+    def getWidth(self):
+        """Getter for the renditions's width"""
+        if self.xmlDoc.attributes.has_key('width'):
+            return self.xmlDoc.attributes['width'].value
+
+    def getHref(self):
+        """Getter for the renditions's href"""
+        if self.xmlDoc.attributes.has_key('href'):
+            return self.xmlDoc.attributes['href'].value
+
+    def getRenditionDocumentId(self):
+        """Getter for the renditions's width"""
+        if self.xmlDoc.attributes.has_key('renditionDocumentId'):
+            return self.xmlDoc.attributes['renditionDocumentId'].value
+
+    streamId = property(getStreamId)
+    mimeType = property(getMimeType)
+    length = property(getLength)
+    title = property(getTitle)
+    kind = property(getKind)
+    height = property(getHeight)
+    width = property(getWidth)
+    href = property(getHref)
+    renditionDocumentId = property(getRenditionDocumentId)
+
+
+class AtomPubCmisId(CmisId):
+
+    """
+    This is a marker class to be used for Strings that are used as CMIS ID's.
+    Making the objects instances of this class makes it easier to create the
+    Atom entry XML with the appropriate type, ie, cmis:propertyId, instead of
+    cmis:propertyString.
+    """
+
+    pass
+
+def getSpecializedObject(obj, **kwargs):
+
+    """
+    Returns an instance of the appropriate :class:`CmisObject` class or one
+    of its child types depending on the specified baseType.
+    """
+
+    moduleLogger.debug('Inside getSpecializedObject')
+
+    if 'cmis:baseTypeId' in obj.getProperties():
+        baseType = obj.getProperties()['cmis:baseTypeId']
+        if baseType == 'cmis:folder':
+            return AtomPubFolder(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
+        if baseType == 'cmis:document':
+            return AtomPubDocument(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
+        if baseType == 'cmis:relationship':
+            return AtomPubRelationship(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
+        if baseType == 'cmis:policy':
+            return AtomPubPolicy(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
+
+    # if the base type ID wasn't found in the props (this can happen when
+    # someone runs a query that doesn't select * or doesn't individually
+    # specify baseTypeId) or if the type isn't one of the known base
+    # types, give the object back
+    return obj
+
+def getEntryXmlDoc(repo=None, objectTypeId=None, properties=None, contentFile=None,
+                    contentType=None, contentEncoding=None):
+
+    """
+    Internal helper method that knows how to build an Atom entry based
+    on the properties and, optionally, the contentFile provided.
+    """
+
+    moduleLogger.debug('Inside getEntryXmlDoc')
+
+    entryXmlDoc = minidom.Document()
+    entryElement = entryXmlDoc.createElementNS(ATOM_NS, "entry")
+    entryElement.setAttribute('xmlns', ATOM_NS)
+    entryElement.setAttribute('xmlns:app', APP_NS)
+    entryElement.setAttribute('xmlns:cmisra', CMISRA_NS)
+    entryXmlDoc.appendChild(entryElement)
+
+    # if there is a File, encode it and add it to the XML
+    if contentFile:
+        mimetype = contentType
+        encoding = contentEncoding
+
+        # need to determine the mime type
+        if not mimetype and hasattr(contentFile, 'name'):
+            mimetype, encoding = mimetypes.guess_type(contentFile.name)
+
+        if not mimetype:
+            mimetype = 'application/binary'
+
+        if not encoding:
+            encoding = 'utf8'
+
+        # This used to be ATOM_NS content but there is some debate among
+        # vendors whether the ATOM_NS content must always be base64
+        # encoded. The spec does mandate that CMISRA_NS content be encoded
+        # and that element takes precedence over ATOM_NS content if it is
+        # present, so it seems reasonable to use CMIS_RA content for now
+        # and encode everything.
+
+        fileData = contentFile.read().encode("base64")
+        mediaElement = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:mediatype')
+        mediaElementText = entryXmlDoc.createTextNode(mimetype)
+        mediaElement.appendChild(mediaElementText)
+        base64Element = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:base64')
+        base64ElementText = entryXmlDoc.createTextNode(fileData)
+        base64Element.appendChild(base64ElementText)
+        contentElement = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:content')
+        contentElement.appendChild(mediaElement)
+        contentElement.appendChild(base64Element)
+        entryElement.appendChild(contentElement)
+
+    objectElement = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:object')
+    objectElement.setAttribute('xmlns:cmis', CMIS_NS)
+    entryElement.appendChild(objectElement)
+
+    if properties:
+        # a name is required for most things, but not for a checkout
+        if properties.has_key('cmis:name'):
+            titleElement = entryXmlDoc.createElementNS(ATOM_NS, "title")
+            titleText = entryXmlDoc.createTextNode(properties['cmis:name'])
+            titleElement.appendChild(titleText)
+            entryElement.appendChild(titleElement)
+
+        propsElement = entryXmlDoc.createElementNS(CMIS_NS, 'cmis:properties')
+        objectElement.appendChild(propsElement)
+
+        typeDef = None
+        for propName, propValue in properties.items():
+            """
+            the name of the element here is significant: it includes the
+            data type. I should be able to figure out the right type based
+            on the actual type of the object passed in.
+
+            I could do a lookup to the type definition, but that doesn't
+            seem worth the performance hit
+            """
+            if (propValue == None or (type(propValue) == list and propValue[0] == None)):
+                # grab the prop type from the typeDef
+                if (typeDef == None):
+                    moduleLogger.debug('Looking up type def for: %s' % objectTypeId)
+                    typeDef = repo.getTypeDefinition(objectTypeId)
+                    #TODO what to do if type not found
+                propType = typeDef.properties[propName].propertyType
+            elif type(propValue) == list:
+                propType = type(propValue[0])
+            else:
+                propType = type(propValue)
+
+            propElementName, propValueStrList = getElementNameAndValues(propType, propName, propValue, type(propValue) == list)
+
+            propElement = entryXmlDoc.createElementNS(CMIS_NS, propElementName)
+            propElement.setAttribute('propertyDefinitionId', propName)
+            for val in propValueStrList:
+                if val == None:
+                    continue
+                valElement = entryXmlDoc.createElementNS(CMIS_NS, 'cmis:value')
+                valText = entryXmlDoc.createTextNode(val)
+                valElement.appendChild(valText)
+                propElement.appendChild(valElement)
+            propsElement.appendChild(propElement)
+
+    return entryXmlDoc
+
+def getElementNameAndValues(propType, propName, propValue, isList=False):
+
+    """
+    For a given property type, property name, and property value, this function
+    returns the appropriate CMIS Atom entry element name and value list.
+    """
+
+    moduleLogger.debug('Inside getElementNameAndValues')
+    moduleLogger.debug('propType:%s propName:%s isList:%s' % (propType, propName, isList))
+    if (propType == 'id' or propType == CmisId):
+        propElementName = 'cmis:propertyId'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                propValueStrList.append(val)
+        else:
+            propValueStrList = [propValue]
+    elif (propType == 'string' or propType == str):
+        propElementName = 'cmis:propertyString'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                propValueStrList.append(val)
+        else:
+            propValueStrList = [propValue]
+    elif (propType == 'datetime' or propType == datetime.datetime):
+        propElementName = 'cmis:propertyDateTime'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                if val != None:
+                    propValueStrList.append(val.isoformat())
+                else:
+                    propValueStrList.append(val)
+        else:
+            if propValue != None:
+                propValueStrList = [propValue.isoformat()]
+            else:
+                propValueStrList = [propValue]
+    elif (propType == 'boolean' or propType == bool):
+        propElementName = 'cmis:propertyBoolean'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                if val != None:
+                    propValueStrList.append(unicode(val).lower())
+                else:
+                    propValueStrList.append(val)
+        else:
+            if propValue != None:
+                propValueStrList = [unicode(propValue).lower()]
+            else:
+                propValueStrList = [propValue]
+    elif (propType == 'integer' or propType == int):
+        propElementName = 'cmis:propertyInteger'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                if val != None:
+                    propValueStrList.append(unicode(val))
+                else:
+                    propValueStrList.append(val)
+        else:
+            if propValue != None:
+                propValueStrList = [unicode(propValue)]
+            else:
+                propValueStrList = [propValue]
+    elif (propType == 'decimal' or propType == float):
+        propElementName = 'cmis:propertyDecimal'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                if val != None:
+                    propValueStrList.append(unicode(val))
+                else:
+                    propValueStrList.append(val)
+        else:
+            if propValue != None:
+                propValueStrList = [unicode(propValue)]
+            else:
+                propValueStrList = [propValue]
+    else:
+        propElementName = 'cmis:propertyString'
+        if isList:
+            propValueStrList = []
+            for val in propValue:
+                if val != None:
+                    propValueStrList.append(unicode(val))
+                else:
+                    propValueStrList.append(val)
+        else:
+            if propValue != None:
+                propValueStrList = [unicode(propValue)]
+            else:
+                propValueStrList = [propValue]
+
+    return propElementName, propValueStrList
+
+
+def getEmptyXmlDoc():
+
+    """
+    Internal helper method that knows how to build an empty Atom entry.
+    """
+
+    moduleLogger.debug('Inside getEmptyXmlDoc')
+
+    entryXmlDoc = minidom.Document()
+    entryElement = entryXmlDoc.createElementNS(ATOM_NS, "entry")
+    entryElement.setAttribute('xmlns', ATOM_NS)
+    entryXmlDoc.appendChild(entryElement)
+    return entryXmlDoc
+
diff --git a/src/cmislib/browser_binding.py b/src/cmislib/browser_binding.py
new file mode 100644
index 0000000..62cbe54
--- /dev/null
+++ b/src/cmislib/browser_binding.py
@@ -0,0 +1,2378 @@
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you 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.
+#
+"""
+Module containing the browser binding-specific objects used to work with a CMIS
+provider.
+"""
+from cmis_services import RepositoryServiceIfc
+from cmis_services import Binding
+from net import RESTService as Rest
+from urllib2 import HTTPError
+from exceptions import CmisException, RuntimeException
+from domain import CmisId, CmisObject, Repository, Relationship, Policy, ObjectType, Property, Folder, Document, ACL, ACE, ChangeEntry, ResultSet, ChangeEntryResultSet, Rendition
+import json
+import logging
+
+class BrowserBinding(Binding):
+    def __init__(self, **kwargs):
+        self.extArgs = kwargs
+
+    def getRepositoryService(self):
+        return RepositoryService()
+
+    def get(self, url, username, password, **kwargs):
+
+        """
+        Does a get against the CMIS service. More than likely, you will not
+        need to call this method. Instead, let the other objects do it for you.
+
+        For example, if you need to get a specific object by object id, try
+        :class:`Repository.getObject`. If you have a path instead of an object
+        id, use :class:`Repository.getObjectByPath`. Or, you could start with
+        the root folder (:class:`Repository.getRootFolder`) and drill down from
+        there.
+        """
+
+        # merge the cmis client extended args with the ones that got passed in
+        if (len(self.extArgs) > 0):
+            kwargs.update(self.extArgs)
+
+        result = Rest().get(url,
+                            username=username,
+                            password=password,
+                            **kwargs)
+        if type(result) == HTTPError:
+            self._processCommonErrors(result)
+        else:
+            result = json.load(result)
+        return result
+
+class RepositoryService(RepositoryServiceIfc):
+    def getRepository(self, client, repositoryId):
+        #TODO
+        pass
+
+    def getRepositories(self, client):
+        result = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
+        if (type(result) == HTTPError):
+            raise RuntimeException()
+
+        repositories = []
+        for repo in result.itervalues():
+            repositories.append({'repositoryId': repo['repositoryId'],
+                                 'repositoryName': repo['repositoryName']})
+        return repositories
+
+    def getDefaultRepository(self, client):
+        result = client.binding.get(client.repositoryUrl, client.username, client.password, **client.extArgs)
+        # instantiate a Repository object with the first workspace
+        # element we find
+        for repo in result.itervalues():
+            repository = BrowserRepository(client, repo)
+        return repository
+
+    def getRepositoryInfo(self):
+        return "Here is your repository info using the browser binding"
+
+
+class BrowserCmisObject(object):
+
+    """
+    Common ancestor class for other CMIS domain objects such as
+    :class:`Document` and :class:`Folder`.
+    """
+
+    def __init__(self, cmisClient, repository, objectId=None, data=None, **kwargs):
+        """ Constructor """
+        self._cmisClient = cmisClient
+        self._repository = repository
+        self._objectId = objectId
+        self._name = None
+        self._properties = {}
+        self._allowableActions = {}
+        self.data = data
+        self._kwargs = kwargs
+        self.logger = logging.getLogger('cmislib.browser_binding.BrowserCmisObject')
+        self.logger.info('Creating an instance of CmisObject')
+
+    def __str__(self):
+        """To string"""
+        return self.getObjectId()
+
+    def reload(self, **kwargs):
+
+        """
+        Fetches the latest representation of this object from the CMIS service.
+        Some methods, like :class:`^Document.checkout` do this for you.
+
+        If you call reload with a properties filter, the filter will be in
+        effect on subsequent calls until the filter argument is changed. To
+        reset to the full list of properties, call reload with filter set to
+        '*'.
+        """
+
+        if kwargs:
+            if self._kwargs:
+                self._kwargs.update(kwargs)
+            else:
+                self._kwargs = kwargs
+
+        byObjectIdUrl = self.getRootFolderUrl() + "?objectId=" + self.objectId
+        self.data = self._cmisClient.binding.get(byObjectIdUrl.encode('utf-8'),
+                                                   self._cmisClient.username,
+                                                   self._cmisClient.password,
+                                                   **addOptions)
+        self._initData()
+
+        # if a returnVersion arg was passed in, it is possible we got back
+        # a different object ID than the value we started with, so it needs
+        # to be cleared out as well
+        if options.has_key('returnVersion') or addOptions.has_key('returnVersion'):
+            self._objectId = None
+    
+    def getObjectId(self):
+
+        """
+        Returns the object ID for this object.
+
+        >>> doc = resultSet.getResults()[0]
+        >>> doc.getObjectId()
+        u'workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339'
+        """
+
+        pass
+
+    def getObjectParents(self, **kwargs):
+        """
+        Gets the parents of this object as a :class:`ResultSet`.
+
+        The following optional arguments are supported:
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includeRelativePathSegment
+        """
+
+        pass
+
+    def getPaths(self):
+        """
+        Returns the object's paths as a list of strings.
+        """
+        # see sub-classes for implementation
+        pass
+
+    def getAllowableActions(self):
+
+        """
+        Returns a dictionary of allowable actions, keyed off of the action name.
+
+        >>> actions = doc.getAllowableActions()
+        >>> for a in actions:
+        ...     print "%s:%s" % (a,actions[a])
+        ...
+        canDeleteContentStream:True
+        canSetContentStream:True
+        canCreateRelationship:True
+        canCheckIn:False
+        canApplyACL:False
+        canDeleteObject:True
+        canGetAllVersions:True
+        canGetObjectParents:True
+        canGetProperties:True
+        """
+
+        pass
+
+    def getTitle(self):
+
+        """
+        Returns the value of the object's cmis:title property.
+        """
+
+        pass
+
+    def getProperties(self):
+
+        """
+        Returns a dict of the object's properties. If CMIS returns an
+        empty element for a property, the property will be in the
+        dict with a value of None.
+
+        >>> props = doc.getProperties()
+        >>> for p in props:
+        ...     print "%s: %s" % (p, props[p])
+        ...
+        cmis:contentStreamMimeType: text/html
+        cmis:creationDate: 2009-12-15T09:45:35.369-06:00
+        cmis:baseTypeId: cmis:document
+        cmis:isLatestMajorVersion: false
+        cmis:isImmutable: false
+        cmis:isMajorVersion: false
+        cmis:objectId: workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339
+
+        The optional filter argument is not yet implemented.
+        """
+
+        pass
+
+    def getName(self):
+
+        """
+        Returns the value of cmis:name from the getProperties() dictionary.
+        We don't need a getter for every standard CMIS property, but name
+        is a pretty common one so it seems to make sense.
+
+        >>> doc.getName()
+        u'system-overview.html'
+        """
+
+        pass
+
+    def updateProperties(self, properties):
+
+        """
+        Updates the properties of an object with the properties provided.
+        Only provide the set of properties that need to be updated.
+
+        >>> folder = repo.getObjectByPath('/someFolder2')
+        >>> folder.getName()
+        u'someFolder2'
+        >>> props = {'cmis:name': 'someFolderFoo'}
+        >>> folder.updateProperties(props)
+        <cmislib.model.Folder object at 0x103ab1210>
+        >>> folder.getName()
+        u'someFolderFoo'
+
+        """
+
+        pass
+
+    def move(self, sourceFolder, targetFolder):
+
+        """
+        Moves an object from the source folder to the target folder.
+
+        >>> sub1 = repo.getObjectByPath('/cmislib/sub1')
+        >>> sub2 = repo.getObjectByPath('/cmislib/sub2')
+        >>> doc = repo.getObjectByPath('/cmislib/sub1/testdoc1')
+        >>> doc.move(sub1, sub2)
+        """
+
+        pass
+
+    def delete(self, **kwargs):
+
+        """
+        Deletes this :class:`CmisObject` from the repository. Note that in the
+        case of a :class:`Folder` object, some repositories will refuse to
+        delete it if it contains children and some will delete it without
+        complaint. If what you really want to do is delete the folder and all
+        of its descendants, use :meth:`~Folder.deleteTree` instead.
+
+        >>> folder.delete()
+
+        The optional allVersions argument is supported.
+        """
+
+        pass
+
+    def applyPolicy(self, policyId):
+
+        """
+        This is not yet implemented.
+        """
+
+        pass
+
+    def createRelationship(self, targetObj, relTypeId):
+
+        """
+        Creates a relationship between this object and a specified target
+        object using the relationship type specified. Returns the new
+        :class:`Relationship` object.
+
+        >>> rel = tstDoc1.createRelationship(tstDoc2, 'R:cmiscustom:assoc')
+        >>> rel.getProperties()
+        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
+
+        """
+
+        pass
+
+    def getRelationships(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` of :class:`Relationship` objects for each
+        relationship where the source is this object.
+
+        >>> rels = tstDoc1.getRelationships()
+        >>> len(rels.getResults())
+        1
+        >>> rel = rels.getResults().values()[0]
+        >>> rel.getProperties()
+        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
+
+        The following optional arguments are supported:
+         - includeSubRelationshipTypes
+         - relationshipDirection
+         - typeId
+         - maxItems
+         - skipCount
+         - filter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def removePolicy(self, policyId):
+
+        """
+        This is not yet implemented.
+        """
+
+        pass
+
+    def getAppliedPolicies(self):
+
+        """
+        This is not yet implemented.
+        """
+
+        pass
+
+    def getACL(self):
+
+        """
+        Repository.getCapabilities['ACL'] must return manage or discover.
+
+        >>> acl = folder.getACL()
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
+
+        The optional onlyBasicPermissions argument is currently not supported.
+        """
+
+        pass
+
+    def applyACL(self, acl):
+
+        """
+        Updates the object with the provided :class:`ACL`.
+        Repository.getCapabilities['ACL'] must return manage to invoke this
+        call.
+
+        >>> acl = folder.getACL()
+        >>> acl.addEntry(ACE('jdoe', 'cmis:write', 'true'))
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
+        """
+
+        pass
+
+    allowableActions = property(getAllowableActions)
+    name = property(getName)
+    id = property(getObjectId)
+    properties = property(getProperties)
+    title = property(getTitle)
+    ACL = property(getACL)
+
+
+class BrowserRepository(object):
+    """
+    Represents a CMIS repository. Will lazily populate itself by
+    calling the repository CMIS service URL.
+
+    You must pass in an instance of a CmisClient when creating an
+    instance of this class.
+    """
+
+    def __init__(self, cmisClient, data=None):
+        """ Constructor """
+        self._cmisClient = cmisClient
+        self.data = data
+        self._repositoryId = None
+        self._repositoryName = None
+        self._repositoryInfo = {}
+        self._capabilities = {}
+        self._permDefs = {}
+        self._permMap = {}
+        self._permissions = None
+        self._propagation = None
+        self.logger = logging.getLogger('cmislib.browser_binding.BrowserRepository')
+        self.logger.info('Creating an instance of Repository')
+
+    def __str__(self):
+        """To string"""
+        return self.getRepositoryName()
+
+    def _initData(self):
+        """
+        This method clears out any local variables that would be out of sync
+        when data is re-fetched from the server.
+        """
+        self._repositoryId = None
+        self._repositoryName = None
+        self._repositoryInfo = {}
+        self._capabilities = {}
+        self._uriTemplates = {}
+        self._permDefs = {}
+        self._permMap = {}
+        self._permissions = None
+        self._propagation = None
+
+    def reload(self):
+        """
+        This method will re-fetch the repository's XML data from the CMIS
+        repository.
+        """
+
+        pass
+
+    def getRepositoryId(self):
+
+        """
+        Returns this repository's unique identifier
+
+        >>> repo = client.getDefaultRepository()
+        >>> repo.getRepositoryId()
+        u'83beb297-a6fa-4ac5-844b-98c871c0eea9'
+        """
+
+        if self._repositoryId == None:
+            if self.data == None:
+                self.reload()
+            self._repositoryId = self.data['repositoryId']
+        return self._repositoryId
+    
+    def getRepositoryName(self):
+
+        """
+        Returns this repository's name
+
+        >>> repo = client.getDefaultRepository()
+        >>> repo.getRepositoryName()
+        u'Main Repository'
+        """
+
+        if self._repositoryName == None:
+            if self.data == None:
+                self.reload()
+            self._repositoryName = self.data['repositoryName']
+        return self._repositoryName
+
+    def getRepositoryInfo(self):
+
+        """
+        Returns a dict of repository information.
+
+        >>> repo = client.getDefaultRepository()>>> repo.getRepositoryName()
+        u'Main Repository'
+        >>> info = repo.getRepositoryInfo()
+        >>> for k,v in info.items():
+        ...     print "%s:%s" % (k,v)
+        ...
+        cmisSpecificationTitle:Version 1.0 Committee Draft 04
+        cmisVersionSupported:1.0
+        repositoryDescription:None
+        productVersion:3.2.0 (r2 2440)
+        rootFolderId:workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348
+        repositoryId:83beb297-a6fa-4ac5-844b-98c871c0eea9
+        repositoryName:Main Repository
+        vendorName:Alfresco
+        productName:Alfresco Repository (Community)
+        """
+
+        if not self._repositoryInfo:
+            if self.data == None:
+                self.reload()
+            repoInfo = {}
+            repoInfo['repositoryId'] = self.data['repositoryId']
+            repoInfo['repositoryName'] = self.data['repositoryName']
+            repoInfo['resositoryDescription'] = self.data['repositoryDescription']
+            repoInfo['vendorName'] = self.data['vendorName']
+            repoInfo['productName'] = self.data['productName']
+            repoInfo['productVersion'] = self.data['productVersion']
+            repoInfo['rootFolderId'] = self.data['rootFolderId']
+            repoInfo['latestChangeLogToken'] = self.data['latestChangeLogToken']
+            repoInfo['cmisVersionSupported'] = self.data['cmisVersionSupported']
+            repoInfo['thinClientURI'] = self.data['thinClientURI']
+            repoInfo['changesIncomplete'] = self.data['changesIncomplete']
+            repoInfo['changesOnType'] = self.data['changesOnType']
+            repoInfo['principalIdAnonymous'] = self.data['principalIdAnonymous']
+            repoInfo['principalIdAnyone'] = self.data['principalIdAnyone']
+            if self.data.has_key('extendedFeatures'):
+                repoInfo['extendedFeatures'] = self.data['extendedFeatures']
+            self._repositoryInfo = repoInfo
+        return self._repositoryInfo
+
+    def getRootFolderUrl(self):
+        if self.data == None:
+            self.reload()
+        return self.data['rootFolderUrl']
+
+    def getObjectByPath(self, path, **kwargs):
+
+        """
+        Returns an object given the path to the object.
+
+        >>> doc = repo.getObjectByPath('/jeff test/sample-b.pdf')
+        >>> doc.getTitle()
+        u'sample-b.pdf'
+
+        The following optional arguments are not currently supported:
+         - filter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def getSupportedPermissions(self):
+        """
+        Returns the value of the cmis:supportedPermissions element. Valid
+        values are:
+
+         - basic: indicates that the CMIS Basic permissions are supported
+         - repository: indicates that repository specific permissions are supported
+         - both: indicates that both CMIS basic permissions and repository specific permissions are supported
+
+        >>> repo.supportedPermissions
+        u'both'
+        """
+
+        if not self.getCapabilities()['ACL']:
+            raise NotSupportedException(messages.NO_ACL_SUPPORT)
+
+        if not self._permissions:
+            if self.data == None:
+                self.reload()
+            if self.data.has_key('aclCapabilities'):
+                if self.data['aclCapabilities'].has_key('supportedPermissions'):
+                    self._permissions = self.data['aclCapabilities']['supportedPermissions']
+        return self._permissions
+
+    def getPermissionDefinitions(self):
+
+        """
+        Returns a dictionary of permission definitions for this repository. The
+        key is the permission string or technical name of the permission
+        and the value is the permission description.
+
+        >>> for permDef in repo.permissionDefinitions:
+        ...     print permDef
+        ...
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.LinkChildren
+        {http://www.alfresco.org/model/content/1.0}folder.Consumer
+        {http://www.alfresco.org/model/security/1.0}All.All
+        {http://www.alfresco.org/model/system/1.0}base.CreateAssociations
+        {http://www.alfresco.org/model/system/1.0}base.FullControl
+        {http://www.alfresco.org/model/system/1.0}base.AddChildren
+        {http://www.alfresco.org/model/system/1.0}base.ReadAssociations
+        {http://www.alfresco.org/model/content/1.0}folder.Editor
+        {http://www.alfresco.org/model/content/1.0}cmobject.Editor
+        {http://www.alfresco.org/model/system/1.0}base.DeleteAssociations
+        cmis:read
+        cmis:write
+        """
+
+        pass
+
+    def getPermissionMap(self):
+
+        """
+        Returns a dictionary representing the permission mapping table where
+        each key is a permission key string and each value is a list of one or
+        more permissions the principal must have to perform the operation.
+
+        >>> for (k,v) in repo.permissionMap.items():
+        ...     print 'To do this: %s, you must have these perms:' % k
+        ...     for perm in v:
+        ...             print perm
+        ...
+        To do this: canCreateFolder.Folder, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
+        To do this: canAddToFolder.Folder, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
+        To do this: canDelete.Object, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.DeleteNode
+        To do this: canCheckin.Document, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/content/1.0}lockable.CheckIn
+        """
+
+        pass
+
+    def getPropagation(self):
+
+        """
+        Returns the value of the cmis:propagation element. Valid values are:
+          - objectonly: indicates that the repository is able to apply ACEs
+            without changing the ACLs of other objects
+          - propagate: indicates that the repository is able to apply ACEs to a
+            given object and propagate this change to all inheriting objects
+
+        >>> repo.propagation
+        u'propagate'
+        """
+
+        pass
+
+    def getCapabilities(self):
+
+        """
+        Returns a dict of repository capabilities.
+
+        >>> caps = repo.getCapabilities()
+        >>> for k,v in caps.items():
+        ...     print "%s:%s" % (k,v)
+        ...
+        PWCUpdatable:True
+        VersionSpecificFiling:False
+        Join:None
+        ContentStreamUpdatability:anytime
+        AllVersionsSearchable:False
+        Renditions:None
+        Multifiling:True
+        GetFolderTree:True
+        GetDescendants:True
+        ACL:None
+        PWCSearchable:True
+        Query:bothcombined
+        Unfiling:False
+        Changes:None
+        """
+
+        if not self._capabilities:
+            if self.data == None:
+                self.reload()
+            caps = {}
+            if self.data.has_key('capabilities'):
+                for cap in self.data['capabilities'].keys():
+                    key = cap.replace('capability', '')
+                    caps[key] = self.data['capabilities'][cap]
+                self._capabilities = caps
+        return self._capabilities
+
+    def getRootFolder(self):
+        """
+        Returns the root folder of the repository
+
+        >>> root = repo.getRootFolder()
+        >>> root.getObjectId()
+        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
+        """
+
+        # get the root folder id
+        rootFolderId = self.getRepositoryInfo()['rootFolderId']
+        # instantiate a Folder object using the ID
+        folder = BrowserFolder(self._cmisClient, self, rootFolderId)
+        # return it
+        return folder
+
+    def getFolder(self, folderId):
+
+        """
+        Returns a :class:`Folder` object for a specified folderId
+
+        >>> someFolder = repo.getFolder('workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348')
+        >>> someFolder.getObjectId()
+        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
+        """
+
+        retObject = self.getObject(folderId)
+        return BrowserFolder(self._cmisClient, self, data=retObject.data)
+
+    def getTypeChildren(self,
+                        typeId=None):
+
+        """
+        Returns a list of :class:`ObjectType` objects corresponding to the
+        child types of the type specified by the typeId.
+
+        If no typeId is provided, the result will be the same as calling
+        `self.getTypeDefinitions`
+
+        These optional arguments are current unsupported:
+         - includePropertyDefinitions
+         - maxItems
+         - skipCount
+
+        >>> baseTypes = repo.getTypeChildren()
+        >>> for baseType in baseTypes:
+        ...     print baseType.getTypeId()
+        ...
+        cmis:folder
+        cmis:relationship
+        cmis:document
+        cmis:policy
+        """
+
+        pass
+
+    def getTypeDescendants(self, typeId=None, **kwargs):
+
+        """
+        Returns a list of :class:`ObjectType` objects corresponding to the
+        descendant types of the type specified by the typeId.
+
+        If no typeId is provided, the repository's "typesdescendants" URL
+        will be called to determine the list of descendant types.
+
+        >>> allTypes = repo.getTypeDescendants()
+        >>> for aType in allTypes:
+        ...     print aType.getTypeId()
+        ...
+        cmis:folder
+        F:cm:systemfolder
+        F:act:savedactionfolder
+        F:app:configurations
+        F:fm:forums
+        F:wcm:avmfolder
+        F:wcm:avmplainfolder
+        F:wca:webfolder
+        F:wcm:avmlayeredfolder
+        F:st:site
+        F:app:glossary
+        F:fm:topic
+
+        These optional arguments are supported:
+         - depth
+         - includePropertyDefinitions
+
+        >>> types = alfRepo.getTypeDescendants('cmis:folder')
+        >>> len(types)
+        17
+        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=1)
+        >>> len(types)
+        12
+        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=2)
+        >>> len(types)
+        17
+        """
+
+        pass
+
+    def getTypeDefinitions(self, **kwargs):
+
+        """
+        Returns a list of :class:`ObjectType` objects representing
+        the base types in the repository.
+
+        >>> baseTypes = repo.getTypeDefinitions()
+        >>> for baseType in baseTypes:
+        ...     print baseType.getTypeId()
+        ...
+        cmis:folder
+        cmis:relationship
+        cmis:document
+        cmis:policy
+        """
+
+        pass
+
+    def getTypeDefinition(self, typeId):
+
+        """
+        Returns an :class:`ObjectType` object for the specified object type id.
+
+        >>> folderType = repo.getTypeDefinition('cmis:folder')
+        """
+
+        pass
+
+    def getLink(self, rel):
+        """
+        Returns the HREF attribute of an Atom link element for the
+        specified rel.
+        """
+
+        pass
+
+    def getCheckedOutDocs(self, **kwargs):
+
+        """
+        Returns a ResultSet of :class:`CmisObject` objects that
+        are currently checked out.
+
+        >>> rs = repo.getCheckedOutDocs()
+        >>> len(rs.getResults())
+        2
+        >>> for doc in repo.getCheckedOutDocs().getResults():
+        ...     doc.getTitle()
+        ...
+        u'sample-a (Working Copy).pdf'
+        u'sample-b (Working Copy).pdf'
+
+        These optional arguments are supported:
+         - folderId
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def getUnfiledDocs(self, **kwargs):
+
+        """
+        Returns a ResultSet of :class:`CmisObject` objects that
+        are currently unfiled.
+
+        >>> rs = repo.getUnfiledDocs()
+        >>> len(rs.getResults())
+        2
+        >>> for doc in repo.getUnfiledDocs().getResults():
+        ...     doc.getTitle()
+        ...
+        u'sample-a.pdf'
+        u'sample-b.pdf'
+
+        These optional arguments are supported:
+         - folderId
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def getObject(self,
+                  objectId,
+                  **kwargs):
+
+        """
+        Returns an object given the specified object ID.
+
+        >>> doc = repo.getObject('workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808')
+        >>> doc.getTitle()
+        u'sample-b.pdf'
+
+        The following optional arguments are supported:
+         - returnVersion
+         - filter
+         - includeRelationships
+         - includePolicyIds
+         - renditionFilter
+         - includeACL
+         - includeAllowableActions
+        """
+
+        return getSpecializedObject(BrowserCmisObject(self._cmisClient, self, objectId, **kwargs), **kwargs)
+
+    def query(self, statement, **kwargs):
+
+        """
+        Returns a list of :class:`CmisObject` objects based on the CMIS
+        Query Language passed in as the statement. The actual objects
+        returned will be instances of the appropriate child class based
+        on the object's base type ID.
+
+        In order for the results to be properly instantiated as objects,
+        make sure you include 'cmis:objectId' as one of the fields in
+        your select statement, or just use "SELECT \*".
+
+        If you want the search results to automatically be instantiated with
+        the appropriate sub-class of :class:`CmisObject` you must either
+        include cmis:baseTypeId as one of the fields in your select statement
+        or just use "SELECT \*".
+
+        >>> q = "select * from cmis:document where cmis:name like '%test%'"
+        >>> resultSet = repo.query(q)
+        >>> len(resultSet.getResults())
+        1
+        >>> resultSet.hasNext()
+        False
+
+        The following optional arguments are supported:
+         - searchAllVersions
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - maxItems
+         - skipCount
+
+        >>> q = 'select * from cmis:document'
+        >>> rs = repo.query(q)
+        >>> len(rs.getResults())
+        148
+        >>> rs = repo.query(q, maxItems='5')
+        >>> len(rs.getResults())
+        5
+        >>> rs.hasNext()
+        True
+        """
+
+        pass
+
+    def getContentChanges(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` containing :class:`ChangeEntry` objects.
+
+        >>> for changeEntry in rs:
+        ...     changeEntry.objectId
+        ...     changeEntry.id
+        ...     changeEntry.changeType
+        ...     changeEntry.changeTime
+        ...
+        'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+        u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+        u'created'
+        datetime.datetime(2010, 2, 11, 12, 55, 14)
+        'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+        u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+        u'updated'
+        datetime.datetime(2010, 2, 11, 12, 55, 13)
+        'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+        u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+        u'updated'
+
+        The following optional arguments are supported:
+         - changeLogToken
+         - includeProperties
+         - includePolicyIDs
+         - includeACL
+         - maxItems
+
+        You can get the latest change log token by inspecting the repository
+        info via :meth:`Repository.getRepositoryInfo`.
+
+        >>> repo.info['latestChangeLogToken']
+        u'2692'
+        >>> rs = repo.getContentChanges(changeLogToken='2692')
+        >>> len(rs)
+        1
+        >>> rs[0].id
+        u'urn:uuid:8e88f694-93ef-44c5-9f70-f12fff824be9'
+        >>> rs[0].changeType
+        u'updated'
+        >>> rs[0].changeTime
+        datetime.datetime(2010, 2, 16, 20, 6, 37)
+        """
+
+        pass
+
+    def createDocumentFromString(self,
+                                 name,
+                                 properties={},
+                                 parentFolder=None,
+                                 contentString=None,
+                                 contentType=None,
+                                 contentEncoding=None):
+
+        """
+        Creates a new document setting the content to the string provided. If
+        the repository supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        This method is essentially a convenience method that wraps your string
+        with a StringIO and then calls createDocument.
+
+        >>> repo.createDocumentFromString('testdoc5', parentFolder=testFolder, contentString='Hello, World!', contentType='text/plain')
+        <cmislib.model.Document object at 0x101352ed0>
+        """
+
+        pass
+
+    def createDocument(self,
+                       name,
+                       properties={},
+                       parentFolder=None,
+                       contentFile=None,
+                       contentType=None,
+                       contentEncoding=None):
+
+        """
+        Creates a new :class:`Document` object. If the repository
+        supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        To create a document with an associated contentFile, pass in a
+        File object. The method will attempt to guess the appropriate content
+        type and encoding based on the file. To specify it yourself, pass them
+        in via the contentType and contentEncoding arguments.
+
+        >>> f = open('sample-a.pdf', 'rb')
+        >>> doc = folder.createDocument('sample-a.pdf', contentFile=f)
+        <cmislib.model.Document object at 0x105be5e10>
+        >>> f.close()
+        >>> doc.getTitle()
+        u'sample-a.pdf'
+
+        The following optional arguments are not currently supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createDocumentFromSource(self,
+                                 sourceId,
+                                 properties={},
+                                 parentFolder=None):
+        """
+        This is not yet implemented.
+
+        The following optional arguments are not yet supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createFolder(self,
+                     parentFolder,
+                     name,
+                     properties={}):
+
+        """
+        Creates a new :class:`Folder` object in the specified parentFolder.
+
+        >>> root = repo.getRootFolder()
+        >>> folder = repo.createFolder(root, 'someFolder2')
+        >>> folder.getTitle()
+        u'someFolder2'
+        >>> folder.getObjectId()
+        u'workspace://SpacesStore/2224a63c-350b-438c-be72-8f425e79ce1f'
+
+        The following optional arguments are not yet supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createRelationship(self, sourceObj, targetObj, relType):
+        """
+        Creates a relationship of the specific type between a source object
+        and a target object and returns the new :class:`Relationship` object.
+
+        The following optional arguments are not currently supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createPolicy(self, properties):
+        """
+        This has not yet been implemented.
+
+        The following optional arguments are not currently supported:
+         - folderId
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def getCollection(self, collectionType, **kwargs):
+
+        """
+        Returns a list of objects returned for the specified collection.
+
+        If the query collection is requested, an exception will be raised.
+        That collection isn't meant to be retrieved.
+
+        If the types collection is specified, the method returns the result of
+        `getTypeDefinitions` and ignores any optional params passed in.
+
+        >>> from cmislib.model import TYPES_COLL
+        >>> types = repo.getCollection(TYPES_COLL)
+        >>> len(types)
+        4
+        >>> types[0].getTypeId()
+        u'cmis:folder'
+
+        Otherwise, the collection URL is invoked, and a :class:`ResultSet` is
+        returned.
+
+        >>> from cmislib.model import CHECKED_OUT_COLL
+        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
+        >>> len(resultSet.getResults())
+        1
+        """
+
+        pass
+
+    capabilities = property(getCapabilities)
+    id = property(getRepositoryId)
+    info = property(getRepositoryInfo)
+    name = property(getRepositoryName)
+    rootFolder = property(getRootFolder)
+    permissionDefinitions = property(getPermissionDefinitions)
+    permissionMap = property(getPermissionMap)
+    propagation = property(getPropagation)
+    supportedPermissions = property(getSupportedPermissions)
+
+
+class BrowserResultSet(object):
+
+    """
+    Represents a paged result set. In CMIS, this is most often an Atom feed.
+    """
+
+    def __iter__(self):
+        ''' Iterator for the result set '''
+        return iter(self.getResults())
+
+    def __getitem__(self, index):
+        ''' Getter for the result set '''
+        return self.getResults()[index]
+
+    def __len__(self):
+        ''' Len method for the result set '''
+        return len(self.getResults())
+
+    def reload(self):
+
+        '''
+        Re-invokes the self link for the current set of results.
+
+        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
+        >>> resultSet.reload()
+
+        '''
+
+        pass
+
+    def getResults(self):
+
+        '''
+        Returns the results that were fetched and cached by the get*Page call.
+
+        >>> resultSet = repo.getCheckedOutDocs()
+        >>> resultSet.hasNext()
+        False
+        >>> for result in resultSet.getResults():
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x104851810>
+        '''
+
+        pass
+
+    def hasObject(self, objectId):
+
+        '''
+        Returns True if the specified objectId is found in the list of results,
+        otherwise returns False.
+        '''
+
+        pass
+
+    def getFirst(self):
+
+        '''
+        Returns the first page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server returns a "first" link. Not all of them do.
+
+        >>> resultSet.hasFirst()
+        True
+        >>> results = resultSet.getFirst()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def getPrev(self):
+
+        '''
+        Returns the prev page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server returns a "prev" link. Not all of them do.
+        >>> resultSet.hasPrev()
+        True
+        >>> results = resultSet.getPrev()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def getNext(self):
+
+        '''
+        Returns the next page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type.
+        >>> resultSet.hasNext()
+        True
+        >>> results = resultSet.getNext()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def getLast(self):
+
+        '''
+        Returns the last page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server is returning a "last" link. Not all of them do.
+
+        >>> resultSet.hasLast()
+        True
+        >>> results = resultSet.getLast()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def hasNext(self):
+
+        '''
+        Returns True if this page contains a next link.
+
+        >>> resultSet.hasNext()
+        True
+        '''
+
+        pass
+
+    def hasPrev(self):
+
+        '''
+        Returns True if this page contains a prev link. Not all CMIS providers
+        implement prev links consistently.
+
+        >>> resultSet.hasPrev()
+        True
+        '''
+
+        pass
+
+    def hasFirst(self):
+
+        '''
+        Returns True if this page contains a first link. Not all CMIS providers
+        implement first links consistently.
+
+        >>> resultSet.hasFirst()
+        True
+        '''
+
+        pass
+
+    def hasLast(self):
+
+        '''
+        Returns True if this page contains a last link. Not all CMIS providers
+        implement last links consistently.
+
+        >>> resultSet.hasLast()
+        True
+        '''
+
+        pass
+
+
+class BrowserDocument(CmisObject):
+
+    """
+    An object typically associated with file content.
+    """
+
+    def checkout(self):
+
+        """
+        Performs a checkout on the :class:`Document` and returns the
+        Private Working Copy (PWC), which is also an instance of
+        :class:`Document`
+
+        >>> doc.getObjectId()
+        u'workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808;1.0'
+        >>> doc.isCheckedOut()
+        False
+        >>> pwc = doc.checkout()
+        >>> doc.isCheckedOut()
+        True
+        """
+
+        pass
+
+    def cancelCheckout(self):
+        """
+        Cancels the checkout of this object by retrieving the Private Working
+        Copy (PWC) and then deleting it. After the PWC is deleted, this object
+        will be reloaded to update properties related to a checkout.
+
+        >>> doc.isCheckedOut()
+        True
+        >>> doc.cancelCheckout()
+        >>> doc.isCheckedOut()
+        False
+        """
+
+        pass
+
+    def getPrivateWorkingCopy(self):
+
+        """
+        Retrieves the object using the object ID in the property:
+        cmis:versionSeriesCheckedOutId then uses getObject to instantiate
+        the object.
+
+        >>> doc.isCheckedOut()
+        False
+        >>> doc.checkout()
+        <cmislib.model.Document object at 0x103a25ad0>
+        >>> pwc = doc.getPrivateWorkingCopy()
+        >>> pwc.getTitle()
+        u'sample-b (Working Copy).pdf'
+        """
+
+        pass
+
+    def isCheckedOut(self):
+
+        """
+        Returns true if the document is checked out.
+
+        >>> doc.isCheckedOut()
+        True
+        >>> doc.cancelCheckout()
+        >>> doc.isCheckedOut()
+        False
+        """
+
+        pass
+
+    def getCheckedOutBy(self):
+
+        """
+        Returns the ID who currently has the document checked out.
+        >>> pwc = doc.checkout()
+        >>> pwc.getCheckedOutBy()
+        u'admin'
+        """
+
+        pass
+
+    def checkin(self, checkinComment=None, **kwargs):
+
+        """
+        Checks in this :class:`Document` which must be a private
+        working copy (PWC).
+
+        >>> doc.isCheckedOut()
+        False
+        >>> pwc = doc.checkout()
+        >>> doc.isCheckedOut()
+        True
+        >>> pwc.checkin()
+        <cmislib.model.Document object at 0x103a8ae90>
+        >>> doc.isCheckedOut()
+        False
+
+        The following optional arguments are supported:
+         - major
+         - properties
+         - contentStream
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def getLatestVersion(self, **kwargs):
+
+        """
+        Returns a :class:`Document` object representing the latest version in
+        the version series.
+
+        The following optional arguments are supported:
+         - major
+         - filter
+         - includeRelationships
+         - includePolicyIds
+         - renditionFilter
+         - includeACL
+         - includeAllowableActions
+
+        >>> latestDoc = doc.getLatestVersion()
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.1'
+        >>> latestDoc = doc.getLatestVersion(major='false')
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.1'
+        >>> latestDoc = doc.getLatestVersion(major='true')
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.0'
+        """
+
+        pass
+
+    def getPropertiesOfLatestVersion(self, **kwargs):
+
+        """
+        Like :class:`^CmisObject.getProperties`, returns a dict of properties
+        from the latest version of this object in the version series.
+
+        The optional major and filter arguments are supported.
+        """
+
+        pass
+
+    def getAllVersions(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` of document objects for the entire
+        version history of this object, including any PWC's.
+
+        The optional filter and includeAllowableActions are
+        supported.
+        """
+
+        pass
+
+    def getContentStream(self):
+
+        """
+        Returns the CMIS service response from invoking the 'enclosure' link.
+
+        >>> doc.getName()
+        u'sample-b.pdf'
+        >>> o = open('tmp.pdf', 'wb')
+        >>> result = doc.getContentStream()
+        >>> o.write(result.read())
+        >>> result.close()
+        >>> o.close()
+        >>> import os.path
+        >>> os.path.getsize('tmp.pdf')
+        117248
+
+        The optional streamId argument is not yet supported.
+        """
+
+        pass
+
+    def setContentStream(self, contentFile, contentType=None):
+
+        """
+        Sets the content stream on this object.
+
+        The following optional arguments are not yet supported:
+         - overwriteFlag=None
+        """
+
+        pass
+
+    def deleteContentStream(self):
+
+        """
+        Delete's the content stream associated with this object.
+        """
+
+        pass
+
+    def getRenditions(self):
+
+        """
+        Returns an array of :class:`Rendition` objects. The repository
+        must support the Renditions capability.
+
+        The following optional arguments are not currently supported:
+         - renditionFilter
+         - maxItems
+         - skipCount
+        """
+
+        pass
+
+    checkedOut = property(isCheckedOut)
+
+    def getPaths(self):
+        """
+        Returns the Document's paths by asking for the parents with the
+        includeRelativePathSegment flag set to true, then concats the value
+        of cmis:path with the relativePathSegment.
+        """
+
+        pass
+
+class BrowserFolder(BrowserCmisObject):
+
+    """
+    A container object that can hold other :class:`CmisObject` objects
+    """
+
+    def createFolder(self, name, properties={}):
+
+        """
+        Creates a new :class:`Folder` using the properties provided.
+        Right now I expect a property called 'cmis:name' but I don't
+        complain if it isn't there (although the CMIS provider will). If a
+        cmis:name property isn't provided, the value passed in to the name
+        argument will be used.
+
+        To specify a custom folder type, pass in a property called
+        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
+        of the instance you want to create. If you do not pass in an object
+        type ID, an instance of 'cmis:folder' will be created.
+
+        >>> subFolder = folder.createFolder('someSubfolder')
+        >>> subFolder.getName()
+        u'someSubfolder'
+
+        The following optional arguments are not supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createDocumentFromString(self,
+                                 name,
+                                 properties={},
+                                 contentString=None,
+                                 contentType=None,
+                                 contentEncoding=None):
+
+        """
+        Creates a new document setting the content to the string provided. If
+        the repository supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        This method is essentially a convenience method that wraps your string
+        with a StringIO and then calls createDocument.
+
+        >>> testFolder.createDocumentFromString('testdoc3', contentString='hello, world', contentType='text/plain')
+        """
+
+        pass
+
+    def createDocument(self, name, properties={}, contentFile=None,
+            contentType=None, contentEncoding=None):
+
+        """
+        Creates a new Document object in the repository using
+        the properties provided.
+
+        Right now this is basically the same as createFolder,
+        but this deals with contentStreams. The common logic should
+        probably be moved to CmisObject.createObject.
+
+        The method will attempt to guess the appropriate content
+        type and encoding based on the file. To specify it yourself, pass them
+        in via the contentType and contentEncoding arguments.
+
+        >>> f = open('250px-Cmis_logo.png', 'rb')
+        >>> subFolder.createDocument('logo.png', contentFile=f)
+        <cmislib.model.Document object at 0x10410fa10>
+        >>> f.close()
+
+        If you wanted to set one or more properties when creating the doc, pass
+        in a dict, like this:
+
+        >>> props = {'cmis:someProp':'someVal'}
+        >>> f = open('250px-Cmis_logo.png', 'rb')
+        >>> subFolder.createDocument('logo.png', props, contentFile=f)
+        <cmislib.model.Document object at 0x10410fa10>
+        >>> f.close()
+
+        To specify a custom object type, pass in a property called
+        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
+        of the instance you want to create. If you do not pass in an object
+        type ID, an instance of 'cmis:document' will be created.
+
+        The following optional arguments are not yet supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def getChildren(self, **kwargs):
+
+        """
+        Returns a paged :class:`ResultSet`. The result set contains a list of
+        :class:`CmisObject` objects for each child of the Folder. The actual
+        type of the object returned depends on the object's CMIS base type id.
+        For example, the method might return a list that contains both
+        :class:`Document` objects and :class:`Folder` objects.
+
+        >>> childrenRS = subFolder.getChildren()
+        >>> children = childrenRS.getResults()
+
+        The following optional arguments are supported:
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+        """
+
+        pass
+
+    def getDescendants(self, **kwargs):
+
+        """
+        Gets the descendants of this folder. The descendants are returned as
+        a paged :class:`ResultSet` object. The result set contains a list of
+        :class:`CmisObject` objects where the actual type of each object
+        returned will vary depending on the object's base type id. For example,
+        the method might return a list that contains both :class:`Document`
+        objects and :class:`Folder` objects.
+
+        The following optional argument is supported:
+         - depth. Use depth=-1 for all descendants, which is the default if no
+           depth is specified.
+
+        >>> resultSet = folder.getDescendants()
+        >>> len(resultSet.getResults())
+        105
+        >>> resultSet = folder.getDescendants(depth=1)
+        >>> len(resultSet.getResults())
+        103
+
+        The following optional arguments *may* also work but haven't been
+        tested:
+
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+
+        """
+
+        pass
+
+    def getTree(self, **kwargs):
+
+        """
+        Unlike :class:`Folder.getChildren` or :class:`Folder.getDescendants`,
+        this method returns only the descendant objects that are folders. The
+        results do not include the current folder.
+
+        The following optional arguments are supported:
+         - depth
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+
+         >>> rs = folder.getTree(depth='2')
+         >>> len(rs.getResults())
+         3
+         >>> for folder in rs.getResults().values():
+         ...     folder.getTitle()
+         ...
+         u'subfolder2'
+         u'parent test folder'
+         u'subfolder'
+        """
+
+        pass
+
+    def getParent(self):
+
+        """
+        The optional filter argument is not yet supported.
+        """
+
+        pass
+
+    def deleteTree(self, **kwargs):
+
+        """
+        Deletes the folder and all of its descendant objects.
+
+        >>> resultSet = subFolder.getDescendants()
+        >>> len(resultSet.getResults())
+        2
+        >>> subFolder.deleteTree()
+
+        The following optional arguments are supported:
+         - allVersions
+         - unfileObjects
+         - continueOnFailure
+        """
+
+        pass
+
+    def addObject(self, cmisObject, **kwargs):
+
+        """
+        Adds the specified object as a child of this object. No new object is
+        created. The repository must support multifiling for this to work.
+
+        >>> sub1 = repo.getObjectByPath("/cmislib/sub1")
+        >>> sub2 = repo.getObjectByPath("/cmislib/sub2")
+        >>> doc = sub1.createDocument("testdoc1")
+        >>> len(sub1.getChildren())
+        1
+        >>> len(sub2.getChildren())
+        0
+        >>> sub2.addObject(doc)
+        >>> len(sub2.getChildren())
+        1
+        >>> sub2.getChildren()[0].name
+        u'testdoc1'
+
+        The following optional arguments are supported:
+         - allVersions
+        """
+
+        pass
+
+    def removeObject(self, cmisObject):
+
+        """
+        Removes the specified object from this folder. The repository must
+        support unfiling for this to work.
+        """
+
+        pass
+    
+    def getPaths(self):
+        """
+        Returns the paths as a list of strings. The spec says folders cannot
+        be multi-filed, so this should always be one value. We return a list
+        to be symmetric with the same method in :class:`Document`.
+        """
+
+        pass
+
+
+class BrowserRelationship(CmisObject):
+
+    """
+    Defines a relationship object between two :class:`CmisObjects` objects
+    """
+
+    def getSourceId(self):
+
+        """
+        Returns the :class:`CmisId` on the source side of the relationship.
+        """
+
+        pass
+
+    def getTargetId(self):
+
+        """
+        Returns the :class:`CmisId` on the target side of the relationship.
+        """
+
+        pass
+
+    def getSource(self):
+
+        """
+        Returns an instance of the appropriate child-type of :class:`CmisObject`
+        for the source side of the relationship.
+        """
+
+        pass
+
+    def getTarget(self):
+
+        """
+        Returns an instance of the appropriate child-type of :class:`CmisObject`
+        for the target side of the relationship.
+        """
+
+        pass
+
+    sourceId = property(getSourceId)
+    targetId = property(getTargetId)
+    source = property(getSource)
+    target = property(getTarget)
+
+
+class BrowserPolicy(CmisObject):
+
+    """
+    An arbirary object that can 'applied' to objects that the
+    repository identifies as being 'controllable'.
+    """
+
+    pass
+
+
+class BrowserObjectType(object):
+
+    """
+    Represents the CMIS object type such as 'cmis:document' or 'cmis:folder'.
+    Contains metadata about the type.
+    """
+
+    def getTypeId(self):
+
+        """
+        Returns the type ID for this object.
+
+        >>> docType = repo.getTypeDefinition('cmis:document')
+        >>> docType.getTypeId()
+        'cmis:document'
+        """
+
+        pass
+
+    def getLocalName(self):
+        """Getter for cmis:localName"""
+        pass
+
+    def getLocalNamespace(self):
+        """Getter for cmis:localNamespace"""
+        pass
+
+    def getDisplayName(self):
+        """Getter for cmis:displayName"""
+        pass
+
+    def getQueryName(self):
+        """Getter for cmis:queryName"""
+        pass
+
+    def getDescription(self):
+        """Getter for cmis:description"""
+        pass
+
+    def getBaseId(self):
+        """Getter for cmis:baseId"""
+        pass
+
+    def isCreatable(self):
+        """Getter for cmis:creatable"""
+        pass
+
+    def isFileable(self):
+        """Getter for cmis:fileable"""
+        pass
+
+    def isQueryable(self):
+        """Getter for cmis:queryable"""
+        pass
+
+    def isFulltextIndexed(self):
+        """Getter for cmis:fulltextIndexed"""
+        pass
+
+    def isIncludedInSupertypeQuery(self):
+        """Getter for cmis:includedInSupertypeQuery"""
+        pass
+
+    def isControllablePolicy(self):
+        """Getter for cmis:controllablePolicy"""
+        pass
+
+    def isControllableACL(self):
+        """Getter for cmis:controllableACL"""
+        pass
+
+    def getLink(self, rel, linkType):
+
+        """
+        Gets the HREF for the link element with the specified rel and linkType.
+
+        >>> from cmislib.model import ATOM_XML_FEED_TYPE
+        >>> docType.getLink('down', ATOM_XML_FEED_TYPE)
+        u'http://localhost:8080/alfresco/s/cmis/type/cmis:document/children'
+        """
+
+        pass
+
+    def getProperties(self):
+
+        """
+        Returns a list of :class:`Property` objects representing each property
+        defined for this type.
+
+        >>> objType = repo.getTypeDefinition('cmis:relationship')
+        >>> for prop in objType.properties:
+        ...    print 'Id:%s' % prop.id
+        ...    print 'Cardinality:%s' % prop.cardinality
+        ...    print 'Description:%s' % prop.description
+        ...    print 'Display name:%s' % prop.displayName
+        ...    print 'Local name:%s' % prop.localName
+        ...    print 'Local namespace:%s' % prop.localNamespace
+        ...    print 'Property type:%s' % prop.propertyType
+        ...    print 'Query name:%s' % prop.queryName
+        ...    print 'Updatability:%s' % prop.updatability
+        ...    print 'Inherited:%s' % prop.inherited
+        ...    print 'Orderable:%s' % prop.orderable
+        ...    print 'Queryable:%s' % prop.queryable
+        ...    print 'Required:%s' % prop.required
+        ...    print 'Open choice:%s' % prop.openChoice
+        """
+
+        pass
+
+    def reload(self, **kwargs):
+        """
+        This method will reload the object's data from the CMIS service.
+        """
+        pass
+
+    id = property(getTypeId)
+    localName = property(getLocalName)
+    localNamespace = property(getLocalNamespace)
+    displayName = property(getDisplayName)
+    queryName = property(getQueryName)
+    description = property(getDescription)
+    baseId = property(getBaseId)
+    creatable = property(isCreatable)
+    fileable = property(isFileable)
+    queryable = property(isQueryable)
+    fulltextIndexed = property(isFulltextIndexed)
+    includedInSupertypeQuery = property(isIncludedInSupertypeQuery)
+    controllablePolicy = property(isControllablePolicy)
+    controllableACL = property(isControllableACL)
+    properties = property(getProperties)
+
+
+class BrowserProperty(object):
+
+    """
+    This class represents an attribute or property definition of an object
+    type.
+    """
+
+    def getId(self):
+        """Getter for cmis:id"""
+        pass
+
+    def getLocalName(self):
+        """Getter for cmis:localName"""
+        pass
+
+    def getLocalNamespace(self):
+        """Getter for cmis:localNamespace"""
+        pass
+
+    def getDisplayName(self):
+        """Getter for cmis:displayName"""
+        pass
+
+    def getQueryName(self):
+        """Getter for cmis:queryName"""
+        pass
+
+    def getDescription(self):
+        """Getter for cmis:description"""
+        pass
+
+    def getPropertyType(self):
+        """Getter for cmis:propertyType"""
+        pass
+
+    def getCardinality(self):
+        """Getter for cmis:cardinality"""
+        pass
+
+    def getUpdatability(self):
+        """Getter for cmis:updatability"""
+        pass
+
+    def isInherited(self):
+        """Getter for cmis:inherited"""
+        pass
+
+    def isRequired(self):
+        """Getter for cmis:required"""
+        pass
+
+    def isQueryable(self):
+        """Getter for cmis:queryable"""
+        pass
+
+    def isOrderable(self):
+        """Getter for cmis:orderable"""
+        pass
+
+    def isOpenChoice(self):
+        """Getter for cmis:openChoice"""
+        pass
+
+    id = property(getId)
+    localName = property(getLocalName)
+    localNamespace = property(getLocalNamespace)
+    displayName = property(getDisplayName)
+    queryName = property(getQueryName)
+    description = property(getDescription)
+    propertyType = property(getPropertyType)
+    cardinality = property(getCardinality)
+    updatability = property(getUpdatability)
+    inherited = property(isInherited)
+    required = property(isRequired)
+    queryable = property(isQueryable)
+    orderable = property(isOrderable)
+    openChoice = property(isOpenChoice)
+
+
+class BrowserACL(object):
+
+    """
+    Represents the Access Control List for an object.
+    """
+
+    def addEntry(self, ace):
+
+        """
+        Adds an :class:`ACE` entry to the ACL.
+
+        >>> acl = folder.getACL()
+        >>> acl.addEntry(ACE('jpotts', 'cmis:read', 'true'))
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
+        """
+
+        pass
+
+    def removeEntry(self, principalId):
+
+        """
+        Removes the :class:`ACE` entry given a specific principalId.
+
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
+        >>> acl.removeEntry('jsmith')
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>}
+        """
+
+        pass
+
+    def clearEntries(self):
+
+        """
+        Clears all :class:`ACE` entries from the ACL and removes the internal
+        XML representation of the ACL.
+
+        >>> acl = ACL()
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
+        >>> acl.entries
+        {'jpotts': <cmislib.model.ACE object at 0x1012c7310>, 'jsmith': <cmislib.model.ACE object at 0x100528490>}
+        >>> acl.getXmlDoc()
+        <xml.dom.minidom.Document instance at 0x1012cbb90>
+        >>> acl.clearEntries()
+        >>> acl.entries
+        >>> acl.getXmlDoc()
+        """
+
+        pass
+
+    def getEntries(self):
+
+        """
+        Returns a dictionary of :class:`ACE` objects for each Access Control
+        Entry in the ACL. The key value is the ACE principalid.
+
+        >>> acl = ACL()
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
+        >>> for ace in acl.entries.values():
+        ...     print 'principal:%s has the following permissions...' % ace.principalId
+        ...     for perm in ace.permissions:
+        ...             print perm
+        ...
+        principal:jpotts has the following permissions...
+        cmis:write
+        principal:jsmith has the following permissions...
+        cmis:write
+        """
+
+        pass
+
+    entries = property(getEntries)
+
+
+class BrowserACE(object):
+
+    """
+    Represents an individual Access Control Entry.
+    """
+
+    @property
+    def principalId(self):
+        """Getter for principalId"""
+        pass
+
+    @property
+    def direct(self):
+        """Getter for direct"""
+        pass
+
+    @property
+    def permissions(self):
+        """Getter for permissions"""
+        pass
+
+
+class BrowserChangeEntry(object):
+
+    """
+    Represents a change log entry. Retrieve a list of change entries via
+    :meth:`Repository.getContentChanges`.
+
+    >>> for changeEntry in rs:
+    ...     changeEntry.objectId
+    ...     changeEntry.id
+    ...     changeEntry.changeType
+    ...     changeEntry.changeTime
+    ...
+    'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'created'
+    datetime.datetime(2010, 2, 11, 12, 55, 14)
+    'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'updated'
+    datetime.datetime(2010, 2, 11, 12, 55, 13)
+    'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'updated'
+    """
+
+    def getId(self):
+        """
+        Returns the unique ID of the change entry.
+        """
+        pass
+
+    def getObjectId(self):
+        """
+        Returns the object ID of the object that changed.
+        """
+        pass
+
+    def getChangeType(self):
+
+        """
+        Returns the type of change that occurred. The resulting value must be
+        one of:
+
+         - created
+         - updated
+         - deleted
+         - security
+        """
+        pass
+
+    def getACL(self):
+
+        """
+        Gets the :class:`ACL` object that is included with this Change Entry.
+        """
+
+        pass
+
+    def getChangeTime(self):
+
+        """
+        Returns a datetime object representing the time the change occurred.
+        """
+
+        pass
+
+    def getProperties(self):
+
+        """
+        Returns the properties of the change entry. Note that depending on the
+        capabilities of the repository ("capabilityChanges") the list may not
+        include the actual property values that changed.
+        """
+
+        pass
+
+    id = property(getId)
+    objectId = property(getObjectId)
+    changeTime = property(getChangeTime)
+    changeType = property(getChangeType)
+    properties = property(getProperties)
+
+
+class BrowserChangeEntryResultSet(ResultSet):
+
+    """
+    A specialized type of :class:`ResultSet` that knows how to instantiate
+    :class:`ChangeEntry` objects. The parent class assumes children of
+    :class:`CmisObject` which doesn't work for ChangeEntries.
+    """
+
+    def __iter__(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return iter(self.getResults())
+
+    def __getitem__(self, index):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return self.getResults()[index]
+
+    def __len__(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return len(self.getResults())
+
+    def getResults(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        pass
+
+
+class BrowserRendition(object):
+
+    """
+    This class represents a Rendition.
+    """
+
+    def __str__(self):
+        """To string"""
+        return self.getStreamId()
+
+    def getStreamId(self):
+        """Getter for the rendition's stream ID"""
+        pass
+
+    def getMimeType(self):
+        """Getter for the rendition's mime type"""
+        pass
+
+    def getLength(self):
+        """Getter for the renditions's length"""
+        pass
+
+    def getTitle(self):
+        """Getter for the renditions's title"""
+        pass
+
+    def getKind(self):
+        """Getter for the renditions's kind"""
+        pass
+
+    def getHeight(self):
+        """Getter for the renditions's height"""
+        pass
+
+    def getWidth(self):
+        """Getter for the renditions's width"""
+        pass
+
+    def getHref(self):
+        """Getter for the renditions's href"""
+        pass
+
+    def getRenditionDocumentId(self):
+        """Getter for the renditions's width"""
+        pass
+
+    streamId = property(getStreamId)
+    mimeType = property(getMimeType)
+    length = property(getLength)
+    title = property(getTitle)
+    kind = property(getKind)
+    height = property(getHeight)
+    width = property(getWidth)
+    href = property(getHref)
+    renditionDocumentId = property(getRenditionDocumentId)
+
+
+class BrowserCmisId(str):
+
+    """
+    This is a marker class to be used for Strings that are used as CMIS ID's.
+    Making the objects instances of this class makes it easier to create the
+    Atom entry XML with the appropriate type, ie, cmis:propertyId, instead of
+    cmis:propertyString.
+    """
+
+    pass
+
+def getSpecializedObject(obj, **kwargs):
+
+    """
+    Returns an instance of the appropriate :class:`CmisObject` class or one
+    of its child types depending on the specified baseType.
+    """
+
+    moduleLogger.debug('Inside getSpecializedObject')
+
+    if 'cmis:baseTypeId' in obj.getProperties():
+        baseType = obj.getProperties()['cmis:baseTypeId']
+        if baseType == 'cmis:folder':
+            return BrowserFolder(obj._cmisClient, obj._repository, obj.getObjectId(), obj.data, **kwargs)
+        if baseType == 'cmis:document':
+            return BrowserDocument(obj._cmisClient, obj._repository, obj.getObjectId(), obj.data, **kwargs)
+        if baseType == 'cmis:relationship':
+            return BrowserRelationship(obj._cmisClient, obj._repository, obj.getObjectId(), obj.data, **kwargs)
+        if baseType == 'cmis:policy':
+            return BrowserPolicy(obj._cmisClient, obj._repository, obj.getObjectId(), obj.data, **kwargs)
+
+    # if the base type ID wasn't found in the props (this can happen when
+    # someone runs a query that doesn't select * or doesn't individually
+    # specify baseTypeId) or if the type isn't one of the known base
+    # types, give the object back
+    return obj
diff --git a/src/cmislib/cmis_services.py b/src/cmislib/cmis_services.py
new file mode 100644
index 0000000..bea5212
--- /dev/null
+++ b/src/cmislib/cmis_services.py
@@ -0,0 +1,60 @@
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you 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.
+#
+"""
+Module containing the base Binding class and other service objects.
+"""
+from exceptions import CmisException, RuntimeException, \
+    ObjectNotFoundException, InvalidArgumentException, \
+    PermissionDeniedException, NotSupportedException, \
+    UpdateConflictException
+
+class Binding(object):
+    def getRepositoryService():
+        pass
+
+    def _processCommonErrors(self, error):
+
+        """
+        Maps HTTPErrors that are common to all to exceptions. Only errors
+        that are truly global, like 401 not authorized, should be handled
+        here. Callers should handle the rest.
+        """
+
+        if error.status == 401:
+            raise PermissionDeniedException(error.status, error.url)
+        elif error.status == 400:
+            raise InvalidArgumentException(error.status, error.url)
+        elif error.status == 404:
+            raise ObjectNotFoundException(error.status, error.url)
+        elif error.status == 403:
+            raise PermissionDeniedException(error.status, error.url)
+        elif error.status == 405:
+            raise NotSupportedException(error.status, error.url)
+        elif error.status == 409:
+            raise UpdateConflictException(error.status, error.url)
+        elif error.status == 500:
+            raise RuntimeException(error.status, error.url)
+
+
+class RepositoryServiceIfc(object):
+    def getRepositories():
+        pass
+
+    def getRepositoryInfo():
+        pass
diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py
new file mode 100644
index 0000000..1b0cff5
--- /dev/null
+++ b/src/cmislib/domain.py
@@ -0,0 +1,2196 @@
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you 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.
+#
+"""
+Module containing the domain objects used to work with a CMIS provider.
+"""
+import logging
+
+moduleLogger = logging.getLogger('cmislib.domain')
+
+class CmisObject(object):
+
+    """
+    Common ancestor class for other CMIS domain objects such as
+    :class:`Document` and :class:`Folder`.
+    """
+
+    def __str__(self):
+        """To string"""
+        return self.getObjectId()
+
+    def reload(self, **kwargs):
+
+        """
+        Fetches the latest representation of this object from the CMIS service.
+        Some methods, like :class:`^Document.checkout` do this for you.
+
+        If you call reload with a properties filter, the filter will be in
+        effect on subsequent calls until the filter argument is changed. To
+        reset to the full list of properties, call reload with filter set to
+        '*'.
+        """
+
+        pass
+    
+    def getObjectId(self):
+
+        """
+        Returns the object ID for this object.
+
+        >>> doc = resultSet.getResults()[0]
+        >>> doc.getObjectId()
+        u'workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339'
+        """
+
+        pass
+
+    def getObjectParents(self, **kwargs):
+        """
+        Gets the parents of this object as a :class:`ResultSet`.
+
+        The following optional arguments are supported:
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includeRelativePathSegment
+        """
+
+        pass
+
+    def getPaths(self):
+        """
+        Returns the object's paths as a list of strings.
+        """
+        # see sub-classes for implementation
+        pass
+
+    def getAllowableActions(self):
+
+        """
+        Returns a dictionary of allowable actions, keyed off of the action name.
+
+        >>> actions = doc.getAllowableActions()
+        >>> for a in actions:
+        ...     print "%s:%s" % (a,actions[a])
+        ...
+        canDeleteContentStream:True
+        canSetContentStream:True
+        canCreateRelationship:True
+        canCheckIn:False
+        canApplyACL:False
+        canDeleteObject:True
+        canGetAllVersions:True
+        canGetObjectParents:True
+        canGetProperties:True
+        """
+
+        pass
+
+    def getTitle(self):
+
+        """
+        Returns the value of the object's cmis:title property.
+        """
+
+        pass
+
+    def getProperties(self):
+
+        """
+        Returns a dict of the object's properties. If CMIS returns an
+        empty element for a property, the property will be in the
+        dict with a value of None.
+
+        >>> props = doc.getProperties()
+        >>> for p in props:
+        ...     print "%s: %s" % (p, props[p])
+        ...
+        cmis:contentStreamMimeType: text/html
+        cmis:creationDate: 2009-12-15T09:45:35.369-06:00
+        cmis:baseTypeId: cmis:document
+        cmis:isLatestMajorVersion: false
+        cmis:isImmutable: false
+        cmis:isMajorVersion: false
+        cmis:objectId: workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339
+
+        The optional filter argument is not yet implemented.
+        """
+
+        pass
+
+    def getName(self):
+
+        """
+        Returns the value of cmis:name from the getProperties() dictionary.
+        We don't need a getter for every standard CMIS property, but name
+        is a pretty common one so it seems to make sense.
+
+        >>> doc.getName()
+        u'system-overview.html'
+        """
+
+        pass
+
+    def updateProperties(self, properties):
+
+        """
+        Updates the properties of an object with the properties provided.
+        Only provide the set of properties that need to be updated.
+
+        >>> folder = repo.getObjectByPath('/someFolder2')
+        >>> folder.getName()
+        u'someFolder2'
+        >>> props = {'cmis:name': 'someFolderFoo'}
+        >>> folder.updateProperties(props)
+        <cmislib.model.Folder object at 0x103ab1210>
+        >>> folder.getName()
+        u'someFolderFoo'
+
+        """
+
+        pass
+
+    def move(self, sourceFolder, targetFolder):
+
+        """
+        Moves an object from the source folder to the target folder.
+
+        >>> sub1 = repo.getObjectByPath('/cmislib/sub1')
+        >>> sub2 = repo.getObjectByPath('/cmislib/sub2')
+        >>> doc = repo.getObjectByPath('/cmislib/sub1/testdoc1')
+        >>> doc.move(sub1, sub2)
+        """
+
+        pass
+
+    def delete(self, **kwargs):
+
+        """
+        Deletes this :class:`CmisObject` from the repository. Note that in the
+        case of a :class:`Folder` object, some repositories will refuse to
+        delete it if it contains children and some will delete it without
+        complaint. If what you really want to do is delete the folder and all
+        of its descendants, use :meth:`~Folder.deleteTree` instead.
+
+        >>> folder.delete()
+
+        The optional allVersions argument is supported.
+        """
+
+        pass
+
+    def applyPolicy(self, policyId):
+
+        """
+        This is not yet implemented.
+        """
+
+        pass
+
+    def createRelationship(self, targetObj, relTypeId):
+
+        """
+        Creates a relationship between this object and a specified target
+        object using the relationship type specified. Returns the new
+        :class:`Relationship` object.
+
+        >>> rel = tstDoc1.createRelationship(tstDoc2, 'R:cmiscustom:assoc')
+        >>> rel.getProperties()
+        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
+
+        """
+
+        pass
+
+    def getRelationships(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` of :class:`Relationship` objects for each
+        relationship where the source is this object.
+
+        >>> rels = tstDoc1.getRelationships()
+        >>> len(rels.getResults())
+        1
+        >>> rel = rels.getResults().values()[0]
+        >>> rel.getProperties()
+        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
+
+        The following optional arguments are supported:
+         - includeSubRelationshipTypes
+         - relationshipDirection
+         - typeId
+         - maxItems
+         - skipCount
+         - filter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def removePolicy(self, policyId):
+
+        """
+        This is not yet implemented.
+        """
+
+        pass
+
+    def getAppliedPolicies(self):
+
+        """
+        This is not yet implemented.
+        """
+
+        pass
+
+    def getACL(self):
+
+        """
+        Repository.getCapabilities['ACL'] must return manage or discover.
+
+        >>> acl = folder.getACL()
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
+
+        The optional onlyBasicPermissions argument is currently not supported.
+        """
+
+        pass
+
+    def applyACL(self, acl):
+
+        """
+        Updates the object with the provided :class:`ACL`.
+        Repository.getCapabilities['ACL'] must return manage to invoke this
+        call.
+
+        >>> acl = folder.getACL()
+        >>> acl.addEntry(ACE('jdoe', 'cmis:write', 'true'))
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
+        """
+
+        pass
+
+    allowableActions = property(getAllowableActions)
+    name = property(getName)
+    id = property(getObjectId)
+    properties = property(getProperties)
+    title = property(getTitle)
+    ACL = property(getACL)
+
+
+class Repository(object):
+    """
+    Represents a CMIS repository. Will lazily populate itself by
+    calling the repository CMIS service URL.
+
+    You must pass in an instance of a CmisClient when creating an
+    instance of this class.
+    """
+
+    def __init__(self, cmisClient, xmlDoc=None):
+        """ Constructor """
+        self._cmisClient = cmisClient
+        self.xmlDoc = xmlDoc
+        self._repositoryId = None
+        self._repositoryName = None
+        self._repositoryInfo = {}
+        self._capabilities = {}
+        self._permDefs = {}
+        self._permMap = {}
+        self._permissions = None
+        self._propagation = None
+        self.logger = logging.getLogger('cmislib.model.Repository')
+        self.logger.info('Creating an instance of Repository')
+
+    def __str__(self):
+        """To string"""
+        return self.getRepositoryName()
+
+    def _initData(self):
+        """
+        This method clears out any local variables that would be out of sync
+        when data is re-fetched from the server.
+        """
+        self._repositoryId = None
+        self._repositoryName = None
+        self._repositoryInfo = {}
+        self._capabilities = {}
+        self._uriTemplates = {}
+        self._permDefs = {}
+        self._permMap = {}
+        self._permissions = None
+        self._propagation = None
+
+    def reload(self):
+        """
+        This method will re-fetch the repository's XML data from the CMIS
+        repository.
+        """
+
+        pass
+
+    def getRepositoryId(self):
+
+        """
+        Returns this repository's unique identifier
+
+        >>> repo = client.getDefaultRepository()
+        >>> repo.getRepositoryId()
+        u'83beb297-a6fa-4ac5-844b-98c871c0eea9'
+        """
+
+        pass
+    
+    def getRepositoryName(self):
+
+        """
+        Returns this repository's name
+
+        >>> repo = client.getDefaultRepository()
+        >>> repo.getRepositoryName()
+        u'Main Repository'
+        """
+
+        pass
+
+    def getRepositoryInfo(self):
+
+        """
+        Returns a dict of repository information.
+
+        >>> repo = client.getDefaultRepository()>>> repo.getRepositoryName()
+        u'Main Repository'
+        >>> info = repo.getRepositoryInfo()
+        >>> for k,v in info.items():
+        ...     print "%s:%s" % (k,v)
+        ...
+        cmisSpecificationTitle:Version 1.0 Committee Draft 04
+        cmisVersionSupported:1.0
+        repositoryDescription:None
+        productVersion:3.2.0 (r2 2440)
+        rootFolderId:workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348
+        repositoryId:83beb297-a6fa-4ac5-844b-98c871c0eea9
+        repositoryName:Main Repository
+        vendorName:Alfresco
+        productName:Alfresco Repository (Community)
+        """
+
+        pass
+
+    def getObjectByPath(self, path, **kwargs):
+
+        """
+        Returns an object given the path to the object.
+
+        >>> doc = repo.getObjectByPath('/jeff test/sample-b.pdf')
+        >>> doc.getTitle()
+        u'sample-b.pdf'
+
+        The following optional arguments are not currently supported:
+         - filter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def getSupportedPermissions(self):
+        """
+        Returns the value of the cmis:supportedPermissions element. Valid
+        values are:
+
+         - basic: indicates that the CMIS Basic permissions are supported
+         - repository: indicates that repository specific permissions are supported
+         - both: indicates that both CMIS basic permissions and repository specific permissions are supported
+
+        >>> repo.supportedPermissions
+        u'both'
+        """
+
+        pass
+
+    def getPermissionDefinitions(self):
+
+        """
+        Returns a dictionary of permission definitions for this repository. The
+        key is the permission string or technical name of the permission
+        and the value is the permission description.
+
+        >>> for permDef in repo.permissionDefinitions:
+        ...     print permDef
+        ...
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.LinkChildren
+        {http://www.alfresco.org/model/content/1.0}folder.Consumer
+        {http://www.alfresco.org/model/security/1.0}All.All
+        {http://www.alfresco.org/model/system/1.0}base.CreateAssociations
+        {http://www.alfresco.org/model/system/1.0}base.FullControl
+        {http://www.alfresco.org/model/system/1.0}base.AddChildren
+        {http://www.alfresco.org/model/system/1.0}base.ReadAssociations
+        {http://www.alfresco.org/model/content/1.0}folder.Editor
+        {http://www.alfresco.org/model/content/1.0}cmobject.Editor
+        {http://www.alfresco.org/model/system/1.0}base.DeleteAssociations
+        cmis:read
+        cmis:write
+        """
+
+        pass
+
+    def getPermissionMap(self):
+
+        """
+        Returns a dictionary representing the permission mapping table where
+        each key is a permission key string and each value is a list of one or
+        more permissions the principal must have to perform the operation.
+
+        >>> for (k,v) in repo.permissionMap.items():
+        ...     print 'To do this: %s, you must have these perms:' % k
+        ...     for perm in v:
+        ...             print perm
+        ...
+        To do this: canCreateFolder.Folder, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
+        To do this: canAddToFolder.Folder, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
+        To do this: canDelete.Object, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/system/1.0}base.DeleteNode
+        To do this: canCheckin.Document, you must have these perms:
+        cmis:all
+        {http://www.alfresco.org/model/content/1.0}lockable.CheckIn
+        """
+
+        pass
+
+    def getPropagation(self):
+
+        """
+        Returns the value of the cmis:propagation element. Valid values are:
+          - objectonly: indicates that the repository is able to apply ACEs
+            without changing the ACLs of other objects
+          - propagate: indicates that the repository is able to apply ACEs to a
+            given object and propagate this change to all inheriting objects
+
+        >>> repo.propagation
+        u'propagate'
+        """
+
+        pass
+
+    def getCapabilities(self):
+
+        """
+        Returns a dict of repository capabilities.
+
+        >>> caps = repo.getCapabilities()
+        >>> for k,v in caps.items():
+        ...     print "%s:%s" % (k,v)
+        ...
+        PWCUpdatable:True
+        VersionSpecificFiling:False
+        Join:None
+        ContentStreamUpdatability:anytime
+        AllVersionsSearchable:False
+        Renditions:None
+        Multifiling:True
+        GetFolderTree:True
+        GetDescendants:True
+        ACL:None
+        PWCSearchable:True
+        Query:bothcombined
+        Unfiling:False
+        Changes:None
+        """
+
+        pass
+
+    def getRootFolder(self):
+        """
+        Returns the root folder of the repository
+
+        >>> root = repo.getRootFolder()
+        >>> root.getObjectId()
+        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
+        """
+
+        pass
+
+    def getFolder(self, folderId):
+
+        """
+        Returns a :class:`Folder` object for a specified folderId
+
+        >>> someFolder = repo.getFolder('workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348')
+        >>> someFolder.getObjectId()
+        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
+        """
+
+        pass
+
+    def getTypeChildren(self,
+                        typeId=None):
+
+        """
+        Returns a list of :class:`ObjectType` objects corresponding to the
+        child types of the type specified by the typeId.
+
+        If no typeId is provided, the result will be the same as calling
+        `self.getTypeDefinitions`
+
+        These optional arguments are current unsupported:
+         - includePropertyDefinitions
+         - maxItems
+         - skipCount
+
+        >>> baseTypes = repo.getTypeChildren()
+        >>> for baseType in baseTypes:
+        ...     print baseType.getTypeId()
+        ...
+        cmis:folder
+        cmis:relationship
+        cmis:document
+        cmis:policy
+        """
+
+        pass
+
+    def getTypeDescendants(self, typeId=None, **kwargs):
+
+        """
+        Returns a list of :class:`ObjectType` objects corresponding to the
+        descendant types of the type specified by the typeId.
+
+        If no typeId is provided, the repository's "typesdescendants" URL
+        will be called to determine the list of descendant types.
+
+        >>> allTypes = repo.getTypeDescendants()
+        >>> for aType in allTypes:
+        ...     print aType.getTypeId()
+        ...
+        cmis:folder
+        F:cm:systemfolder
+        F:act:savedactionfolder
+        F:app:configurations
+        F:fm:forums
+        F:wcm:avmfolder
+        F:wcm:avmplainfolder
+        F:wca:webfolder
+        F:wcm:avmlayeredfolder
+        F:st:site
+        F:app:glossary
+        F:fm:topic
+
+        These optional arguments are supported:
+         - depth
+         - includePropertyDefinitions
+
+        >>> types = alfRepo.getTypeDescendants('cmis:folder')
+        >>> len(types)
+        17
+        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=1)
+        >>> len(types)
+        12
+        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=2)
+        >>> len(types)
+        17
+        """
+
+        pass
+
+    def getTypeDefinitions(self, **kwargs):
+
+        """
+        Returns a list of :class:`ObjectType` objects representing
+        the base types in the repository.
+
+        >>> baseTypes = repo.getTypeDefinitions()
+        >>> for baseType in baseTypes:
+        ...     print baseType.getTypeId()
+        ...
+        cmis:folder
+        cmis:relationship
+        cmis:document
+        cmis:policy
+        """
+
+        pass
+
+    def getTypeDefinition(self, typeId):
+
+        """
+        Returns an :class:`ObjectType` object for the specified object type id.
+
+        >>> folderType = repo.getTypeDefinition('cmis:folder')
+        """
+
+        pass
+
+    def getLink(self, rel):
+        """
+        Returns the HREF attribute of an Atom link element for the
+        specified rel.
+        """
+
+        pass
+
+    def getCheckedOutDocs(self, **kwargs):
+
+        """
+        Returns a ResultSet of :class:`CmisObject` objects that
+        are currently checked out.
+
+        >>> rs = repo.getCheckedOutDocs()
+        >>> len(rs.getResults())
+        2
+        >>> for doc in repo.getCheckedOutDocs().getResults():
+        ...     doc.getTitle()
+        ...
+        u'sample-a (Working Copy).pdf'
+        u'sample-b (Working Copy).pdf'
+
+        These optional arguments are supported:
+         - folderId
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def getUnfiledDocs(self, **kwargs):
+
+        """
+        Returns a ResultSet of :class:`CmisObject` objects that
+        are currently unfiled.
+
+        >>> rs = repo.getUnfiledDocs()
+        >>> len(rs.getResults())
+        2
+        >>> for doc in repo.getUnfiledDocs().getResults():
+        ...     doc.getTitle()
+        ...
+        u'sample-a.pdf'
+        u'sample-b.pdf'
+
+        These optional arguments are supported:
+         - folderId
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+        """
+
+        pass
+
+    def getObject(self,
+                  objectId,
+                  **kwargs):
+
+        """
+        Returns an object given the specified object ID.
+
+        >>> doc = repo.getObject('workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808')
+        >>> doc.getTitle()
+        u'sample-b.pdf'
+
+        The following optional arguments are supported:
+         - returnVersion
+         - filter
+         - includeRelationships
+         - includePolicyIds
+         - renditionFilter
+         - includeACL
+         - includeAllowableActions
+        """
+
+        pass
+
+    def query(self, statement, **kwargs):
+
+        """
+        Returns a list of :class:`CmisObject` objects based on the CMIS
+        Query Language passed in as the statement. The actual objects
+        returned will be instances of the appropriate child class based
+        on the object's base type ID.
+
+        In order for the results to be properly instantiated as objects,
+        make sure you include 'cmis:objectId' as one of the fields in
+        your select statement, or just use "SELECT \*".
+
+        If you want the search results to automatically be instantiated with
+        the appropriate sub-class of :class:`CmisObject` you must either
+        include cmis:baseTypeId as one of the fields in your select statement
+        or just use "SELECT \*".
+
+        >>> q = "select * from cmis:document where cmis:name like '%test%'"
+        >>> resultSet = repo.query(q)
+        >>> len(resultSet.getResults())
+        1
+        >>> resultSet.hasNext()
+        False
+
+        The following optional arguments are supported:
+         - searchAllVersions
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - maxItems
+         - skipCount
+
+        >>> q = 'select * from cmis:document'
+        >>> rs = repo.query(q)
+        >>> len(rs.getResults())
+        148
+        >>> rs = repo.query(q, maxItems='5')
+        >>> len(rs.getResults())
+        5
+        >>> rs.hasNext()
+        True
+        """
+
+        pass
+
+    def getContentChanges(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` containing :class:`ChangeEntry` objects.
+
+        >>> for changeEntry in rs:
+        ...     changeEntry.objectId
+        ...     changeEntry.id
+        ...     changeEntry.changeType
+        ...     changeEntry.changeTime
+        ...
+        'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+        u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+        u'created'
+        datetime.datetime(2010, 2, 11, 12, 55, 14)
+        'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+        u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+        u'updated'
+        datetime.datetime(2010, 2, 11, 12, 55, 13)
+        'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+        u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+        u'updated'
+
+        The following optional arguments are supported:
+         - changeLogToken
+         - includeProperties
+         - includePolicyIDs
+         - includeACL
+         - maxItems
+
+        You can get the latest change log token by inspecting the repository
+        info via :meth:`Repository.getRepositoryInfo`.
+
+        >>> repo.info['latestChangeLogToken']
+        u'2692'
+        >>> rs = repo.getContentChanges(changeLogToken='2692')
+        >>> len(rs)
+        1
+        >>> rs[0].id
+        u'urn:uuid:8e88f694-93ef-44c5-9f70-f12fff824be9'
+        >>> rs[0].changeType
+        u'updated'
+        >>> rs[0].changeTime
+        datetime.datetime(2010, 2, 16, 20, 6, 37)
+        """
+
+        pass
+
+    def createDocumentFromString(self,
+                                 name,
+                                 properties={},
+                                 parentFolder=None,
+                                 contentString=None,
+                                 contentType=None,
+                                 contentEncoding=None):
+
+        """
+        Creates a new document setting the content to the string provided. If
+        the repository supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        This method is essentially a convenience method that wraps your string
+        with a StringIO and then calls createDocument.
+
+        >>> repo.createDocumentFromString('testdoc5', parentFolder=testFolder, contentString='Hello, World!', contentType='text/plain')
+        <cmislib.model.Document object at 0x101352ed0>
+        """
+
+        pass
+
+    def createDocument(self,
+                       name,
+                       properties={},
+                       parentFolder=None,
+                       contentFile=None,
+                       contentType=None,
+                       contentEncoding=None):
+
+        """
+        Creates a new :class:`Document` object. If the repository
+        supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        To create a document with an associated contentFile, pass in a
+        File object. The method will attempt to guess the appropriate content
+        type and encoding based on the file. To specify it yourself, pass them
+        in via the contentType and contentEncoding arguments.
+
+        >>> f = open('sample-a.pdf', 'rb')
+        >>> doc = folder.createDocument('sample-a.pdf', contentFile=f)
+        <cmislib.model.Document object at 0x105be5e10>
+        >>> f.close()
+        >>> doc.getTitle()
+        u'sample-a.pdf'
+
+        The following optional arguments are not currently supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createDocumentFromSource(self,
+                                 sourceId,
+                                 properties={},
+                                 parentFolder=None):
+        """
+        This is not yet implemented.
+
+        The following optional arguments are not yet supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createFolder(self,
+                     parentFolder,
+                     name,
+                     properties={}):
+
+        """
+        Creates a new :class:`Folder` object in the specified parentFolder.
+
+        >>> root = repo.getRootFolder()
+        >>> folder = repo.createFolder(root, 'someFolder2')
+        >>> folder.getTitle()
+        u'someFolder2'
+        >>> folder.getObjectId()
+        u'workspace://SpacesStore/2224a63c-350b-438c-be72-8f425e79ce1f'
+
+        The following optional arguments are not yet supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createRelationship(self, sourceObj, targetObj, relType):
+        """
+        Creates a relationship of the specific type between a source object
+        and a target object and returns the new :class:`Relationship` object.
+
+        The following optional arguments are not currently supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createPolicy(self, properties):
+        """
+        This has not yet been implemented.
+
+        The following optional arguments are not currently supported:
+         - folderId
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def getCollection(self, collectionType, **kwargs):
+
+        """
+        Returns a list of objects returned for the specified collection.
+
+        If the query collection is requested, an exception will be raised.
+        That collection isn't meant to be retrieved.
+
+        If the types collection is specified, the method returns the result of
+        `getTypeDefinitions` and ignores any optional params passed in.
+
+        >>> from cmislib.model import TYPES_COLL
+        >>> types = repo.getCollection(TYPES_COLL)
+        >>> len(types)
+        4
+        >>> types[0].getTypeId()
+        u'cmis:folder'
+
+        Otherwise, the collection URL is invoked, and a :class:`ResultSet` is
+        returned.
+
+        >>> from cmislib.model import CHECKED_OUT_COLL
+        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
+        >>> len(resultSet.getResults())
+        1
+        """
+
+        pass
+
+    capabilities = property(getCapabilities)
+    id = property(getRepositoryId)
+    info = property(getRepositoryInfo)
+    name = property(getRepositoryName)
+    rootFolder = property(getRootFolder)
+    permissionDefinitions = property(getPermissionDefinitions)
+    permissionMap = property(getPermissionMap)
+    propagation = property(getPropagation)
+    supportedPermissions = property(getSupportedPermissions)
+
+
+class ResultSet(object):
+
+    """
+    Represents a paged result set. In CMIS, this is most often an Atom feed.
+    """
+
+    def __iter__(self):
+        ''' Iterator for the result set '''
+        return iter(self.getResults())
+
+    def __getitem__(self, index):
+        ''' Getter for the result set '''
+        return self.getResults()[index]
+
+    def __len__(self):
+        ''' Len method for the result set '''
+        return len(self.getResults())
+
+    def reload(self):
+
+        '''
+        Re-invokes the self link for the current set of results.
+
+        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
+        >>> resultSet.reload()
+
+        '''
+
+        pass
+
+    def getResults(self):
+
+        '''
+        Returns the results that were fetched and cached by the get*Page call.
+
+        >>> resultSet = repo.getCheckedOutDocs()
+        >>> resultSet.hasNext()
+        False
+        >>> for result in resultSet.getResults():
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x104851810>
+        '''
+
+        pass
+
+    def hasObject(self, objectId):
+
+        '''
+        Returns True if the specified objectId is found in the list of results,
+        otherwise returns False.
+        '''
+
+        pass
+
+    def getFirst(self):
+
+        '''
+        Returns the first page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server returns a "first" link. Not all of them do.
+
+        >>> resultSet.hasFirst()
+        True
+        >>> results = resultSet.getFirst()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def getPrev(self):
+
+        '''
+        Returns the prev page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server returns a "prev" link. Not all of them do.
+        >>> resultSet.hasPrev()
+        True
+        >>> results = resultSet.getPrev()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def getNext(self):
+
+        '''
+        Returns the next page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type.
+        >>> resultSet.hasNext()
+        True
+        >>> results = resultSet.getNext()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def getLast(self):
+
+        '''
+        Returns the last page of results as a dictionary of
+        :class:`CmisObject` objects or its appropriate sub-type. This only
+        works when the server is returning a "last" link. Not all of them do.
+
+        >>> resultSet.hasLast()
+        True
+        >>> results = resultSet.getLast()
+        >>> for result in results:
+        ...     result
+        ...
+        <cmislib.model.Document object at 0x10480bc90>
+        '''
+
+        pass
+
+    def hasNext(self):
+
+        '''
+        Returns True if this page contains a next link.
+
+        >>> resultSet.hasNext()
+        True
+        '''
+
+        pass
+
+    def hasPrev(self):
+
+        '''
+        Returns True if this page contains a prev link. Not all CMIS providers
+        implement prev links consistently.
+
+        >>> resultSet.hasPrev()
+        True
+        '''
+
+        pass
+
+    def hasFirst(self):
+
+        '''
+        Returns True if this page contains a first link. Not all CMIS providers
+        implement first links consistently.
+
+        >>> resultSet.hasFirst()
+        True
+        '''
+
+        pass
+
+    def hasLast(self):
+
+        '''
+        Returns True if this page contains a last link. Not all CMIS providers
+        implement last links consistently.
+
+        >>> resultSet.hasLast()
+        True
+        '''
+
+        pass
+
+
+class Document(CmisObject):
+
+    """
+    An object typically associated with file content.
+    """
+
+    def checkout(self):
+
+        """
+        Performs a checkout on the :class:`Document` and returns the
+        Private Working Copy (PWC), which is also an instance of
+        :class:`Document`
+
+        >>> doc.getObjectId()
+        u'workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808;1.0'
+        >>> doc.isCheckedOut()
+        False
+        >>> pwc = doc.checkout()
+        >>> doc.isCheckedOut()
+        True
+        """
+
+        pass
+
+    def cancelCheckout(self):
+        """
+        Cancels the checkout of this object by retrieving the Private Working
+        Copy (PWC) and then deleting it. After the PWC is deleted, this object
+        will be reloaded to update properties related to a checkout.
+
+        >>> doc.isCheckedOut()
+        True
+        >>> doc.cancelCheckout()
+        >>> doc.isCheckedOut()
+        False
+        """
+
+        pass
+
+    def getPrivateWorkingCopy(self):
+
+        """
+        Retrieves the object using the object ID in the property:
+        cmis:versionSeriesCheckedOutId then uses getObject to instantiate
+        the object.
+
+        >>> doc.isCheckedOut()
+        False
+        >>> doc.checkout()
+        <cmislib.model.Document object at 0x103a25ad0>
+        >>> pwc = doc.getPrivateWorkingCopy()
+        >>> pwc.getTitle()
+        u'sample-b (Working Copy).pdf'
+        """
+
+        pass
+
+    def isCheckedOut(self):
+
+        """
+        Returns true if the document is checked out.
+
+        >>> doc.isCheckedOut()
+        True
+        >>> doc.cancelCheckout()
+        >>> doc.isCheckedOut()
+        False
+        """
+
+        pass
+
+    def getCheckedOutBy(self):
+
+        """
+        Returns the ID who currently has the document checked out.
+        >>> pwc = doc.checkout()
+        >>> pwc.getCheckedOutBy()
+        u'admin'
+        """
+
+        pass
+
+    def checkin(self, checkinComment=None, **kwargs):
+
+        """
+        Checks in this :class:`Document` which must be a private
+        working copy (PWC).
+
+        >>> doc.isCheckedOut()
+        False
+        >>> pwc = doc.checkout()
+        >>> doc.isCheckedOut()
+        True
+        >>> pwc.checkin()
+        <cmislib.model.Document object at 0x103a8ae90>
+        >>> doc.isCheckedOut()
+        False
+
+        The following optional arguments are supported:
+         - major
+         - properties
+         - contentStream
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def getLatestVersion(self, **kwargs):
+
+        """
+        Returns a :class:`Document` object representing the latest version in
+        the version series.
+
+        The following optional arguments are supported:
+         - major
+         - filter
+         - includeRelationships
+         - includePolicyIds
+         - renditionFilter
+         - includeACL
+         - includeAllowableActions
+
+        >>> latestDoc = doc.getLatestVersion()
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.1'
+        >>> latestDoc = doc.getLatestVersion(major='false')
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.1'
+        >>> latestDoc = doc.getLatestVersion(major='true')
+        >>> latestDoc.getProperties()['cmis:versionLabel']
+        u'2.0'
+        """
+
+        pass
+
+    def getPropertiesOfLatestVersion(self, **kwargs):
+
+        """
+        Like :class:`^CmisObject.getProperties`, returns a dict of properties
+        from the latest version of this object in the version series.
+
+        The optional major and filter arguments are supported.
+        """
+
+        pass
+
+    def getAllVersions(self, **kwargs):
+
+        """
+        Returns a :class:`ResultSet` of document objects for the entire
+        version history of this object, including any PWC's.
+
+        The optional filter and includeAllowableActions are
+        supported.
+        """
+
+        pass
+
+    def getContentStream(self):
+
+        """
+        Returns the CMIS service response from invoking the 'enclosure' link.
+
+        >>> doc.getName()
+        u'sample-b.pdf'
+        >>> o = open('tmp.pdf', 'wb')
+        >>> result = doc.getContentStream()
+        >>> o.write(result.read())
+        >>> result.close()
+        >>> o.close()
+        >>> import os.path
+        >>> os.path.getsize('tmp.pdf')
+        117248
+
+        The optional streamId argument is not yet supported.
+        """
+
+        pass
+
+    def setContentStream(self, contentFile, contentType=None):
+
+        """
+        Sets the content stream on this object.
+
+        The following optional arguments are not yet supported:
+         - overwriteFlag=None
+        """
+
+        pass
+
+    def deleteContentStream(self):
+
+        """
+        Delete's the content stream associated with this object.
+        """
+
+        pass
+
+    def getRenditions(self):
+
+        """
+        Returns an array of :class:`Rendition` objects. The repository
+        must support the Renditions capability.
+
+        The following optional arguments are not currently supported:
+         - renditionFilter
+         - maxItems
+         - skipCount
+        """
+
+        pass
+
+    checkedOut = property(isCheckedOut)
+
+    def getPaths(self):
+        """
+        Returns the Document's paths by asking for the parents with the
+        includeRelativePathSegment flag set to true, then concats the value
+        of cmis:path with the relativePathSegment.
+        """
+
+        pass
+
+class Folder(CmisObject):
+
+    """
+    A container object that can hold other :class:`CmisObject` objects
+    """
+
+    def createFolder(self, name, properties={}):
+
+        """
+        Creates a new :class:`Folder` using the properties provided.
+        Right now I expect a property called 'cmis:name' but I don't
+        complain if it isn't there (although the CMIS provider will). If a
+        cmis:name property isn't provided, the value passed in to the name
+        argument will be used.
+
+        To specify a custom folder type, pass in a property called
+        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
+        of the instance you want to create. If you do not pass in an object
+        type ID, an instance of 'cmis:folder' will be created.
+
+        >>> subFolder = folder.createFolder('someSubfolder')
+        >>> subFolder.getName()
+        u'someSubfolder'
+
+        The following optional arguments are not supported:
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def createDocumentFromString(self,
+                                 name,
+                                 properties={},
+                                 contentString=None,
+                                 contentType=None,
+                                 contentEncoding=None):
+
+        """
+        Creates a new document setting the content to the string provided. If
+        the repository supports unfiled objects, you do not have to pass in
+        a parent :class:`Folder` otherwise it is required.
+
+        This method is essentially a convenience method that wraps your string
+        with a StringIO and then calls createDocument.
+
+        >>> testFolder.createDocumentFromString('testdoc3', contentString='hello, world', contentType='text/plain')
+        """
+
+        pass
+
+    def createDocument(self, name, properties={}, contentFile=None,
+            contentType=None, contentEncoding=None):
+
+        """
+        Creates a new Document object in the repository using
+        the properties provided.
+
+        Right now this is basically the same as createFolder,
+        but this deals with contentStreams. The common logic should
+        probably be moved to CmisObject.createObject.
+
+        The method will attempt to guess the appropriate content
+        type and encoding based on the file. To specify it yourself, pass them
+        in via the contentType and contentEncoding arguments.
+
+        >>> f = open('250px-Cmis_logo.png', 'rb')
+        >>> subFolder.createDocument('logo.png', contentFile=f)
+        <cmislib.model.Document object at 0x10410fa10>
+        >>> f.close()
+
+        If you wanted to set one or more properties when creating the doc, pass
+        in a dict, like this:
+
+        >>> props = {'cmis:someProp':'someVal'}
+        >>> f = open('250px-Cmis_logo.png', 'rb')
+        >>> subFolder.createDocument('logo.png', props, contentFile=f)
+        <cmislib.model.Document object at 0x10410fa10>
+        >>> f.close()
+
+        To specify a custom object type, pass in a property called
+        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
+        of the instance you want to create. If you do not pass in an object
+        type ID, an instance of 'cmis:document' will be created.
+
+        The following optional arguments are not yet supported:
+         - versioningState
+         - policies
+         - addACEs
+         - removeACEs
+        """
+
+        pass
+
+    def getChildren(self, **kwargs):
+
+        """
+        Returns a paged :class:`ResultSet`. The result set contains a list of
+        :class:`CmisObject` objects for each child of the Folder. The actual
+        type of the object returned depends on the object's CMIS base type id.
+        For example, the method might return a list that contains both
+        :class:`Document` objects and :class:`Folder` objects.
+
+        >>> childrenRS = subFolder.getChildren()
+        >>> children = childrenRS.getResults()
+
+        The following optional arguments are supported:
+         - maxItems
+         - skipCount
+         - orderBy
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+        """
+
+        pass
+
+    def getDescendants(self, **kwargs):
+
+        """
+        Gets the descendants of this folder. The descendants are returned as
+        a paged :class:`ResultSet` object. The result set contains a list of
+        :class:`CmisObject` objects where the actual type of each object
+        returned will vary depending on the object's base type id. For example,
+        the method might return a list that contains both :class:`Document`
+        objects and :class:`Folder` objects.
+
+        The following optional argument is supported:
+         - depth. Use depth=-1 for all descendants, which is the default if no
+           depth is specified.
+
+        >>> resultSet = folder.getDescendants()
+        >>> len(resultSet.getResults())
+        105
+        >>> resultSet = folder.getDescendants(depth=1)
+        >>> len(resultSet.getResults())
+        103
+
+        The following optional arguments *may* also work but haven't been
+        tested:
+
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+
+        """
+
+        pass
+
+    def getTree(self, **kwargs):
+
+        """
+        Unlike :class:`Folder.getChildren` or :class:`Folder.getDescendants`,
+        this method returns only the descendant objects that are folders. The
+        results do not include the current folder.
+
+        The following optional arguments are supported:
+         - depth
+         - filter
+         - includeRelationships
+         - renditionFilter
+         - includeAllowableActions
+         - includePathSegment
+
+         >>> rs = folder.getTree(depth='2')
+         >>> len(rs.getResults())
+         3
+         >>> for folder in rs.getResults().values():
+         ...     folder.getTitle()
+         ...
+         u'subfolder2'
+         u'parent test folder'
+         u'subfolder'
+        """
+
+        pass
+
+    def getParent(self):
+
+        """
+        The optional filter argument is not yet supported.
+        """
+
+        pass
+
+    def deleteTree(self, **kwargs):
+
+        """
+        Deletes the folder and all of its descendant objects.
+
+        >>> resultSet = subFolder.getDescendants()
+        >>> len(resultSet.getResults())
+        2
+        >>> subFolder.deleteTree()
+
+        The following optional arguments are supported:
+         - allVersions
+         - unfileObjects
+         - continueOnFailure
+        """
+
+        pass
+
+    def addObject(self, cmisObject, **kwargs):
+
+        """
+        Adds the specified object as a child of this object. No new object is
+        created. The repository must support multifiling for this to work.
+
+        >>> sub1 = repo.getObjectByPath("/cmislib/sub1")
+        >>> sub2 = repo.getObjectByPath("/cmislib/sub2")
+        >>> doc = sub1.createDocument("testdoc1")
+        >>> len(sub1.getChildren())
+        1
+        >>> len(sub2.getChildren())
+        0
+        >>> sub2.addObject(doc)
+        >>> len(sub2.getChildren())
+        1
+        >>> sub2.getChildren()[0].name
+        u'testdoc1'
+
+        The following optional arguments are supported:
+         - allVersions
+        """
+
+        pass
+
+    def removeObject(self, cmisObject):
+
+        """
+        Removes the specified object from this folder. The repository must
+        support unfiling for this to work.
+        """
+
+        pass
+    
+    def getPaths(self):
+        """
+        Returns the paths as a list of strings. The spec says folders cannot
+        be multi-filed, so this should always be one value. We return a list
+        to be symmetric with the same method in :class:`Document`.
+        """
+
+        pass
+
+
+class Relationship(CmisObject):
+
+    """
+    Defines a relationship object between two :class:`CmisObjects` objects
+    """
+
+    def getSourceId(self):
+
+        """
+        Returns the :class:`CmisId` on the source side of the relationship.
+        """
+
+        pass
+
+    def getTargetId(self):
+
+        """
+        Returns the :class:`CmisId` on the target side of the relationship.
+        """
+
+        pass
+
+    def getSource(self):
+
+        """
+        Returns an instance of the appropriate child-type of :class:`CmisObject`
+        for the source side of the relationship.
+        """
+
+        pass
+
+    def getTarget(self):
+
+        """
+        Returns an instance of the appropriate child-type of :class:`CmisObject`
+        for the target side of the relationship.
+        """
+
+        pass
+
+    sourceId = property(getSourceId)
+    targetId = property(getTargetId)
+    source = property(getSource)
+    target = property(getTarget)
+
+
+class Policy(CmisObject):
+
+    """
+    An arbirary object that can 'applied' to objects that the
+    repository identifies as being 'controllable'.
+    """
+
+    pass
+
+
+class ObjectType(object):
+
+    """
+    Represents the CMIS object type such as 'cmis:document' or 'cmis:folder'.
+    Contains metadata about the type.
+    """
+
+    def getTypeId(self):
+
+        """
+        Returns the type ID for this object.
+
+        >>> docType = repo.getTypeDefinition('cmis:document')
+        >>> docType.getTypeId()
+        'cmis:document'
+        """
+
+        pass
+
+    def getLocalName(self):
+        """Getter for cmis:localName"""
+        pass
+
+    def getLocalNamespace(self):
+        """Getter for cmis:localNamespace"""
+        pass
+
+    def getDisplayName(self):
+        """Getter for cmis:displayName"""
+        pass
+
+    def getQueryName(self):
+        """Getter for cmis:queryName"""
+        pass
+
+    def getDescription(self):
+        """Getter for cmis:description"""
+        pass
+
+    def getBaseId(self):
+        """Getter for cmis:baseId"""
+        pass
+
+    def isCreatable(self):
+        """Getter for cmis:creatable"""
+        pass
+
+    def isFileable(self):
+        """Getter for cmis:fileable"""
+        pass
+
+    def isQueryable(self):
+        """Getter for cmis:queryable"""
+        pass
+
+    def isFulltextIndexed(self):
+        """Getter for cmis:fulltextIndexed"""
+        pass
+
+    def isIncludedInSupertypeQuery(self):
+        """Getter for cmis:includedInSupertypeQuery"""
+        pass
+
+    def isControllablePolicy(self):
+        """Getter for cmis:controllablePolicy"""
+        pass
+
+    def isControllableACL(self):
+        """Getter for cmis:controllableACL"""
+        pass
+
+    def getLink(self, rel, linkType):
+
+        """
+        Gets the HREF for the link element with the specified rel and linkType.
+
+        >>> from cmislib.model import ATOM_XML_FEED_TYPE
+        >>> docType.getLink('down', ATOM_XML_FEED_TYPE)
+        u'http://localhost:8080/alfresco/s/cmis/type/cmis:document/children'
+        """
+
+        pass
+
+    def getProperties(self):
+
+        """
+        Returns a list of :class:`Property` objects representing each property
+        defined for this type.
+
+        >>> objType = repo.getTypeDefinition('cmis:relationship')
+        >>> for prop in objType.properties:
+        ...    print 'Id:%s' % prop.id
+        ...    print 'Cardinality:%s' % prop.cardinality
+        ...    print 'Description:%s' % prop.description
+        ...    print 'Display name:%s' % prop.displayName
+        ...    print 'Local name:%s' % prop.localName
+        ...    print 'Local namespace:%s' % prop.localNamespace
+        ...    print 'Property type:%s' % prop.propertyType
+        ...    print 'Query name:%s' % prop.queryName
+        ...    print 'Updatability:%s' % prop.updatability
+        ...    print 'Inherited:%s' % prop.inherited
+        ...    print 'Orderable:%s' % prop.orderable
+        ...    print 'Queryable:%s' % prop.queryable
+        ...    print 'Required:%s' % prop.required
+        ...    print 'Open choice:%s' % prop.openChoice
+        """
+
+        pass
+
+    def reload(self, **kwargs):
+        """
+        This method will reload the object's data from the CMIS service.
+        """
+        pass
+
+    id = property(getTypeId)
+    localName = property(getLocalName)
+    localNamespace = property(getLocalNamespace)
+    displayName = property(getDisplayName)
+    queryName = property(getQueryName)
+    description = property(getDescription)
+    baseId = property(getBaseId)
+    creatable = property(isCreatable)
+    fileable = property(isFileable)
+    queryable = property(isQueryable)
+    fulltextIndexed = property(isFulltextIndexed)
+    includedInSupertypeQuery = property(isIncludedInSupertypeQuery)
+    controllablePolicy = property(isControllablePolicy)
+    controllableACL = property(isControllableACL)
+    properties = property(getProperties)
+
+
+class Property(object):
+
+    """
+    This class represents an attribute or property definition of an object
+    type.
+    """
+
+    def getId(self):
+        """Getter for cmis:id"""
+        pass
+
+    def getLocalName(self):
+        """Getter for cmis:localName"""
+        pass
+
+    def getLocalNamespace(self):
+        """Getter for cmis:localNamespace"""
+        pass
+
+    def getDisplayName(self):
+        """Getter for cmis:displayName"""
+        pass
+
+    def getQueryName(self):
+        """Getter for cmis:queryName"""
+        pass
+
+    def getDescription(self):
+        """Getter for cmis:description"""
+        pass
+
+    def getPropertyType(self):
+        """Getter for cmis:propertyType"""
+        pass
+
+    def getCardinality(self):
+        """Getter for cmis:cardinality"""
+        pass
+
+    def getUpdatability(self):
+        """Getter for cmis:updatability"""
+        pass
+
+    def isInherited(self):
+        """Getter for cmis:inherited"""
+        pass
+
+    def isRequired(self):
+        """Getter for cmis:required"""
+        pass
+
+    def isQueryable(self):
+        """Getter for cmis:queryable"""
+        pass
+
+    def isOrderable(self):
+        """Getter for cmis:orderable"""
+        pass
+
+    def isOpenChoice(self):
+        """Getter for cmis:openChoice"""
+        pass
+
+    id = property(getId)
+    localName = property(getLocalName)
+    localNamespace = property(getLocalNamespace)
+    displayName = property(getDisplayName)
+    queryName = property(getQueryName)
+    description = property(getDescription)
+    propertyType = property(getPropertyType)
+    cardinality = property(getCardinality)
+    updatability = property(getUpdatability)
+    inherited = property(isInherited)
+    required = property(isRequired)
+    queryable = property(isQueryable)
+    orderable = property(isOrderable)
+    openChoice = property(isOpenChoice)
+
+
+class ACL(object):
+
+    """
+    Represents the Access Control List for an object.
+    """
+
+    def addEntry(self, ace):
+
+        """
+        Adds an :class:`ACE` entry to the ACL.
+
+        >>> acl = folder.getACL()
+        >>> acl.addEntry(ACE('jpotts', 'cmis:read', 'true'))
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
+        """
+
+        pass
+
+    def removeEntry(self, principalId):
+
+        """
+        Removes the :class:`ACE` entry given a specific principalId.
+
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
+        >>> acl.removeEntry('jsmith')
+        >>> acl.getEntries()
+        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>}
+        """
+
+        pass
+
+    def clearEntries(self):
+
+        """
+        Clears all :class:`ACE` entries from the ACL and removes the internal
+        XML representation of the ACL.
+
+        >>> acl = ACL()
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
+        >>> acl.entries
+        {'jpotts': <cmislib.model.ACE object at 0x1012c7310>, 'jsmith': <cmislib.model.ACE object at 0x100528490>}
+        >>> acl.getXmlDoc()
+        <xml.dom.minidom.Document instance at 0x1012cbb90>
+        >>> acl.clearEntries()
+        >>> acl.entries
+        >>> acl.getXmlDoc()
+        """
+
+        pass
+
+    def getEntries(self):
+
+        """
+        Returns a dictionary of :class:`ACE` objects for each Access Control
+        Entry in the ACL. The key value is the ACE principalid.
+
+        >>> acl = ACL()
+        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
+        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
+        >>> for ace in acl.entries.values():
+        ...     print 'principal:%s has the following permissions...' % ace.principalId
+        ...     for perm in ace.permissions:
+        ...             print perm
+        ...
+        principal:jpotts has the following permissions...
+        cmis:write
+        principal:jsmith has the following permissions...
+        cmis:write
+        """
+
+        pass
+
+    entries = property(getEntries)
+
+
+class ACE(object):
+
+    """
+    Represents an individual Access Control Entry.
+    """
+
+    @property
+    def principalId(self):
+        """Getter for principalId"""
+        pass
+
+    @property
+    def direct(self):
+        """Getter for direct"""
+        pass
+
+    @property
+    def permissions(self):
+        """Getter for permissions"""
+        pass
+
+
+class ChangeEntry(object):
+
+    """
+    Represents a change log entry. Retrieve a list of change entries via
+    :meth:`Repository.getContentChanges`.
+
+    >>> for changeEntry in rs:
+    ...     changeEntry.objectId
+    ...     changeEntry.id
+    ...     changeEntry.changeType
+    ...     changeEntry.changeTime
+    ...
+    'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
+    u'created'
+    datetime.datetime(2010, 2, 11, 12, 55, 14)
+    'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
+    u'updated'
+    datetime.datetime(2010, 2, 11, 12, 55, 13)
+    'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
+    u'updated'
+    """
+
+    def getId(self):
+        """
+        Returns the unique ID of the change entry.
+        """
+        pass
+
+    def getObjectId(self):
+        """
+        Returns the object ID of the object that changed.
+        """
+        pass
+
+    def getChangeType(self):
+
+        """
+        Returns the type of change that occurred. The resulting value must be
+        one of:
+
+         - created
+         - updated
+         - deleted
+         - security
+        """
+        pass
+
+    def getACL(self):
+
+        """
+        Gets the :class:`ACL` object that is included with this Change Entry.
+        """
+
+        pass
+
+    def getChangeTime(self):
+
+        """
+        Returns a datetime object representing the time the change occurred.
+        """
+
+        pass
+
+    def getProperties(self):
+
+        """
+        Returns the properties of the change entry. Note that depending on the
+        capabilities of the repository ("capabilityChanges") the list may not
+        include the actual property values that changed.
+        """
+
+        pass
+
+    id = property(getId)
+    objectId = property(getObjectId)
+    changeTime = property(getChangeTime)
+    changeType = property(getChangeType)
+    properties = property(getProperties)
+
+
+class ChangeEntryResultSet(ResultSet):
+
+    """
+    A specialized type of :class:`ResultSet` that knows how to instantiate
+    :class:`ChangeEntry` objects. The parent class assumes children of
+    :class:`CmisObject` which doesn't work for ChangeEntries.
+    """
+
+    def __iter__(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return iter(self.getResults())
+
+    def __getitem__(self, index):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return self.getResults()[index]
+
+    def __len__(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        return len(self.getResults())
+
+    def getResults(self):
+
+        """
+        Overriding to make it work with a list instead of a dict.
+        """
+
+        pass
+
+
+class Rendition(object):
+
+    """
+    This class represents a Rendition.
+    """
+
+    def __str__(self):
+        """To string"""
+        return self.getStreamId()
+
+    def getStreamId(self):
+        """Getter for the rendition's stream ID"""
+        pass
+
+    def getMimeType(self):
+        """Getter for the rendition's mime type"""
+        pass
+
+    def getLength(self):
+        """Getter for the renditions's length"""
+        pass
+
+    def getTitle(self):
+        """Getter for the renditions's title"""
+        pass
+
+    def getKind(self):
+        """Getter for the renditions's kind"""
+        pass
+
+    def getHeight(self):
+        """Getter for the renditions's height"""
+        pass
+
+    def getWidth(self):
+        """Getter for the renditions's width"""
+        pass
+
+    def getHref(self):
+        """Getter for the renditions's href"""
+        pass
+
+    def getRenditionDocumentId(self):
+        """Getter for the renditions's width"""
+        pass
+
+    streamId = property(getStreamId)
+    mimeType = property(getMimeType)
+    length = property(getLength)
+    title = property(getTitle)
+    kind = property(getKind)
+    height = property(getHeight)
+    width = property(getWidth)
+    href = property(getHref)
+    renditionDocumentId = property(getRenditionDocumentId)
+
+
+class CmisId(str):
+
+    """
+    This is a marker class to be used for Strings that are used as CMIS ID's.
+    Making the objects instances of this class makes it easier to create the
+    Atom entry XML with the appropriate type, ie, cmis:propertyId, instead of
+    cmis:propertyString.
+    """
+
+    pass
diff --git a/src/cmislib/model.py b/src/cmislib/model.py
index 562f2ea..cc86368 100644
--- a/src/cmislib/model.py
+++ b/src/cmislib/model.py
@@ -17,78 +17,17 @@
 #      under the License.
 #
 """
-Module containing the domain objects used to work with a CMIS provider.
+Module containing the CmisClient object, which is responsible for
+keeping track of connection information. The name 'model' is no longer
+really appropriate, but it is kept for backwards compatibility.
 """
-from net import RESTService as Rest
-from exceptions import CmisException, RuntimeException, \
-    ObjectNotFoundException, InvalidArgumentException, \
-    PermissionDeniedException, NotSupportedException, \
-    UpdateConflictException
-import messages
-
-from urllib import quote
-from urllib2 import HTTPError
-from urlparse import urlparse, urlunparse
-import re
-import mimetypes
-from xml.parsers.expat import ExpatError
-import datetime
-import time
-import iso8601
-import StringIO
+from atompub_binding import AtomPubBinding
+from cmis_services import Binding
+from domain import CmisObject, Repository
 import logging
 
-# would kind of like to not have any parsing logic in this module,
-# but for now I'm going to put the serial/deserialization in methods
-# of the CMIS object classes
-from xml.dom import minidom
-
-# Namespaces
-ATOM_NS = 'http://www.w3.org/2005/Atom'
-APP_NS = 'http://www.w3.org/2007/app'
-CMISRA_NS = 'http://docs.oasis-open.org/ns/cmis/restatom/200908/'
-CMIS_NS = 'http://docs.oasis-open.org/ns/cmis/core/200908/'
-
-# Content types
-# Not all of these patterns have variability, but some do. It seemed cleaner
-# just to treat them all like patterns to simplify the matching logic
-ATOM_XML_TYPE = 'application/atom+xml'
-ATOM_XML_ENTRY_TYPE = 'application/atom+xml;type=entry'
-ATOM_XML_ENTRY_TYPE_P = re.compile('^application/atom\+xml.*type.*entry')
-ATOM_XML_FEED_TYPE = 'application/atom+xml;type=feed'
-ATOM_XML_FEED_TYPE_P = re.compile('^application/atom\+xml.*type.*feed')
-CMIS_TREE_TYPE = 'application/cmistree+xml'
-CMIS_TREE_TYPE_P = re.compile('^application/cmistree\+xml')
-CMIS_QUERY_TYPE = 'application/cmisquery+xml'
-CMIS_ACL_TYPE = 'application/cmisacl+xml'
-
-# Standard rels
-DOWN_REL = 'down'
-FIRST_REL = 'first'
-LAST_REL = 'last'
-NEXT_REL = 'next'
-PREV_REL = 'prev'
-SELF_REL = 'self'
-UP_REL = 'up'
-TYPE_DESCENDANTS_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/typedescendants'
-VERSION_HISTORY_REL = 'version-history'
-FOLDER_TREE_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/foldertree'
-RELATIONSHIPS_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/relationships'
-ACL_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/acl'
-CHANGE_LOG_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/changes'
-POLICIES_REL = 'http://docs.oasis-open.org/ns/cmis/link/200908/policies'
-RENDITION_REL = 'alternate'
-
-# Collection types
-QUERY_COLL = 'query'
-TYPES_COLL = 'types'
-CHECKED_OUT_COLL = 'checkedout'
-UNFILED_COLL = 'unfiled'
-ROOT_COLL = 'root'
-
 moduleLogger = logging.getLogger('cmislib.model')
 
-
 class CmisClient(object):
 
     """
@@ -110,6 +49,10 @@
         self.username = username
         self.password = password
         self.extArgs = kwargs
+        if (kwargs.has_key('binding') and (isinstance(kwargs['binding'], Binding))):
+            self.binding = kwargs['binding']
+        else:
+            self.binding = AtomPubBinding(**kwargs)
         self.logger = logging.getLogger('cmislib.model.CmisClient')
         self.logger.info('Creating an instance of CmisClient')
 
@@ -128,21 +71,7 @@
         [{'repositoryName': u'Main Repository', 'repositoryId': u'83beb297-a6fa-4ac5-844b-98c871c0eea9'}]
         """
 
-        result = self.get(self.repositoryUrl, **self.extArgs)
-        if (type(result) == HTTPError):
-            raise RuntimeException()
-
-        workspaceElements = result.getElementsByTagNameNS(APP_NS, 'workspace')
-        # instantiate a Repository object using every workspace element
-        # in the service URL then ask the repository object for its ID
-        # and name, and return that back
-
-        repositories = []
-        for node in [e for e in workspaceElements if e.nodeType == e.ELEMENT_NODE]:
-            repository = Repository(self, node)
-            repositories.append({'repositoryId': repository.getRepositoryId(),
-                                 'repositoryName': repository.getRepositoryInfo()['repositoryName']})
-        return repositories
+        return self.binding.getRepositoryService().getRepositories(self)
 
     def getRepository(self, repositoryId):
 
@@ -153,16 +82,7 @@
         >>> repo.getRepositoryName()
         u'Main Repository'
         """
-
-        doc = self.get(self.repositoryUrl, **self.extArgs)
-        workspaceElements = doc.getElementsByTagNameNS(APP_NS, 'workspace')
-
-        for workspaceElement in workspaceElements:
-            idElement = workspaceElement.getElementsByTagNameNS(CMIS_NS, 'repositoryId')
-            if idElement[0].childNodes[0].data == repositoryId:
-                return Repository(self, workspaceElement)
-
-        raise ObjectNotFoundException(url=self.repositoryUrl)
+        return self.binding.getRepositoryService().getRepository(self, repositoryId)
 
     def getDefaultRepository(self):
 
@@ -176,133 +96,7 @@
         u'83beb297-a6fa-4ac5-844b-98c871c0eea9'
         """
 
-        doc = self.get(self.repositoryUrl, **self.extArgs)
-        workspaceElements = doc.getElementsByTagNameNS(APP_NS, 'workspace')
-        # instantiate a Repository object with the first workspace
-        # element we find
-        repository = Repository(self, [e for e in workspaceElements if e.nodeType == e.ELEMENT_NODE][0])
-        return repository
-
-    def get(self, url, **kwargs):
-
-        """
-        Does a get against the CMIS service. More than likely, you will not
-        need to call this method. Instead, let the other objects do it for you.
-
-        For example, if you need to get a specific object by object id, try
-        :class:`Repository.getObject`. If you have a path instead of an object
-        id, use :class:`Repository.getObjectByPath`. Or, you could start with
-        the root folder (:class:`Repository.getRootFolder`) and drill down from
-        there.
-        """
-
-        # merge the cmis client extended args with the ones that got passed in
-        if (len(self.extArgs) > 0):
-            kwargs.update(self.extArgs)
-
-        result = Rest().get(url,
-                            username=self.username,
-                            password=self.password,
-                            **kwargs)
-        if type(result) == HTTPError:
-            self._processCommonErrors(result)
-            return result
-        else:
-            try:
-                return minidom.parse(result)
-            except ExpatError:
-                raise CmisException('Could not parse server response', url)
-
-    def delete(self, url, **kwargs):
-
-        """
-        Does a delete against the CMIS service. More than likely, you will not
-        need to call this method. Instead, let the other objects do it for you.
-
-        For example, to delete a folder you'd call :class:`Folder.delete` and
-        to delete a document you'd call :class:`Document.delete`.
-        """
-
-        # merge the cmis client extended args with the ones that got passed in
-        if (len(self.extArgs) > 0):
-            kwargs.update(self.extArgs)
-
-        result = Rest().delete(url,
-                               username=self.username,
-                               password=self.password,
-                               **kwargs)
-        if type(result) == HTTPError:
-            self._processCommonErrors(result)
-            return result
-        else:
-            pass
-
-    def post(self, url, payload, contentType, **kwargs):
-
-        """
-        Does a post against the CMIS service. More than likely, you will not
-        need to call this method. Instead, let the other objects do it for you.
-
-        For example, to update the properties on an object, you'd call
-        :class:`CmisObject.updateProperties`. Or, to check in a document that's
-        been checked out, you'd call :class:`Document.checkin` on the PWC.
-        """
-
-        # merge the cmis client extended args with the ones that got passed in
-        if (len(self.extArgs) > 0):
-            kwargs.update(self.extArgs)
-
-        result = Rest().post(url,
-                             payload,
-                             contentType,
-                             username=self.username,
-                             password=self.password,
-                             **kwargs)
-        if type(result) != HTTPError:
-            try:
-                return minidom.parse(result)
-            except ExpatError:
-                raise CmisException('Could not parse server response', url)
-        elif result.code == 201:
-            try:
-                return minidom.parse(result)
-            except ExpatError:
-                raise CmisException('Could not parse server response', url)
-        else:
-            self._processCommonErrors(result)
-            return result
-
-    def put(self, url, payload, contentType, **kwargs):
-
-        """
-        Does a put against the CMIS service. More than likely, you will not
-        need to call this method. Instead, let the other objects do it for you.
-
-        For example, to update the properties on an object, you'd call
-        :class:`CmisObject.updateProperties`. Or, to check in a document that's
-        been checked out, you'd call :class:`Document.checkin` on the PWC.
-        """
-
-        # merge the cmis client extended args with the ones that got passed in
-        if (len(self.extArgs) > 0):
-            kwargs.update(self.extArgs)
-
-        result = Rest().put(url,
-                            payload,
-                            contentType,
-                            username=self.username,
-                            password=self.password,
-                            **kwargs)
-        if type(result) == HTTPError:
-            self._processCommonErrors(result)
-            return result
-        else:
-            #if result.headers['content-length'] != '0':
-            try:
-                return minidom.parse(result)
-            except ExpatError:
-                # This may happen and is normal
-                return None
+        return self.binding.getRepositoryService().getDefaultRepository(self)
 
     def _processCommonErrors(self, error):
 
@@ -329,3923 +123,3 @@
 
     defaultRepository = property(getDefaultRepository)
     repositories = property(getRepositories)
-
-
-class Repository(object):
-
-    """
-    Represents a CMIS repository. Will lazily populate itself by
-    calling the repository CMIS service URL.
-
-    You must pass in an instance of a CmisClient when creating an
-    instance of this class.
-    """
-
-    def __init__(self, cmisClient, xmlDoc=None):
-        """ Constructor """
-        self._cmisClient = cmisClient
-        self.xmlDoc = xmlDoc
-        self._repositoryId = None
-        self._repositoryName = None
-        self._repositoryInfo = {}
-        self._capabilities = {}
-        self._uriTemplates = {}
-        self._permDefs = {}
-        self._permMap = {}
-        self._permissions = None
-        self._propagation = None
-        self.logger = logging.getLogger('cmislib.model.Repository')
-        self.logger.info('Creating an instance of Repository')
-
-    def __str__(self):
-        """To string"""
-        return self.getRepositoryName()
-
-    def reload(self):
-        """
-        This method will re-fetch the repository's XML data from the CMIS
-        repository.
-        """
-        self.logger.debug('Reload called on object')
-        self.xmlDoc = self._cmisClient.get(self._cmisClient.repositoryUrl.encode('utf-8'))
-        self._initData()
-
-    def _initData(self):
-        """
-        This method clears out any local variables that would be out of sync
-        when data is re-fetched from the server.
-        """
-        self._repositoryId = None
-        self._repositoryName = None
-        self._repositoryInfo = {}
-        self._capabilities = {}
-        self._uriTemplates = {}
-        self._permDefs = {}
-        self._permMap = {}
-        self._permissions = None
-        self._propagation = None
-
-    def getSupportedPermissions(self):
-
-        """
-        Returns the value of the cmis:supportedPermissions element. Valid
-        values are:
-
-         - basic: indicates that the CMIS Basic permissions are supported
-         - repository: indicates that repository specific permissions are supported
-         - both: indicates that both CMIS basic permissions and repository specific permissions are supported
-
-        >>> repo.supportedPermissions
-        u'both'
-        """
-
-        if not self.getCapabilities()['ACL']:
-            raise NotSupportedException(messages.NO_ACL_SUPPORT)
-
-        if not self._permissions:
-            if self.xmlDoc == None:
-                self.reload()
-            suppEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'supportedPermissions')
-            assert len(suppEls) == 1, 'Expected the repository service document to have one element named supportedPermissions'
-            self._permissions = suppEls[0].childNodes[0].data
-
-        return self._permissions
-
-    def getPermissionDefinitions(self):
-
-        """
-        Returns a dictionary of permission definitions for this repository. The
-        key is the permission string or technical name of the permission
-        and the value is the permission description.
-
-        >>> for permDef in repo.permissionDefinitions:
-        ...     print permDef
-        ...
-        cmis:all
-        {http://www.alfresco.org/model/system/1.0}base.LinkChildren
-        {http://www.alfresco.org/model/content/1.0}folder.Consumer
-        {http://www.alfresco.org/model/security/1.0}All.All
-        {http://www.alfresco.org/model/system/1.0}base.CreateAssociations
-        {http://www.alfresco.org/model/system/1.0}base.FullControl
-        {http://www.alfresco.org/model/system/1.0}base.AddChildren
-        {http://www.alfresco.org/model/system/1.0}base.ReadAssociations
-        {http://www.alfresco.org/model/content/1.0}folder.Editor
-        {http://www.alfresco.org/model/content/1.0}cmobject.Editor
-        {http://www.alfresco.org/model/system/1.0}base.DeleteAssociations
-        cmis:read
-        cmis:write
-        """
-
-        if not self.getCapabilities()['ACL']:
-            raise NotSupportedException(messages.NO_ACL_SUPPORT)
-
-        if self._permDefs == {}:
-            if self.xmlDoc == None:
-                self.reload()
-            aclEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'aclCapability')
-            assert len(aclEls) == 1, 'Expected the repository service document to have one element named aclCapability'
-            aclEl = aclEls[0]
-            perms = {}
-            for e in aclEl.childNodes:
-                if e.localName == 'permissions':
-                    permEls = e.getElementsByTagNameNS(CMIS_NS, 'permission')
-                    assert len(permEls) == 1, 'Expected permissions element to have a child named permission'
-                    descEls = e.getElementsByTagNameNS(CMIS_NS, 'description')
-                    assert len(descEls) == 1, 'Expected permissions element to have a child named description'
-                    perm = permEls[0].childNodes[0].data
-                    desc = descEls[0].childNodes[0].data
-                    perms[perm] = desc
-            self._permDefs = perms
-
-        return self._permDefs
-
-    def getPermissionMap(self):
-
-        """
-        Returns a dictionary representing the permission mapping table where
-        each key is a permission key string and each value is a list of one or
-        more permissions the principal must have to perform the operation.
-
-        >>> for (k,v) in repo.permissionMap.items():
-        ...     print 'To do this: %s, you must have these perms:' % k
-        ...     for perm in v:
-        ...             print perm
-        ...
-        To do this: canCreateFolder.Folder, you must have these perms:
-        cmis:all
-        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
-        To do this: canAddToFolder.Folder, you must have these perms:
-        cmis:all
-        {http://www.alfresco.org/model/system/1.0}base.CreateChildren
-        To do this: canDelete.Object, you must have these perms:
-        cmis:all
-        {http://www.alfresco.org/model/system/1.0}base.DeleteNode
-        To do this: canCheckin.Document, you must have these perms:
-        cmis:all
-        {http://www.alfresco.org/model/content/1.0}lockable.CheckIn
-        """
-
-        if not self.getCapabilities()['ACL']:
-            raise NotSupportedException(messages.NO_ACL_SUPPORT)
-
-        if self._permMap == {}:
-            if self.xmlDoc == None:
-                self.reload()
-            aclEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'aclCapability')
-            assert len(aclEls) == 1, 'Expected the repository service document to have one element named aclCapability'
-            aclEl = aclEls[0]
-            permMap = {}
-            for e in aclEl.childNodes:
-                permList = []
-                if e.localName == 'mapping':
-                    keyEls = e.getElementsByTagNameNS(CMIS_NS, 'key')
-                    assert len(keyEls) == 1, 'Expected mapping element to have a child named key'
-                    permEls = e.getElementsByTagNameNS(CMIS_NS, 'permission')
-                    assert len(permEls) >= 1, 'Expected mapping element to have at least one permission element'
-                    key = keyEls[0].childNodes[0].data
-                    for permEl in permEls:
-                        permList.append(permEl.childNodes[0].data)
-                    permMap[key] = permList
-            self._permMap = permMap
-
-        return self._permMap
-
-    def getPropagation(self):
-
-        """
-        Returns the value of the cmis:propagation element. Valid values are:
-          - objectonly: indicates that the repository is able to apply ACEs
-            without changing the ACLs of other objects
-          - propagate: indicates that the repository is able to apply ACEs to a
-            given object and propagate this change to all inheriting objects
-
-        >>> repo.propagation
-        u'propagate'
-        """
-
-        if not self.getCapabilities()['ACL']:
-            raise NotSupportedException(messages.NO_ACL_SUPPORT)
-
-        if not self._propagation:
-            if self.xmlDoc == None:
-                self.reload()
-            propEls = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'propagation')
-            assert len(propEls) == 1, 'Expected the repository service document to have one element named propagation'
-            self._propagation = propEls[0].childNodes[0].data
-
-        return self._propagation
-
-    def getRepositoryId(self):
-
-        """
-        Returns this repository's unique identifier
-
-        >>> repo = client.getDefaultRepository()
-        >>> repo.getRepositoryId()
-        u'83beb297-a6fa-4ac5-844b-98c871c0eea9'
-        """
-
-        if self._repositoryId == None:
-            if self.xmlDoc == None:
-                self.reload()
-            self._repositoryId = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'repositoryId')[0].firstChild.data
-        return self._repositoryId
-
-    def getRepositoryName(self):
-
-        """
-        Returns this repository's name
-
-        >>> repo = client.getDefaultRepository()
-        >>> repo.getRepositoryName()
-        u'Main Repository'
-        """
-
-        if self._repositoryName == None:
-            if self.xmlDoc == None:
-                self.reload()
-            self._repositoryName = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'repositoryName')[0].firstChild.data
-        return self._repositoryName
-
-    def getRepositoryInfo(self):
-
-        """
-        Returns a dict of repository information.
-
-        >>> repo = client.getDefaultRepository()>>> repo.getRepositoryName()
-        u'Main Repository'
-        >>> info = repo.getRepositoryInfo()
-        >>> for k,v in info.items():
-        ...     print "%s:%s" % (k,v)
-        ...
-        cmisSpecificationTitle:Version 1.0 Committee Draft 04
-        cmisVersionSupported:1.0
-        repositoryDescription:None
-        productVersion:3.2.0 (r2 2440)
-        rootFolderId:workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348
-        repositoryId:83beb297-a6fa-4ac5-844b-98c871c0eea9
-        repositoryName:Main Repository
-        vendorName:Alfresco
-        productName:Alfresco Repository (Community)
-        """
-
-        if not self._repositoryInfo:
-            if self.xmlDoc == None:
-                self.reload()
-            repoInfoElement = self.xmlDoc.getElementsByTagNameNS(CMISRA_NS, 'repositoryInfo')[0]
-            for node in repoInfoElement.childNodes:
-                if node.nodeType == node.ELEMENT_NODE and node.localName != 'capabilities':
-                    try:
-                        data = node.childNodes[0].data
-                    except:
-                        data = None
-                    self._repositoryInfo[node.localName] = data
-        return self._repositoryInfo
-
-    def getCapabilities(self):
-
-        """
-        Returns a dict of repository capabilities.
-
-        >>> caps = repo.getCapabilities()
-        >>> for k,v in caps.items():
-        ...     print "%s:%s" % (k,v)
-        ...
-        PWCUpdatable:True
-        VersionSpecificFiling:False
-        Join:None
-        ContentStreamUpdatability:anytime
-        AllVersionsSearchable:False
-        Renditions:None
-        Multifiling:True
-        GetFolderTree:True
-        GetDescendants:True
-        ACL:None
-        PWCSearchable:True
-        Query:bothcombined
-        Unfiling:False
-        Changes:None
-        """
-
-        if not self._capabilities:
-            if self.xmlDoc == None:
-                self.reload()
-            capabilitiesElement = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'capabilities')[0]
-            for node in [e for e in capabilitiesElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
-                key = node.localName.replace('capability', '')
-                value = parseBoolValue(node.childNodes[0].data)
-                self._capabilities[key] = value
-        return self._capabilities
-
-    def getRootFolder(self):
-        """
-        Returns the root folder of the repository
-
-        >>> root = repo.getRootFolder()
-        >>> root.getObjectId()
-        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
-        """
-        # get the root folder id
-        rootFolderId = self.getRepositoryInfo()['rootFolderId']
-        # instantiate a Folder object using the ID
-        folder = Folder(self._cmisClient, self, rootFolderId)
-        # return it
-        return folder
-
-    def getFolder(self, folderId):
-
-        """
-        Returns a :class:`Folder` object for a specified folderId
-
-        >>> someFolder = repo.getFolder('workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348')
-        >>> someFolder.getObjectId()
-        u'workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348'
-        """
-
-        retObject = self.getObject(folderId)
-        return Folder(self._cmisClient, self, xmlDoc=retObject.xmlDoc)
-
-    def getTypeChildren(self,
-                        typeId=None):
-
-        """
-        Returns a list of :class:`ObjectType` objects corresponding to the
-        child types of the type specified by the typeId.
-
-        If no typeId is provided, the result will be the same as calling
-        `self.getTypeDefinitions`
-
-        These optional arguments are current unsupported:
-         - includePropertyDefinitions
-         - maxItems
-         - skipCount
-
-        >>> baseTypes = repo.getTypeChildren()
-        >>> for baseType in baseTypes:
-        ...     print baseType.getTypeId()
-        ...
-        cmis:folder
-        cmis:relationship
-        cmis:document
-        cmis:policy
-        """
-
-        # Unfortunately, the spec does not appear to present a way to
-        # know how to get the children of a specific type without first
-        # retrieving the type, then asking it for one of its navigational
-        # links.
-
-        # if a typeId is specified, get it, then get its "down" link
-        if typeId:
-            targetType = self.getTypeDefinition(typeId)
-            childrenUrl = targetType.getLink(DOWN_REL, ATOM_XML_FEED_TYPE_P)
-            typesXmlDoc = self._cmisClient.get(childrenUrl.encode('utf-8'))
-            entryElements = typesXmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
-            types = []
-            for entryElement in entryElements:
-                objectType = ObjectType(self._cmisClient,
-                                        self,
-                                        xmlDoc=entryElement)
-                types.append(objectType)
-        # otherwise, if a typeId is not specified, return
-        # the list of base types
-        else:
-            types = self.getTypeDefinitions()
-        return types
-
-    def getTypeDescendants(self, typeId=None, **kwargs):
-
-        """
-        Returns a list of :class:`ObjectType` objects corresponding to the
-        descendant types of the type specified by the typeId.
-
-        If no typeId is provided, the repository's "typesdescendants" URL
-        will be called to determine the list of descendant types.
-
-        >>> allTypes = repo.getTypeDescendants()
-        >>> for aType in allTypes:
-        ...     print aType.getTypeId()
-        ...
-        cmis:folder
-        F:cm:systemfolder
-        F:act:savedactionfolder
-        F:app:configurations
-        F:fm:forums
-        F:wcm:avmfolder
-        F:wcm:avmplainfolder
-        F:wca:webfolder
-        F:wcm:avmlayeredfolder
-        F:st:site
-        F:app:glossary
-        F:fm:topic
-
-        These optional arguments are supported:
-         - depth
-         - includePropertyDefinitions
-
-        >>> types = alfRepo.getTypeDescendants('cmis:folder')
-        >>> len(types)
-        17
-        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=1)
-        >>> len(types)
-        12
-        >>> types = alfRepo.getTypeDescendants('cmis:folder', depth=2)
-        >>> len(types)
-        17
-        """
-
-        # Unfortunately, the spec does not appear to present a way to
-        # know how to get the children of a specific type without first
-        # retrieving the type, then asking it for one of its navigational
-        # links.
-        if typeId:
-            targetType = self.getTypeDefinition(typeId)
-            descendUrl = targetType.getLink(DOWN_REL, CMIS_TREE_TYPE_P)
-
-        else:
-            descendUrl = self.getLink(TYPE_DESCENDANTS_REL)
-
-        if not descendUrl:
-            raise NotSupportedException("Could not determine the type descendants URL")
-
-        typesXmlDoc = self._cmisClient.get(descendUrl.encode('utf-8'), **kwargs)
-        entryElements = typesXmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
-        types = []
-        for entryElement in entryElements:
-            objectType = ObjectType(self._cmisClient,
-                                    self,
-                                    xmlDoc=entryElement)
-            types.append(objectType)
-        return types
-
-    def getTypeDefinitions(self, **kwargs):
-
-        """
-        Returns a list of :class:`ObjectType` objects representing
-        the base types in the repository.
-
-        >>> baseTypes = repo.getTypeDefinitions()
-        >>> for baseType in baseTypes:
-        ...     print baseType.getTypeId()
-        ...
-        cmis:folder
-        cmis:relationship
-        cmis:document
-        cmis:policy
-        """
-
-        typesUrl = self.getCollectionLink(TYPES_COLL)
-        typesXmlDoc = self._cmisClient.get(typesUrl, **kwargs)
-        entryElements = typesXmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
-        types = []
-        for entryElement in entryElements:
-            objectType = ObjectType(self._cmisClient,
-                                    self,
-                                    xmlDoc=entryElement)
-            types.append(objectType)
-        # return the result
-        return types
-
-    def getTypeDefinition(self, typeId):
-
-        """
-        Returns an :class:`ObjectType` object for the specified object type id.
-
-        >>> folderType = repo.getTypeDefinition('cmis:folder')
-        """
-
-        objectType = ObjectType(self._cmisClient, self, typeId)
-        objectType.reload()
-        return objectType
-
-    def getLink(self, rel):
-        """
-        Returns the HREF attribute of an Atom link element for the
-        specified rel.
-        """
-        if self.xmlDoc == None:
-            self.reload()
-
-        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        for linkElement in linkElements:
-
-            if linkElement.attributes.has_key('rel'):
-                relAttr = linkElement.attributes['rel'].value
-
-                if relAttr == rel:
-                    return linkElement.attributes['href'].value
-
-    def getCheckedOutDocs(self, **kwargs):
-
-        """
-        Returns a ResultSet of :class:`CmisObject` objects that
-        are currently checked out.
-
-        >>> rs = repo.getCheckedOutDocs()
-        >>> len(rs.getResults())
-        2
-        >>> for doc in repo.getCheckedOutDocs().getResults():
-        ...     doc.getTitle()
-        ...
-        u'sample-a (Working Copy).pdf'
-        u'sample-b (Working Copy).pdf'
-
-        These optional arguments are supported:
-         - folderId
-         - maxItems
-         - skipCount
-         - orderBy
-         - filter
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-        """
-
-        return self.getCollection(CHECKED_OUT_COLL, **kwargs)
-
-    def getUnfiledDocs(self, **kwargs):
-
-        """
-        Returns a ResultSet of :class:`CmisObject` objects that
-        are currently unfiled.
-
-        >>> rs = repo.getUnfiledDocs()
-        >>> len(rs.getResults())
-        2
-        >>> for doc in repo.getUnfiledDocs().getResults():
-        ...     doc.getTitle()
-        ...
-        u'sample-a.pdf'
-        u'sample-b.pdf'
-
-        These optional arguments are supported:
-         - folderId
-         - maxItems
-         - skipCount
-         - orderBy
-         - filter
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-        """
-
-        return self.getCollection(UNFILED_COLL, **kwargs)
-
-    def getObject(self,
-                  objectId,
-                  **kwargs):
-
-        """
-        Returns an object given the specified object ID.
-
-        >>> doc = repo.getObject('workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808')
-        >>> doc.getTitle()
-        u'sample-b.pdf'
-
-        The following optional arguments are supported:
-         - returnVersion
-         - filter
-         - includeRelationships
-         - includePolicyIds
-         - renditionFilter
-         - includeACL
-         - includeAllowableActions
-        """
-
-        return getSpecializedObject(CmisObject(self._cmisClient, self, objectId, **kwargs), **kwargs)
-
-    def getObjectByPath(self, path, **kwargs):
-
-        """
-        Returns an object given the path to the object.
-
-        >>> doc = repo.getObjectByPath('/jeff test/sample-b.pdf')
-        >>> doc.getTitle()
-        u'sample-b.pdf'
-
-        The following optional arguments are not currently supported:
-         - filter
-         - includeAllowableActions
-        """
-
-        # get the uritemplate
-        template = self.getUriTemplates()['objectbypath']['template']
-
-        # fill in the template with the path provided
-        params = {
-              '{path}': quote(path, '/'),
-              '{filter}': '',
-              '{includeAllowableActions}': 'false',
-              '{includePolicyIds}': 'false',
-              '{includeRelationships}': '',
-              '{includeACL}': 'false',
-              '{renditionFilter}': ''}
-
-        options = {}
-        addOptions = {}  # args specified, but not in the template
-        for k, v in kwargs.items():
-            pKey = "{" + k + "}"
-            if template.find(pKey) >= 0:
-                options[pKey] = toCMISValue(v)
-            else:
-                addOptions[k] = toCMISValue(v)
-
-        # merge the templated args with the default params
-        params.update(options)
-
-        byObjectPathUrl = multiple_replace(params, template)
-
-        # do a GET against the URL
-        result = self._cmisClient.get(byObjectPathUrl.encode('utf-8'), **addOptions)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # instantiate CmisObject objects with the results and return the list
-        entryElements = result.getElementsByTagNameNS(ATOM_NS, 'entry')
-        assert(len(entryElements) == 1), "Expected entry element in result from calling %s" % byObjectPathUrl
-        return getSpecializedObject(CmisObject(self._cmisClient, self, xmlDoc=entryElements[0], **kwargs), **kwargs)
-
-    def query(self, statement, **kwargs):
-
-        """
-        Returns a list of :class:`CmisObject` objects based on the CMIS
-        Query Language passed in as the statement. The actual objects
-        returned will be instances of the appropriate child class based
-        on the object's base type ID.
-
-        In order for the results to be properly instantiated as objects,
-        make sure you include 'cmis:objectId' as one of the fields in
-        your select statement, or just use "SELECT \*".
-
-        If you want the search results to automatically be instantiated with
-        the appropriate sub-class of :class:`CmisObject` you must either
-        include cmis:baseTypeId as one of the fields in your select statement
-        or just use "SELECT \*".
-
-        >>> q = "select * from cmis:document where cmis:name like '%test%'"
-        >>> resultSet = repo.query(q)
-        >>> len(resultSet.getResults())
-        1
-        >>> resultSet.hasNext()
-        False
-
-        The following optional arguments are supported:
-         - searchAllVersions
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-         - maxItems
-         - skipCount
-
-        >>> q = 'select * from cmis:document'
-        >>> rs = repo.query(q)
-        >>> len(rs.getResults())
-        148
-        >>> rs = repo.query(q, maxItems='5')
-        >>> len(rs.getResults())
-        5
-        >>> rs.hasNext()
-        True
-        """
-
-        if self.xmlDoc == None:
-            self.reload()
-
-        # get the URL this repository uses to accept query POSTs
-        queryUrl = self.getCollectionLink(QUERY_COLL)
-
-        # build the CMIS query XML that we're going to POST
-        xmlDoc = self._getQueryXmlDoc(statement, **kwargs)
-
-        # do the POST
-        #print 'posting:%s' % xmlDoc.toxml(encoding='utf-8')
-        result = self._cmisClient.post(queryUrl.encode('utf-8'),
-                                       xmlDoc.toxml(encoding='utf-8'),
-                                       CMIS_QUERY_TYPE)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self, result)
-
-    def getContentChanges(self, **kwargs):
-
-        """
-        Returns a :class:`ResultSet` containing :class:`ChangeEntry` objects.
-
-        >>> for changeEntry in rs:
-        ...     changeEntry.objectId
-        ...     changeEntry.id
-        ...     changeEntry.changeType
-        ...     changeEntry.changeTime
-        ...
-        'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
-        u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
-        u'created'
-        datetime.datetime(2010, 2, 11, 12, 55, 14)
-        'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
-        u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
-        u'updated'
-        datetime.datetime(2010, 2, 11, 12, 55, 13)
-        'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
-        u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
-        u'updated'
-
-        The following optional arguments are supported:
-         - changeLogToken
-         - includeProperties
-         - includePolicyIDs
-         - includeACL
-         - maxItems
-
-        You can get the latest change log token by inspecting the repository
-        info via :meth:`Repository.getRepositoryInfo`.
-
-        >>> repo.info['latestChangeLogToken']
-        u'2692'
-        >>> rs = repo.getContentChanges(changeLogToken='2692')
-        >>> len(rs)
-        1
-        >>> rs[0].id
-        u'urn:uuid:8e88f694-93ef-44c5-9f70-f12fff824be9'
-        >>> rs[0].changeType
-        u'updated'
-        >>> rs[0].changeTime
-        datetime.datetime(2010, 2, 16, 20, 6, 37)
-        """
-
-        if self.getCapabilities()['Changes'] == None:
-            raise NotSupportedException(messages.NO_CHANGE_LOG_SUPPORT)
-
-        changesUrl = self.getLink(CHANGE_LOG_REL)
-        result = self._cmisClient.get(changesUrl.encode('utf-8'), **kwargs)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ChangeEntryResultSet(self._cmisClient, self, result)
-
-    def createDocumentFromString(self,
-                                 name,
-                                 properties={},
-                                 parentFolder=None,
-                                 contentString=None,
-                                 contentType=None,
-                                 contentEncoding=None):
-
-        """
-        Creates a new document setting the content to the string provided. If
-        the repository supports unfiled objects, you do not have to pass in
-        a parent :class:`Folder` otherwise it is required.
-
-        This method is essentially a convenience method that wraps your string
-        with a StringIO and then calls createDocument.
-
-        >>> repo.createDocumentFromString('testdoc5', parentFolder=testFolder, contentString='Hello, World!', contentType='text/plain')
-        <cmislib.model.Document object at 0x101352ed0>
-        """
-
-        # if you didn't pass in a parent folder
-        if parentFolder == None:
-            # if the repository doesn't require fileable objects to be filed
-            if self.getCapabilities()['Unfiling']:
-                # has not been implemented
-                #postUrl = self.getCollectionLink(UNFILED_COLL)
-                raise NotImplementedError
-            else:
-                # this repo requires fileable objects to be filed
-                raise InvalidArgumentException
-
-        return parentFolder.createDocument(name, properties, StringIO.StringIO(contentString),
-            contentType, contentEncoding)
-
-    def createDocument(self,
-                       name,
-                       properties={},
-                       parentFolder=None,
-                       contentFile=None,
-                       contentType=None,
-                       contentEncoding=None):
-
-        """
-        Creates a new :class:`Document` object. If the repository
-        supports unfiled objects, you do not have to pass in
-        a parent :class:`Folder` otherwise it is required.
-
-        To create a document with an associated contentFile, pass in a
-        File object. The method will attempt to guess the appropriate content
-        type and encoding based on the file. To specify it yourself, pass them
-        in via the contentType and contentEncoding arguments.
-
-        >>> f = open('sample-a.pdf', 'rb')
-        >>> doc = folder.createDocument('sample-a.pdf', contentFile=f)
-        <cmislib.model.Document object at 0x105be5e10>
-        >>> f.close()
-        >>> doc.getTitle()
-        u'sample-a.pdf'
-
-        The following optional arguments are not currently supported:
-         - versioningState
-         - policies
-         - addACEs
-         - removeACEs
-        """
-
-        postUrl = ''
-        # if you didn't pass in a parent folder
-        if parentFolder == None:
-            # if the repository doesn't require fileable objects to be filed
-            if self.getCapabilities()['Unfiling']:
-                # has not been implemented
-                #postUrl = self.getCollectionLink(UNFILED_COLL)
-                raise NotImplementedError
-            else:
-                # this repo requires fileable objects to be filed
-                raise InvalidArgumentException
-        else:
-            postUrl = parentFolder.getChildrenLink()
-
-        # make sure a name is set
-        properties['cmis:name'] = name
-
-        # hardcoding to cmis:document if it wasn't
-        # passed in via props
-        if not properties.has_key('cmis:objectTypeId'):
-            properties['cmis:objectTypeId'] = CmisId('cmis:document')
-        # and if it was passed in, making sure it is a CmisId
-        elif not isinstance(properties['cmis:objectTypeId'], CmisId):
-            properties['cmis:objectTypeId'] = CmisId(properties['cmis:objectTypeId'])
-
-        # build the Atom entry
-        xmlDoc = getEntryXmlDoc(self, None, properties, contentFile,
-                                contentType, contentEncoding)
-
-        # post the Atom entry
-        result = self._cmisClient.post(postUrl.encode('utf-8'), xmlDoc.toxml(encoding='utf-8'), ATOM_XML_ENTRY_TYPE)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # what comes back is the XML for the new document,
-        # so use it to instantiate a new document
-        # then return it
-        return Document(self._cmisClient, self, xmlDoc=result)
-
-    def createDocumentFromSource(self,
-                                 sourceId,
-                                 properties={},
-                                 parentFolder=None):
-        """
-        This is not yet implemented.
-
-        The following optional arguments are not yet supported:
-         - versioningState
-         - policies
-         - addACEs
-         - removeACEs
-        """
-        # TODO: To be implemented
-        raise NotImplementedError
-
-    def createFolder(self,
-                     parentFolder,
-                     name,
-                     properties={}):
-
-        """
-        Creates a new :class:`Folder` object in the specified parentFolder.
-
-        >>> root = repo.getRootFolder()
-        >>> folder = repo.createFolder(root, 'someFolder2')
-        >>> folder.getTitle()
-        u'someFolder2'
-        >>> folder.getObjectId()
-        u'workspace://SpacesStore/2224a63c-350b-438c-be72-8f425e79ce1f'
-
-        The following optional arguments are not yet supported:
-         - policies
-         - addACEs
-         - removeACEs
-        """
-
-        return parentFolder.createFolder(name, properties)
-
-    def createRelationship(self, sourceObj, targetObj, relType):
-        """
-        Creates a relationship of the specific type between a source object
-        and a target object and returns the new :class:`Relationship` object.
-
-        The following optional arguments are not currently supported:
-         - policies
-         - addACEs
-         - removeACEs
-        """
-        return sourceObj.createRelationship(targetObj, relType)
-
-    def createPolicy(self, properties):
-        """
-        This has not yet been implemented.
-
-        The following optional arguments are not currently supported:
-         - folderId
-         - policies
-         - addACEs
-         - removeACEs
-        """
-        # TODO: To be implemented
-        raise NotImplementedError
-
-    def getUriTemplates(self):
-
-        """
-        Returns a list of the URI templates the repository service knows about.
-
-        >>> templates = repo.getUriTemplates()
-        >>> templates['typebyid']['mediaType']
-        u'application/atom+xml;type=entry'
-        >>> templates['typebyid']['template']
-        u'http://localhost:8080/alfresco/s/cmis/type/{id}'
-        """
-
-        if self._uriTemplates == {}:
-
-            if self.xmlDoc == None:
-                self.reload()
-
-            uriTemplateElements = self.xmlDoc.getElementsByTagNameNS(CMISRA_NS, 'uritemplate')
-
-            for uriTemplateElement in uriTemplateElements:
-                template = None
-                templType = None
-                mediatype = None
-
-                for node in [e for e in uriTemplateElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
-                    if node.localName == 'template':
-                        template = node.childNodes[0].data
-                    elif node.localName == 'type':
-                        templType = node.childNodes[0].data
-                    elif node.localName == 'mediatype':
-                        mediatype = node.childNodes[0].data
-
-                self._uriTemplates[templType] = UriTemplate(template,
-                                                       templType,
-                                                       mediatype)
-
-        return self._uriTemplates
-
-    def getCollection(self, collectionType, **kwargs):
-
-        """
-        Returns a list of objects returned for the specified collection.
-
-        If the query collection is requested, an exception will be raised.
-        That collection isn't meant to be retrieved.
-
-        If the types collection is specified, the method returns the result of
-        `getTypeDefinitions` and ignores any optional params passed in.
-
-        >>> from cmislib.model import TYPES_COLL
-        >>> types = repo.getCollection(TYPES_COLL)
-        >>> len(types)
-        4
-        >>> types[0].getTypeId()
-        u'cmis:folder'
-
-        Otherwise, the collection URL is invoked, and a :class:`ResultSet` is
-        returned.
-
-        >>> from cmislib.model import CHECKED_OUT_COLL
-        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
-        >>> len(resultSet.getResults())
-        1
-        """
-
-        if collectionType == QUERY_COLL:
-            raise NotSupportedException
-        elif collectionType == TYPES_COLL:
-            return self.getTypeDefinitions()
-
-        result = self._cmisClient.get(self.getCollectionLink(collectionType).encode('utf-8'), **kwargs)
-        if (type(result) == HTTPError):
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self, result)
-
-    def getCollectionLink(self, collectionType):
-
-        """
-        Returns the link HREF from the specified collectionType
-        ('checkedout', for example).
-
-        >>> from cmislib.model import CHECKED_OUT_COLL
-        >>> repo.getCollectionLink(CHECKED_OUT_COLL)
-        u'http://localhost:8080/alfresco/s/cmis/checkedout'
-
-        """
-
-        collectionElements = self.xmlDoc.getElementsByTagNameNS(APP_NS, 'collection')
-        for collectionElement in collectionElements:
-            link = collectionElement.attributes['href'].value
-            for node in [e for e in collectionElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
-                if node.localName == 'collectionType':
-                    if node.childNodes[0].data == collectionType:
-                        return link
-
-    def _getQueryXmlDoc(self, query, **kwargs):
-
-        """
-        Utility method that knows how to build CMIS query xml around the
-        specified query statement.
-        """
-
-        cmisXmlDoc = minidom.Document()
-        queryElement = cmisXmlDoc.createElementNS(CMIS_NS, "query")
-        queryElement.setAttribute('xmlns', CMIS_NS)
-        cmisXmlDoc.appendChild(queryElement)
-
-        statementElement = cmisXmlDoc.createElementNS(CMIS_NS, "statement")
-        cdataSection = cmisXmlDoc.createCDATASection(query)
-        statementElement.appendChild(cdataSection)
-        queryElement.appendChild(statementElement)
-
-        for (k, v) in kwargs.items():
-            optionElement = cmisXmlDoc.createElementNS(CMIS_NS, k)
-            optionText = cmisXmlDoc.createTextNode(v)
-            optionElement.appendChild(optionText)
-            queryElement.appendChild(optionElement)
-
-        return cmisXmlDoc
-
-    capabilities = property(getCapabilities)
-    id = property(getRepositoryId)
-    info = property(getRepositoryInfo)
-    name = property(getRepositoryName)
-    rootFolder = property(getRootFolder)
-    permissionDefinitions = property(getPermissionDefinitions)
-    permissionMap = property(getPermissionMap)
-    propagation = property(getPropagation)
-    supportedPermissions = property(getSupportedPermissions)
-
-
-class ResultSet(object):
-
-    """
-    Represents a paged result set. In CMIS, this is most often an Atom feed.
-    """
-
-    def __init__(self, cmisClient, repository, xmlDoc):
-        ''' Constructor '''
-        self._cmisClient = cmisClient
-        self._repository = repository
-        self._xmlDoc = xmlDoc
-        self._results = []
-        self.logger = logging.getLogger('cmislib.model.ResultSet')
-        self.logger.info('Creating an instance of ResultSet')
-
-    def __iter__(self):
-        ''' Iterator for the result set '''
-        return iter(self.getResults())
-
-    def __getitem__(self, index):
-        ''' Getter for the result set '''
-        return self.getResults()[index]
-
-    def __len__(self):
-        ''' Len method for the result set '''
-        return len(self.getResults())
-
-    def _getLink(self, rel):
-        '''
-        Returns the link found in the feed's XML for the specified rel.
-        '''
-        linkElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        for linkElement in linkElements:
-
-            if linkElement.attributes.has_key('rel'):
-                relAttr = linkElement.attributes['rel'].value
-
-                if relAttr == rel:
-                    return linkElement.attributes['href'].value
-
-    def _getPageResults(self, rel):
-        '''
-        Given a specified rel, does a get using that link (if one exists)
-        and then converts the resulting XML into a dictionary of
-        :class:`CmisObject` objects or its appropriate sub-type.
-
-        The results are kept around to facilitate repeated calls without moving
-        the cursor.
-        '''
-        link = self._getLink(rel)
-        if link:
-            result = self._cmisClient.get(link.encode('utf-8'))
-            if (type(result) == HTTPError):
-                raise CmisException(result.code)
-
-            # return the result
-            self._xmlDoc = result
-            self._results = []
-            return self.getResults()
-
-    def reload(self):
-
-        '''
-        Re-invokes the self link for the current set of results.
-
-        >>> resultSet = repo.getCollection(CHECKED_OUT_COLL)
-        >>> resultSet.reload()
-
-        '''
-
-        self.logger.debug('Reload called on result set')
-        self._getPageResults(SELF_REL)
-
-    def getResults(self):
-
-        '''
-        Returns the results that were fetched and cached by the get*Page call.
-
-        >>> resultSet = repo.getCheckedOutDocs()
-        >>> resultSet.hasNext()
-        False
-        >>> for result in resultSet.getResults():
-        ...     result
-        ...
-        <cmislib.model.Document object at 0x104851810>
-        '''
-        if self._results:
-            return self._results
-
-        if self._xmlDoc:
-            entryElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
-            entries = []
-            for entryElement in entryElements:
-                cmisObject = getSpecializedObject(CmisObject(self._cmisClient,
-                                                             self._repository,
-                                                             xmlDoc=entryElement))
-                entries.append(cmisObject)
-
-            self._results = entries
-
-        return self._results
-
-    def hasObject(self, objectId):
-
-        '''
-        Returns True if the specified objectId is found in the list of results,
-        otherwise returns False.
-        '''
-
-        for obj in self.getResults():
-            if obj.id == objectId:
-                return True
-        return False
-
-    def getFirst(self):
-
-        '''
-        Returns the first page of results as a dictionary of
-        :class:`CmisObject` objects or its appropriate sub-type. This only
-        works when the server returns a "first" link. Not all of them do.
-
-        >>> resultSet.hasFirst()
-        True
-        >>> results = resultSet.getFirst()
-        >>> for result in results:
-        ...     result
-        ...
-        <cmislib.model.Document object at 0x10480bc90>
-        '''
-
-        return self._getPageResults(FIRST_REL)
-
-    def getPrev(self):
-
-        '''
-        Returns the prev page of results as a dictionary of
-        :class:`CmisObject` objects or its appropriate sub-type. This only
-        works when the server returns a "prev" link. Not all of them do.
-        >>> resultSet.hasPrev()
-        True
-        >>> results = resultSet.getPrev()
-        >>> for result in results:
-        ...     result
-        ...
-        <cmislib.model.Document object at 0x10480bc90>
-        '''
-
-        return self._getPageResults(PREV_REL)
-
-    def getNext(self):
-
-        '''
-        Returns the next page of results as a dictionary of
-        :class:`CmisObject` objects or its appropriate sub-type.
-        >>> resultSet.hasNext()
-        True
-        >>> results = resultSet.getNext()
-        >>> for result in results:
-        ...     result
-        ...
-        <cmislib.model.Document object at 0x10480bc90>
-        '''
-
-        return self._getPageResults(NEXT_REL)
-
-    def getLast(self):
-
-        '''
-        Returns the last page of results as a dictionary of
-        :class:`CmisObject` objects or its appropriate sub-type. This only
-        works when the server is returning a "last" link. Not all of them do.
-
-        >>> resultSet.hasLast()
-        True
-        >>> results = resultSet.getLast()
-        >>> for result in results:
-        ...     result
-        ...
-        <cmislib.model.Document object at 0x10480bc90>
-        '''
-
-        return self._getPageResults(LAST_REL)
-
-    def hasNext(self):
-
-        '''
-        Returns True if this page contains a next link.
-
-        >>> resultSet.hasNext()
-        True
-        '''
-
-        if self._getLink(NEXT_REL):
-            return True
-        else:
-            return False
-
-    def hasPrev(self):
-
-        '''
-        Returns True if this page contains a prev link. Not all CMIS providers
-        implement prev links consistently.
-
-        >>> resultSet.hasPrev()
-        True
-        '''
-
-        if self._getLink(PREV_REL):
-            return True
-        else:
-            return False
-
-    def hasFirst(self):
-
-        '''
-        Returns True if this page contains a first link. Not all CMIS providers
-        implement first links consistently.
-
-        >>> resultSet.hasFirst()
-        True
-        '''
-
-        if self._getLink(FIRST_REL):
-            return True
-        else:
-            return False
-
-    def hasLast(self):
-
-        '''
-        Returns True if this page contains a last link. Not all CMIS providers
-        implement last links consistently.
-
-        >>> resultSet.hasLast()
-        True
-        '''
-
-        if self._getLink(LAST_REL):
-            return True
-        else:
-            return False
-
-
-class CmisObject(object):
-
-    """
-    Common ancestor class for other CMIS domain objects such as
-    :class:`Document` and :class:`Folder`.
-    """
-
-    def __init__(self, cmisClient, repository, objectId=None, xmlDoc=None, **kwargs):
-        """ Constructor """
-        self._cmisClient = cmisClient
-        self._repository = repository
-        self._objectId = objectId
-        self._name = None
-        self._properties = {}
-        self._allowableActions = {}
-        self.xmlDoc = xmlDoc
-        self._kwargs = kwargs
-        self.logger = logging.getLogger('cmislib.model.CmisObject')
-        self.logger.info('Creating an instance of CmisObject')
-
-    def __str__(self):
-        """To string"""
-        return self.getObjectId()
-
-    def reload(self, **kwargs):
-
-        """
-        Fetches the latest representation of this object from the CMIS service.
-        Some methods, like :class:`^Document.checkout` do this for you.
-
-        If you call reload with a properties filter, the filter will be in
-        effect on subsequent calls until the filter argument is changed. To
-        reset to the full list of properties, call reload with filter set to
-        '*'.
-        """
-
-        self.logger.debug('Reload called on CmisObject')
-        if kwargs:
-            if self._kwargs:
-                self._kwargs.update(kwargs)
-            else:
-                self._kwargs = kwargs
-
-        templates = self._repository.getUriTemplates()
-        template = templates['objectbyid']['template']
-
-        # Doing some refactoring here. Originally, we snagged the template
-        # and then "filled in" the template based on the args passed in.
-        # However, some servers don't provide a full template which meant
-        # supported optional args wouldn't get passed in using the fill-the-
-        # template approach. What's going on now is that the template gets
-        # filled in where it can, but if additional, non-templated args are
-        # passed in, those will get tacked on to the query string as
-        # "additional" options.
-
-        params = {
-              '{id}': self.getObjectId(),
-              '{filter}': '',
-              '{includeAllowableActions}': 'false',
-              '{includePolicyIds}': 'false',
-              '{includeRelationships}': '',
-              '{includeACL}': 'false',
-              '{renditionFilter}': ''}
-
-        options = {}
-        addOptions = {}  # args specified, but not in the template
-        for k, v in self._kwargs.items():
-            pKey = "{" + k + "}"
-            if template.find(pKey) >= 0:
-                options[pKey] = toCMISValue(v)
-            else:
-                addOptions[k] = toCMISValue(v)
-
-        # merge the templated args with the default params
-        params.update(options)
-
-        # fill in the template
-        byObjectIdUrl = multiple_replace(params, template)
-
-        self.xmlDoc = self._cmisClient.get(byObjectIdUrl.encode('utf-8'), **addOptions)
-        self._initData()
-
-        # if a returnVersion arg was passed in, it is possible we got back
-        # a different object ID than the value we started with, so it needs
-        # to be cleared out as well
-        if options.has_key('returnVersion') or addOptions.has_key('returnVersion'):
-            self._objectId = None
-
-    def _initData(self):
-
-        """
-        An internal method used to clear out any member variables that
-        might be out of sync if we were to fetch new XML from the
-        service.
-        """
-
-        self._properties = {}
-        self._name = None
-        self._allowableActions = {}
-
-    def getObjectId(self):
-
-        """
-        Returns the object ID for this object.
-
-        >>> doc = resultSet.getResults()[0]
-        >>> doc.getObjectId()
-        u'workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339'
-        """
-
-        if self._objectId == None:
-            if self.xmlDoc == None:
-                self.logger.debug('Both objectId and xmlDoc were None, reloading')
-                self.reload()
-            props = self.getProperties()
-            self._objectId = CmisId(props['cmis:objectId'])
-        return self._objectId
-
-    def getObjectParents(self, **kwargs):
-        """
-        Gets the parents of this object as a :class:`ResultSet`.
-
-        The following optional arguments are supported:
-         - filter
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-         - includeRelativePathSegment
-        """
-        # get the appropriate 'up' link
-        parentUrl = self._getLink(UP_REL)
-
-        if parentUrl == None:
-            raise NotSupportedException('Root folder does not support getObjectParents')
-
-        # invoke the URL
-        result = self._cmisClient.get(parentUrl.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self._repository, result)
-
-    def getPaths(self):
-        """
-        Returns the object's paths as a list of strings.
-        """
-        # see sub-classes for implementation
-        pass
-
-    def getAllowableActions(self):
-
-        """
-        Returns a dictionary of allowable actions, keyed off of the action name.
-
-        >>> actions = doc.getAllowableActions()
-        >>> for a in actions:
-        ...     print "%s:%s" % (a,actions[a])
-        ...
-        canDeleteContentStream:True
-        canSetContentStream:True
-        canCreateRelationship:True
-        canCheckIn:False
-        canApplyACL:False
-        canDeleteObject:True
-        canGetAllVersions:True
-        canGetObjectParents:True
-        canGetProperties:True
-        """
-
-        if self._allowableActions == {}:
-            self.reload(includeAllowableActions=True)
-            allowElements = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'allowableActions')
-            assert len(allowElements) == 1, "Expected response to have exactly one allowableActions element"
-            allowElement = allowElements[0]
-            for node in [e for e in allowElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
-                actionName = node.localName
-                actionValue = parseBoolValue(node.childNodes[0].data)
-                self._allowableActions[actionName] = actionValue
-
-        return self._allowableActions
-
-    def getTitle(self):
-
-        """
-        Returns the value of the object's cmis:title property.
-        """
-
-        if self.xmlDoc == None:
-            self.reload()
-
-        titleElement = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'title')[0]
-
-        if titleElement and titleElement.childNodes:
-            return titleElement.childNodes[0].data
-
-    def getProperties(self):
-
-        """
-        Returns a dict of the object's properties. If CMIS returns an
-        empty element for a property, the property will be in the
-        dict with a value of None.
-
-        >>> props = doc.getProperties()
-        >>> for p in props:
-        ...     print "%s: %s" % (p, props[p])
-        ...
-        cmis:contentStreamMimeType: text/html
-        cmis:creationDate: 2009-12-15T09:45:35.369-06:00
-        cmis:baseTypeId: cmis:document
-        cmis:isLatestMajorVersion: false
-        cmis:isImmutable: false
-        cmis:isMajorVersion: false
-        cmis:objectId: workspace://SpacesStore/dc26102b-e312-471b-b2af-91bfb0225339
-
-        The optional filter argument is not yet implemented.
-        """
-
-        #TODO implement filter
-        if self._properties == {}:
-            if self.xmlDoc == None:
-                self.reload()
-            propertiesElement = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'properties')[0]
-            #cpattern = re.compile(r'^property([\w]*)')
-            for node in [e for e in propertiesElement.childNodes if e.nodeType == e.ELEMENT_NODE and e.namespaceURI == CMIS_NS]:
-                #propertyId, propertyString, propertyDateTime
-                #propertyType = cpattern.search(node.localName).groups()[0]
-                propertyName = node.attributes['propertyDefinitionId'].value
-                if node.childNodes and \
-                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0] and \
-                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes:
-                    valNodeList = node.getElementsByTagNameNS(CMIS_NS, 'value')
-                    if (len(valNodeList) == 1):
-                        propertyValue = parsePropValue(valNodeList[0].
-                                                       childNodes[0].data,
-                                                       node.localName)
-                    else:
-                        propertyValue = []
-                        for valNode in valNodeList:
-                            propertyValue.append(parsePropValue(valNode.
-                                                       childNodes[0].data,
-                                                       node.localName))
-                else:
-                    propertyValue = None
-                self._properties[propertyName] = propertyValue
-
-            for node in [e for e in self.xmlDoc.childNodes if e.nodeType == e.ELEMENT_NODE and e.namespaceURI == CMISRA_NS]:
-                propertyName = node.nodeName
-                if node.childNodes:
-                    propertyValue = node.firstChild.nodeValue
-                else:
-                    propertyValue = None
-                self._properties[propertyName] = propertyValue
-
-        return self._properties
-
-    def getName(self):
-
-        """
-        Returns the value of cmis:name from the getProperties() dictionary.
-        We don't need a getter for every standard CMIS property, but name
-        is a pretty common one so it seems to make sense.
-
-        >>> doc.getName()
-        u'system-overview.html'
-        """
-
-        if self._name == None:
-            self._name = self.getProperties()['cmis:name']
-        return self._name
-
-    def updateProperties(self, properties):
-
-        """
-        Updates the properties of an object with the properties provided.
-        Only provide the set of properties that need to be updated.
-
-        >>> folder = repo.getObjectByPath('/someFolder2')
-        >>> folder.getName()
-        u'someFolder2'
-        >>> props = {'cmis:name': 'someFolderFoo'}
-        >>> folder.updateProperties(props)
-        <cmislib.model.Folder object at 0x103ab1210>
-        >>> folder.getName()
-        u'someFolderFoo'
-
-        """
-
-        self.logger.debug('Inside updateProperties')
-
-        # get the self link
-        selfUrl = self._getSelfLink()
-
-        # if we have a change token, we must pass it back, per the spec
-        args = {}
-        if (self.properties.has_key('cmis:changeToken') and
-            self.properties['cmis:changeToken'] != None):
-            self.logger.debug('Change token present, adding it to args')
-            args = {"changeToken": self.properties['cmis:changeToken']}
-
-        # the getEntryXmlDoc function may need the object type
-        objectTypeId = None
-        if (self.properties.has_key('cmis:objectTypeId') and
-            not properties.has_key('cmis:objectTypeId')):
-            objectTypeId = self.properties['cmis:objectTypeId']
-            self.logger.debug('This object type is:%s' % objectTypeId)
-
-        # build the entry based on the properties provided
-        xmlEntryDoc = getEntryXmlDoc(self._repository, objectTypeId, properties)
-
-        self.logger.debug('xmlEntryDoc:' + xmlEntryDoc.toxml())
-
-        # do a PUT of the entry
-        updatedXmlDoc = self._cmisClient.put(selfUrl.encode('utf-8'),
-                                             xmlEntryDoc.toxml(encoding='utf-8'),
-                                             ATOM_XML_TYPE,
-                                             **args)
-
-        # reset the xmlDoc for this object with what we got back from
-        # the PUT, then call initData we dont' want to call
-        # self.reload because we've already got the parsed XML--
-        # there's no need to fetch it again
-        self.xmlDoc = updatedXmlDoc
-        self._initData()
-        return self
-
-    def move(self, sourceFolder, targetFolder):
-
-        """
-        Moves an object from the source folder to the target folder.
-
-        >>> sub1 = repo.getObjectByPath('/cmislib/sub1')
-        >>> sub2 = repo.getObjectByPath('/cmislib/sub2')
-        >>> doc = repo.getObjectByPath('/cmislib/sub1/testdoc1')
-        >>> doc.move(sub1, sub2)
-        """
-
-        postUrl = targetFolder.getChildrenLink()
-
-        args = {"sourceFolderId": sourceFolder.id}
-
-        # post the Atom entry
-        result = self._cmisClient.post(postUrl.encode('utf-8'), self.xmlDoc.toxml(encoding='utf-8'), ATOM_XML_ENTRY_TYPE, **args)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-    def delete(self, **kwargs):
-
-        """
-        Deletes this :class:`CmisObject` from the repository. Note that in the
-        case of a :class:`Folder` object, some repositories will refuse to
-        delete it if it contains children and some will delete it without
-        complaint. If what you really want to do is delete the folder and all
-        of its descendants, use :meth:`~Folder.deleteTree` instead.
-
-        >>> folder.delete()
-
-        The optional allVersions argument is supported.
-        """
-
-        url = self._getSelfLink()
-        result = self._cmisClient.delete(url.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-    def applyPolicy(self, policyId):
-
-        """
-        This is not yet implemented.
-        """
-
-        # depends on this object's canApplyPolicy allowable action
-        if self.getAllowableActions()['canApplyPolicy']:
-            raise NotImplementedError
-        else:
-            raise CmisException('This object has canApplyPolicy set to false')
-
-    def createRelationship(self, targetObj, relTypeId):
-
-        """
-        Creates a relationship between this object and a specified target
-        object using the relationship type specified. Returns the new
-        :class:`Relationship` object.
-
-        >>> rel = tstDoc1.createRelationship(tstDoc2, 'R:cmiscustom:assoc')
-        >>> rel.getProperties()
-        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
-
-        """
-
-        if isinstance(relTypeId, str):
-            relTypeId = CmisId(relTypeId)
-
-        props = {}
-        props['cmis:sourceId'] = self.getObjectId()
-        props['cmis:targetId'] = targetObj.getObjectId()
-        props['cmis:objectTypeId'] = relTypeId
-        xmlDoc = getEntryXmlDoc(self._repository, properties=props)
-
-        url = self._getLink(RELATIONSHIPS_REL)
-        assert url != None, 'Could not determine relationships URL'
-
-        result = self._cmisClient.post(url.encode('utf-8'),
-                                       xmlDoc.toxml(encoding='utf-8'),
-                                       ATOM_XML_TYPE)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # instantiate CmisObject objects with the results and return the list
-        entryElements = result.getElementsByTagNameNS(ATOM_NS, 'entry')
-        assert(len(entryElements) == 1), "Expected entry element in result from relationship URL post"
-        return getSpecializedObject(CmisObject(self._cmisClient, self, xmlDoc=entryElements[0]))
-
-    def getRelationships(self, **kwargs):
-
-        """
-        Returns a :class:`ResultSet` of :class:`Relationship` objects for each
-        relationship where the source is this object.
-
-        >>> rels = tstDoc1.getRelationships()
-        >>> len(rels.getResults())
-        1
-        >>> rel = rels.getResults().values()[0]
-        >>> rel.getProperties()
-        {u'cmis:objectId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:creationDate': None, u'cmis:objectTypeId': u'R:cmiscustom:assoc', u'cmis:lastModificationDate': None, u'cmis:targetId': u'workspace://SpacesStore/0ca1aa08-cb49-42e2-8881-53aa8496a1c1', u'cmis:lastModifiedBy': None, u'cmis:baseTypeId': u'cmis:relationship', u'cmis:sourceId': u'workspace://SpacesStore/271c48dd-6548-4771-a8f5-0de69b7cdc25', u'cmis:changeToken': None, u'cmis:createdBy': None}
-
-        The following optional arguments are supported:
-         - includeSubRelationshipTypes
-         - relationshipDirection
-         - typeId
-         - maxItems
-         - skipCount
-         - filter
-         - includeAllowableActions
-        """
-
-        url = self._getLink(RELATIONSHIPS_REL)
-        assert url != None, 'Could not determine relationships URL'
-
-        result = self._cmisClient.get(url.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self._repository, result)
-
-    def removePolicy(self, policyId):
-
-        """
-        This is not yet implemented.
-        """
-
-        # depends on this object's canRemovePolicy allowable action
-        if self.getAllowableActions()['canRemovePolicy']:
-            raise NotImplementedError
-        else:
-            raise CmisException('This object has canRemovePolicy set to false')
-
-    def getAppliedPolicies(self):
-
-        """
-        This is not yet implemented.
-        """
-
-        # depends on this object's canGetAppliedPolicies allowable action
-        if self.getAllowableActions()['canGetAppliedPolicies']:
-            raise NotImplementedError
-        else:
-            raise CmisException('This object has canGetAppliedPolicies set to false')
-
-    def getACL(self):
-
-        """
-        Repository.getCapabilities['ACL'] must return manage or discover.
-
-        >>> acl = folder.getACL()
-        >>> acl.getEntries()
-        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
-
-        The optional onlyBasicPermissions argument is currently not supported.
-        """
-
-        if self._repository.getCapabilities()['ACL']:
-            # if the ACL capability is discover or manage, this must be
-            # supported
-            aclUrl = self._getLink(ACL_REL)
-            result = self._cmisClient.get(aclUrl.encode('utf-8'))
-            if type(result) == HTTPError:
-                raise CmisException(result.code)
-            return ACL(xmlDoc=result)
-        else:
-            raise NotSupportedException
-
-    def applyACL(self, acl):
-
-        """
-        Updates the object with the provided :class:`ACL`.
-        Repository.getCapabilities['ACL'] must return manage to invoke this
-        call.
-
-        >>> acl = folder.getACL()
-        >>> acl.addEntry(ACE('jdoe', 'cmis:write', 'true'))
-        >>> acl.getEntries()
-        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x10071a8d0>, 'jdoe': <cmislib.model.ACE object at 0x10071a590>}
-        """
-
-        if self._repository.getCapabilities()['ACL'] == 'manage':
-            # if the ACL capability is manage, this must be
-            # supported
-            # but it also depends on the canApplyACL allowable action
-            # for this object
-            if not isinstance(acl, ACL):
-                raise CmisException('The ACL to apply must be an instance of the ACL class.')
-            aclUrl = self._getLink(ACL_REL)
-            assert aclUrl, "Could not determine the object's ACL URL."
-            result = self._cmisClient.put(aclUrl.encode('utf-8'), acl.getXmlDoc().toxml(encoding='utf-8'), CMIS_ACL_TYPE)
-            if type(result) == HTTPError:
-                raise CmisException(result.code)
-            return ACL(xmlDoc=result)
-        else:
-            raise NotSupportedException
-
-    def _getSelfLink(self):
-
-        """
-        Returns the URL used to retrieve this object.
-        """
-
-        url = self._getLink(SELF_REL)
-
-        assert len(url) > 0, "Could not determine the self link."
-
-        return url
-
-    def _getLink(self, rel, ltype=None):
-
-        """
-        Returns the HREF attribute of an Atom link element for the
-        specified rel.
-        """
-
-        if self.xmlDoc == None:
-            self.reload()
-        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        for linkElement in linkElements:
-
-            if ltype:
-                if linkElement.attributes.has_key('rel'):
-                    relAttr = linkElement.attributes['rel'].value
-
-                    if ltype and linkElement.attributes.has_key('type'):
-                        typeAttr = linkElement.attributes['type'].value
-
-                        if relAttr == rel and ltype.match(typeAttr):
-                            return linkElement.attributes['href'].value
-            else:
-                if linkElement.attributes.has_key('rel'):
-                    relAttr = linkElement.attributes['rel'].value
-
-                    if relAttr == rel:
-                        return linkElement.attributes['href'].value
-
-    allowableActions = property(getAllowableActions)
-    name = property(getName)
-    id = property(getObjectId)
-    properties = property(getProperties)
-    title = property(getTitle)
-    ACL = property(getACL)
-
-
-class Document(CmisObject):
-
-    """
-    An object typically associated with file content.
-    """
-
-    def checkout(self):
-
-        """
-        Performs a checkout on the :class:`Document` and returns the
-        Private Working Copy (PWC), which is also an instance of
-        :class:`Document`
-
-        >>> doc.getObjectId()
-        u'workspace://SpacesStore/f0c8b90f-bec0-4405-8b9c-2ab570589808;1.0'
-        >>> doc.isCheckedOut()
-        False
-        >>> pwc = doc.checkout()
-        >>> doc.isCheckedOut()
-        True
-        """
-
-        # get the checkedout collection URL
-        checkoutUrl = self._repository.getCollectionLink(CHECKED_OUT_COLL)
-        assert len(checkoutUrl) > 0, "Could not determine the checkedout collection url."
-
-        # get this document's object ID
-        # build entry XML with it
-        properties = {'cmis:objectId': self.getObjectId()}
-        entryXmlDoc = getEntryXmlDoc(self._repository, properties=properties)
-
-        # post it to to the checkedout collection URL
-        result = self._cmisClient.post(checkoutUrl.encode('utf-8'),
-                                       entryXmlDoc.toxml(encoding='utf-8'),
-                                       ATOM_XML_ENTRY_TYPE)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # now that the doc is checked out, we need to refresh the XML
-        # to pick up the prop updates related to a checkout
-        self.reload()
-
-        return Document(self._cmisClient, self._repository, xmlDoc=result)
-
-    def cancelCheckout(self):
-        """
-        Cancels the checkout of this object by retrieving the Private Working
-        Copy (PWC) and then deleting it. After the PWC is deleted, this object
-        will be reloaded to update properties related to a checkout.
-
-        >>> doc.isCheckedOut()
-        True
-        >>> doc.cancelCheckout()
-        >>> doc.isCheckedOut()
-        False
-        """
-
-        pwcDoc = self.getPrivateWorkingCopy()
-        if pwcDoc:
-            pwcDoc.delete()
-            self.reload()
-
-    def getPrivateWorkingCopy(self):
-
-        """
-        Retrieves the object using the object ID in the property:
-        cmis:versionSeriesCheckedOutId then uses getObject to instantiate
-        the object.
-
-        >>> doc.isCheckedOut()
-        False
-        >>> doc.checkout()
-        <cmislib.model.Document object at 0x103a25ad0>
-        >>> pwc = doc.getPrivateWorkingCopy()
-        >>> pwc.getTitle()
-        u'sample-b (Working Copy).pdf'
-        """
-
-        # reloading the document just to make sure we've got the latest
-        # and greatest PWC ID
-        self.reload()
-        pwcDocId = self.getProperties()['cmis:versionSeriesCheckedOutId']
-        if pwcDocId:
-            return self._repository.getObject(pwcDocId)
-
-    def isCheckedOut(self):
-
-        """
-        Returns true if the document is checked out.
-
-        >>> doc.isCheckedOut()
-        True
-        >>> doc.cancelCheckout()
-        >>> doc.isCheckedOut()
-        False
-        """
-
-        # reloading the document just to make sure we've got the latest
-        # and greatest checked out prop
-        self.reload()
-        return parseBoolValue(self.getProperties()['cmis:isVersionSeriesCheckedOut'])
-
-    def getCheckedOutBy(self):
-
-        """
-        Returns the ID who currently has the document checked out.
-        >>> pwc = doc.checkout()
-        >>> pwc.getCheckedOutBy()
-        u'admin'
-        """
-
-        # reloading the document just to make sure we've got the latest
-        # and greatest checked out prop
-        self.reload()
-        return self.getProperties()['cmis:versionSeriesCheckedOutBy']
-
-    def checkin(self, checkinComment=None, **kwargs):
-
-        """
-        Checks in this :class:`Document` which must be a private
-        working copy (PWC).
-
-        >>> doc.isCheckedOut()
-        False
-        >>> pwc = doc.checkout()
-        >>> doc.isCheckedOut()
-        True
-        >>> pwc.checkin()
-        <cmislib.model.Document object at 0x103a8ae90>
-        >>> doc.isCheckedOut()
-        False
-
-        The following optional arguments are supported:
-         - major
-         - properties
-         - contentStream
-         - policies
-         - addACEs
-         - removeACEs
-        """
-
-        # Add checkin to kwargs and checkinComment, if it exists
-        kwargs['checkin'] = 'true'
-        kwargs['checkinComment'] = checkinComment
-
-        # Build an empty ATOM entry
-        entryXmlDoc = getEmptyXmlDoc()
-
-        # Get the self link
-        # Do a PUT of the empty ATOM to the self link
-        url = self._getSelfLink()
-        result = self._cmisClient.put(url.encode('utf-8'), entryXmlDoc.toxml(encoding='utf-8'), ATOM_XML_TYPE, **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        return Document(self._cmisClient, self._repository, xmlDoc=result)
-
-    def getLatestVersion(self, **kwargs):
-
-        """
-        Returns a :class:`Document` object representing the latest version in
-        the version series.
-
-        The following optional arguments are supported:
-         - major
-         - filter
-         - includeRelationships
-         - includePolicyIds
-         - renditionFilter
-         - includeACL
-         - includeAllowableActions
-
-        >>> latestDoc = doc.getLatestVersion()
-        >>> latestDoc.getProperties()['cmis:versionLabel']
-        u'2.1'
-        >>> latestDoc = doc.getLatestVersion(major='false')
-        >>> latestDoc.getProperties()['cmis:versionLabel']
-        u'2.1'
-        >>> latestDoc = doc.getLatestVersion(major='true')
-        >>> latestDoc.getProperties()['cmis:versionLabel']
-        u'2.0'
-        """
-
-        doc = None
-        if kwargs.has_key('major') and kwargs['major'] == 'true':
-            doc = self._repository.getObject(self.getObjectId(), returnVersion='latestmajor')
-        else:
-            doc = self._repository.getObject(self.getObjectId(), returnVersion='latest')
-
-        return doc
-
-    def getPropertiesOfLatestVersion(self, **kwargs):
-
-        """
-        Like :class:`^CmisObject.getProperties`, returns a dict of properties
-        from the latest version of this object in the version series.
-
-        The optional major and filter arguments are supported.
-        """
-
-        latestDoc = self.getLatestVersion(**kwargs)
-
-        return latestDoc.getProperties()
-
-    def getAllVersions(self, **kwargs):
-
-        """
-        Returns a :class:`ResultSet` of document objects for the entire
-        version history of this object, including any PWC's.
-
-        The optional filter and includeAllowableActions are
-        supported.
-        """
-
-        # get the version history link
-        versionsUrl = self._getLink(VERSION_HISTORY_REL)
-
-        # invoke the URL
-        result = self._cmisClient.get(versionsUrl.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self._repository, result)
-
-    def getContentStream(self):
-
-        """
-        Returns the CMIS service response from invoking the 'enclosure' link.
-
-        >>> doc.getName()
-        u'sample-b.pdf'
-        >>> o = open('tmp.pdf', 'wb')
-        >>> result = doc.getContentStream()
-        >>> o.write(result.read())
-        >>> result.close()
-        >>> o.close()
-        >>> import os.path
-        >>> os.path.getsize('tmp.pdf')
-        117248
-
-        The optional streamId argument is not yet supported.
-        """
-
-        # TODO: Need to implement the streamId
-
-        contentElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'content')
-
-        assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
-
-        # if the src element exists, follow that
-        if contentElements[0].attributes.has_key('src'):
-            srcUrl = contentElements[0].attributes['src'].value
-
-            # the cmis client class parses non-error responses
-            result = Rest().get(srcUrl.encode('utf-8'),
-                                username=self._cmisClient.username,
-                                password=self._cmisClient.password,
-                                **self._cmisClient.extArgs)
-            if result.code != 200:
-                raise CmisException(result.code)
-            return result
-        else:
-            # otherwise, try to return the value of the content element
-            if contentElements[0].childNodes:
-                return contentElements[0].childNodes[0].data
-
-    def setContentStream(self, contentFile, contentType=None):
-
-        """
-        Sets the content stream on this object.
-
-        The following optional arguments are not yet supported:
-         - overwriteFlag=None
-        """
-
-        # get this object's content stream link
-        contentElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'content')
-
-        assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
-
-        # if the src element exists, follow that
-        if contentElements[0].attributes.has_key('src'):
-            srcUrl = contentElements[0].attributes['src'].value
-
-        # there may be times when this URL is absent, but I'm not sure how to
-        # set the content stream when that is the case
-        assert(srcUrl), 'Unable to determine content stream URL.'
-
-        # need to determine the mime type
-        mimetype = contentType
-        if not mimetype and hasattr(contentFile, 'name'):
-            mimetype, encoding = mimetypes.guess_type(contentFile.name)
-
-        if not mimetype:
-            mimetype = 'application/binary'
-
-        # if we have a change token, we must pass it back, per the spec
-        args = {}
-        if (self.properties.has_key('cmis:changeToken') and
-            self.properties['cmis:changeToken'] != None):
-            self.logger.debug('Change token present, adding it to args')
-            args = {"changeToken": self.properties['cmis:changeToken']}
-
-        # put the content file
-        result = self._cmisClient.put(srcUrl.encode('utf-8'),
-                                      contentFile.read(),
-                                      mimetype,
-                                      **args)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # what comes back is the XML for the updated document,
-        # which is not required by the spec to be the same document
-        # we just updated, so use it to instantiate a new document
-        # then return it
-        return Document(self._cmisClient, self._repository, xmlDoc=result)
-
-    def deleteContentStream(self):
-
-        """
-        Delete's the content stream associated with this object.
-        """
-
-        # get this object's content stream link
-        contentElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'content')
-
-        assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
-
-        # if the src element exists, follow that
-        if contentElements[0].attributes.has_key('src'):
-            srcUrl = contentElements[0].attributes['src'].value
-
-        # there may be times when this URL is absent, but I'm not sure how to
-        # delete the content stream when that is the case
-        assert(srcUrl), 'Unable to determine content stream URL.'
-
-        # if we have a change token, we must pass it back, per the spec
-        args = {}
-        if (self.properties.has_key('cmis:changeToken') and
-            self.properties['cmis:changeToken'] != None):
-            self.logger.debug('Change token present, adding it to args')
-            args = {"changeToken": self.properties['cmis:changeToken']}
-
-        # delete the content stream
-        result = self._cmisClient.delete(srcUrl.encode('utf-8'), **args)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-    def getRenditions(self):
-
-        """
-        Returns an array of :class:`Rendition` objects. The repository
-        must support the Renditions capability.
-
-        The following optional arguments are not currently supported:
-         - renditionFilter
-         - maxItems
-         - skipCount
-        """
-
-        # if Renditions capability is None, return notsupported
-        if self._repository.getCapabilities()['Renditions']:
-            pass
-        else:
-            raise NotSupportedException
-
-        if self.xmlDoc == None:
-            self.reload()
-
-        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        renditions = []
-        for linkElement in linkElements:
-
-            if linkElement.attributes.has_key('rel'):
-                relAttr = linkElement.attributes['rel'].value
-
-                if relAttr == RENDITION_REL:
-                    renditions.append(Rendition(linkElement))
-        return renditions
-
-    checkedOut = property(isCheckedOut)
-
-    def getPaths(self):
-        """
-        Returns the Document's paths by asking for the parents with the
-        includeRelativePathSegment flag set to true, then concats the value
-        of cmis:path with the relativePathSegment.
-        """
-        # get the appropriate 'up' link
-        parentUrl = self._getLink(UP_REL)
-
-        if parentUrl == None:
-            raise NotSupportedException('Root folder does not support getObjectParents')
-
-        # invoke the URL
-        result = self._cmisClient.get(parentUrl.encode('utf-8'),
-                                      filter='cmis:path',
-                                      includeRelativePathSegment=True)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        paths = []
-        rs = ResultSet(self._cmisClient, self._repository, result)
-        for res in rs:
-            path = res.properties['cmis:path']
-            relativePathSegment = res.properties['cmisra:relativePathSegment']
-
-            # concat with a slash
-            # add it to the list
-            paths.append(path + '/' + relativePathSegment)
-
-        return paths
-
-
-class Folder(CmisObject):
-
-    """
-    A container object that can hold other :class:`CmisObject` objects
-    """
-
-    def createFolder(self, name, properties={}):
-
-        """
-        Creates a new :class:`Folder` using the properties provided.
-        Right now I expect a property called 'cmis:name' but I don't
-        complain if it isn't there (although the CMIS provider will). If a
-        cmis:name property isn't provided, the value passed in to the name
-        argument will be used.
-
-        To specify a custom folder type, pass in a property called
-        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
-        of the instance you want to create. If you do not pass in an object
-        type ID, an instance of 'cmis:folder' will be created.
-
-        >>> subFolder = folder.createFolder('someSubfolder')
-        >>> subFolder.getName()
-        u'someSubfolder'
-
-        The following optional arguments are not supported:
-         - policies
-         - addACEs
-         - removeACEs
-        """
-
-        # get the folder represented by folderId.
-        # we'll use his 'children' link post the new child
-        postUrl = self.getChildrenLink()
-
-        # make sure the name property gets set
-        properties['cmis:name'] = name
-
-        # hardcoding to cmis:folder if it wasn't passed in via props
-        if not properties.has_key('cmis:objectTypeId'):
-            properties['cmis:objectTypeId'] = CmisId('cmis:folder')
-        # and checking to make sure the object type ID is an instance of CmisId
-        elif not isinstance(properties['cmis:objectTypeId'], CmisId):
-            properties['cmis:objectTypeId'] = CmisId(properties['cmis:objectTypeId'])
-
-        # build the Atom entry
-        entryXml = getEntryXmlDoc(self._repository, properties=properties)
-
-        # post the Atom entry
-        result = self._cmisClient.post(postUrl.encode('utf-8'),
-                                       entryXml.toxml(encoding='utf-8'),
-                                       ATOM_XML_ENTRY_TYPE)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # what comes back is the XML for the new folder,
-        # so use it to instantiate a new folder then return it
-        return Folder(self._cmisClient, self._repository, xmlDoc=result)
-
-    def createDocumentFromString(self,
-                                 name,
-                                 properties={},
-                                 contentString=None,
-                                 contentType=None,
-                                 contentEncoding=None):
-
-        """
-        Creates a new document setting the content to the string provided. If
-        the repository supports unfiled objects, you do not have to pass in
-        a parent :class:`Folder` otherwise it is required.
-
-        This method is essentially a convenience method that wraps your string
-        with a StringIO and then calls createDocument.
-
-        >>> testFolder.createDocumentFromString('testdoc3', contentString='hello, world', contentType='text/plain')
-        """
-
-        return self._repository.createDocumentFromString(name, properties,
-            self, contentString, contentType, contentEncoding)
-
-    def createDocument(self, name, properties={}, contentFile=None,
-            contentType=None, contentEncoding=None):
-
-        """
-        Creates a new Document object in the repository using
-        the properties provided.
-
-        Right now this is basically the same as createFolder,
-        but this deals with contentStreams. The common logic should
-        probably be moved to CmisObject.createObject.
-
-        The method will attempt to guess the appropriate content
-        type and encoding based on the file. To specify it yourself, pass them
-        in via the contentType and contentEncoding arguments.
-
-        >>> f = open('250px-Cmis_logo.png', 'rb')
-        >>> subFolder.createDocument('logo.png', contentFile=f)
-        <cmislib.model.Document object at 0x10410fa10>
-        >>> f.close()
-
-        If you wanted to set one or more properties when creating the doc, pass
-        in a dict, like this:
-
-        >>> props = {'cmis:someProp':'someVal'}
-        >>> f = open('250px-Cmis_logo.png', 'rb')
-        >>> subFolder.createDocument('logo.png', props, contentFile=f)
-        <cmislib.model.Document object at 0x10410fa10>
-        >>> f.close()
-
-        To specify a custom object type, pass in a property called
-        cmis:objectTypeId set to the :class:`CmisId` representing the type ID
-        of the instance you want to create. If you do not pass in an object
-        type ID, an instance of 'cmis:document' will be created.
-
-        The following optional arguments are not yet supported:
-         - versioningState
-         - policies
-         - addACEs
-         - removeACEs
-        """
-
-        return self._repository.createDocument(name,
-                                               properties,
-                                               self,
-                                               contentFile,
-                                               contentType,
-                                               contentEncoding)
-
-    def getChildren(self, **kwargs):
-
-        """
-        Returns a paged :class:`ResultSet`. The result set contains a list of
-        :class:`CmisObject` objects for each child of the Folder. The actual
-        type of the object returned depends on the object's CMIS base type id.
-        For example, the method might return a list that contains both
-        :class:`Document` objects and :class:`Folder` objects.
-
-        >>> childrenRS = subFolder.getChildren()
-        >>> children = childrenRS.getResults()
-
-        The following optional arguments are supported:
-         - maxItems
-         - skipCount
-         - orderBy
-         - filter
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-         - includePathSegment
-        """
-
-        # get the appropriate 'down' link
-        childrenUrl = self.getChildrenLink()
-        # invoke the URL
-        result = self._cmisClient.get(childrenUrl.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self._repository, result)
-
-    def getChildrenLink(self):
-
-        """
-        Gets the Atom link that knows how to return this object's children.
-        """
-
-        url = self._getLink(DOWN_REL, ATOM_XML_FEED_TYPE_P)
-
-        assert len(url) > 0, "Could not find the children url"
-
-        return url
-
-    def getDescendantsLink(self):
-
-        """
-        Returns the 'down' link of type `CMIS_TREE_TYPE`
-
-        >>> folder.getDescendantsLink()
-        u'http://localhost:8080/alfresco/s/cmis/s/workspace:SpacesStore/i/86f6bf54-f0e8-4a72-8cb1-213599ba086c/descendants'
-        """
-
-        url = self._getLink(DOWN_REL, CMIS_TREE_TYPE_P)
-
-        assert len(url) > 0, "Could not find the descendants url"
-
-        # some servers return a depth arg as part of this URL
-        # so strip it off but keep other args
-        if url.find("?") >= 0:
-            u = list(urlparse(url))
-            u[4] = '&'.join([p for p in u[4].split('&') if not p.startswith('depth=')])
-            url = urlunparse(u)
-
-        return url
-
-    def getDescendants(self, **kwargs):
-
-        """
-        Gets the descendants of this folder. The descendants are returned as
-        a paged :class:`ResultSet` object. The result set contains a list of
-        :class:`CmisObject` objects where the actual type of each object
-        returned will vary depending on the object's base type id. For example,
-        the method might return a list that contains both :class:`Document`
-        objects and :class:`Folder` objects.
-
-        The following optional argument is supported:
-         - depth. Use depth=-1 for all descendants, which is the default if no
-           depth is specified.
-
-        >>> resultSet = folder.getDescendants()
-        >>> len(resultSet.getResults())
-        105
-        >>> resultSet = folder.getDescendants(depth=1)
-        >>> len(resultSet.getResults())
-        103
-
-        The following optional arguments *may* also work but haven't been
-        tested:
-
-         - filter
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-         - includePathSegment
-
-        """
-
-        if not self._repository.getCapabilities()['GetDescendants']:
-            raise NotSupportedException('This repository does not support getDescendants')
-
-        # default the depth to -1, which is all descendants
-        if "depth" not in kwargs:
-            kwargs['depth'] = -1
-
-        # get the appropriate 'down' link
-        descendantsUrl = self.getDescendantsLink()
-
-        # invoke the URL
-        result = self._cmisClient.get(descendantsUrl.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self._repository, result)
-
-    def getTree(self, **kwargs):
-
-        """
-        Unlike :class:`Folder.getChildren` or :class:`Folder.getDescendants`,
-        this method returns only the descendant objects that are folders. The
-        results do not include the current folder.
-
-        The following optional arguments are supported:
-         - depth
-         - filter
-         - includeRelationships
-         - renditionFilter
-         - includeAllowableActions
-         - includePathSegment
-
-         >>> rs = folder.getTree(depth='2')
-         >>> len(rs.getResults())
-         3
-         >>> for folder in rs.getResults().values():
-         ...     folder.getTitle()
-         ...
-         u'subfolder2'
-         u'parent test folder'
-         u'subfolder'
-        """
-
-        # Get the descendants link and do a GET against it
-        url = self._getLink(FOLDER_TREE_REL)
-        assert url != None, 'Unable to determine folder tree link'
-        result = self._cmisClient.get(url.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return ResultSet(self._cmisClient, self, result)
-
-    def getParent(self):
-
-        """
-        This is not yet implemented.
-
-        The optional filter argument is not yet supported.
-        """
-        # get the appropriate 'up' link
-        parentUrl = self._getLink(UP_REL)
-        # invoke the URL
-        result = self._cmisClient.get(parentUrl.encode('utf-8'))
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # return the result set
-        return Folder(self._cmisClient, self._repository, xmlDoc=result)
-
-    def deleteTree(self, **kwargs):
-
-        """
-        Deletes the folder and all of its descendant objects.
-
-        >>> resultSet = subFolder.getDescendants()
-        >>> len(resultSet.getResults())
-        2
-        >>> subFolder.deleteTree()
-
-        The following optional arguments are supported:
-         - allVersions
-         - unfileObjects
-         - continueOnFailure
-        """
-
-        # Per the spec, the repo must have the GetDescendants capability
-        # to support deleteTree
-        if not self._repository.getCapabilities()['GetDescendants']:
-            raise NotSupportedException('This repository does not support deleteTree')
-
-        # Get the descendants link and do a DELETE against it
-        url = self._getLink(DOWN_REL, CMIS_TREE_TYPE_P)
-        result = self._cmisClient.delete(url.encode('utf-8'), **kwargs)
-
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-    def addObject(self, cmisObject, **kwargs):
-
-        """
-        Adds the specified object as a child of this object. No new object is
-        created. The repository must support multifiling for this to work.
-
-        >>> sub1 = repo.getObjectByPath("/cmislib/sub1")
-        >>> sub2 = repo.getObjectByPath("/cmislib/sub2")
-        >>> doc = sub1.createDocument("testdoc1")
-        >>> len(sub1.getChildren())
-        1
-        >>> len(sub2.getChildren())
-        0
-        >>> sub2.addObject(doc)
-        >>> len(sub2.getChildren())
-        1
-        >>> sub2.getChildren()[0].name
-        u'testdoc1'
-
-        The following optional arguments are supported:
-         - allVersions
-        """
-
-        if not self._repository.getCapabilities()['Multifiling']:
-            raise NotSupportedException('This repository does not support multifiling')
-
-        postUrl = self.getChildrenLink()
-
-        # post the Atom entry
-        result = self._cmisClient.post(postUrl.encode('utf-8'), cmisObject.xmlDoc.toxml(encoding='utf-8'), ATOM_XML_ENTRY_TYPE, **kwargs)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-    def removeObject(self, cmisObject):
-
-        """
-        Removes the specified object from this folder. The repository must
-        support unfiling for this to work.
-        """
-
-        if not self._repository.getCapabilities()['Unfiling']:
-            raise NotSupportedException('This repository does not support unfiling')
-
-        postUrl = self._repository.getCollectionLink(UNFILED_COLL)
-
-        args = {"removeFrom": self.getObjectId()}
-
-        # post the Atom entry to the unfiled collection
-        result = self._cmisClient.post(postUrl.encode('utf-8'), cmisObject.xmlDoc.toxml(encoding='utf-8'), ATOM_XML_ENTRY_TYPE, **args)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-    def getPaths(self):
-        """
-        Returns the paths as a list of strings. The spec says folders cannot
-        be multi-filed, so this should always be one value. We return a list
-        to be symmetric with the same method in :class:`Document`.
-        """
-        return [self.properties['cmis:path']]
-
-
-class Relationship(CmisObject):
-
-    """
-    Defines a relationship object between two :class:`CmisObjects` objects
-    """
-
-    def getSourceId(self):
-
-        """
-        Returns the :class:`CmisId` on the source side of the relationship.
-        """
-
-        if self.xmlDoc == None:
-            self.reload()
-        props = self.getProperties()
-        return CmisId(props['cmis:sourceId'])
-
-    def getTargetId(self):
-
-        """
-        Returns the :class:`CmisId` on the target side of the relationship.
-        """
-
-        if self.xmlDoc == None:
-            self.reload()
-        props = self.getProperties()
-        return CmisId(props['cmis:targetId'])
-
-    def getSource(self):
-
-        """
-        Returns an instance of the appropriate child-type of :class:`CmisObject`
-        for the source side of the relationship.
-        """
-
-        sourceId = self.getSourceId()
-        return getSpecializedObject(self._repository.getObject(sourceId))
-
-    def getTarget(self):
-
-        """
-        Returns an instance of the appropriate child-type of :class:`CmisObject`
-        for the target side of the relationship.
-        """
-
-        targetId = self.getTargetId()
-        return getSpecializedObject(self._repository.getObject(targetId))
-
-    sourceId = property(getSourceId)
-    targetId = property(getTargetId)
-    source = property(getSource)
-    target = property(getTarget)
-
-
-class Policy(CmisObject):
-
-    """
-    An arbirary object that can 'applied' to objects that the
-    repository identifies as being 'controllable'.
-    """
-
-    pass
-
-
-class ObjectType(object):
-
-    """
-    Represents the CMIS object type such as 'cmis:document' or 'cmis:folder'.
-    Contains metadata about the type.
-    """
-
-    def __init__(self, cmisClient, repository, typeId=None, xmlDoc=None):
-        """ Constructor """
-        self._cmisClient = cmisClient
-        self._repository = repository
-        self._kwargs = None
-        self._typeId = typeId
-        self.xmlDoc = xmlDoc
-        self.logger = logging.getLogger('cmislib.model.ObjectType')
-        self.logger.info('Creating an instance of ObjectType')
-
-    def __str__(self):
-        """To string"""
-        return self.getTypeId()
-
-    def getTypeId(self):
-
-        """
-        Returns the type ID for this object.
-
-        >>> docType = repo.getTypeDefinition('cmis:document')
-        >>> docType.getTypeId()
-        'cmis:document'
-        """
-
-        if self._typeId == None:
-            if self.xmlDoc == None:
-                self.reload()
-            self._typeId = CmisId(self._getElementValue(CMIS_NS, 'id'))
-
-        return self._typeId
-
-    def _getElementValue(self, namespace, elementName):
-
-        """
-        Helper method to retrieve child element values from type XML.
-        """
-
-        if self.xmlDoc == None:
-            self.reload()
-        #typeEls = self.xmlDoc.getElementsByTagNameNS(CMISRA_NS, 'type')
-        #assert len(typeEls) == 1, "Expected to find exactly one type element but instead found %d" % len(typeEls)
-        #typeEl = typeEls[0]
-        typeEl = None
-        for e in self.xmlDoc.childNodes:
-            if e.nodeType == e.ELEMENT_NODE and e.localName == "type":
-                typeEl = e
-                break
-
-        assert typeEl, "Expected to find one child element named type"
-        els = typeEl.getElementsByTagNameNS(namespace, elementName)
-        if len(els) >= 1:
-            el = els[0]
-            if el and len(el.childNodes) >= 1:
-                return el.childNodes[0].data
-
-    def getLocalName(self):
-        """Getter for cmis:localName"""
-        return self._getElementValue(CMIS_NS, 'localName')
-
-    def getLocalNamespace(self):
-        """Getter for cmis:localNamespace"""
-        return self._getElementValue(CMIS_NS, 'localNamespace')
-
-    def getDisplayName(self):
-        """Getter for cmis:displayName"""
-        return self._getElementValue(CMIS_NS, 'displayName')
-
-    def getQueryName(self):
-        """Getter for cmis:queryName"""
-        return self._getElementValue(CMIS_NS, 'queryName')
-
-    def getDescription(self):
-        """Getter for cmis:description"""
-        return self._getElementValue(CMIS_NS, 'description')
-
-    def getBaseId(self):
-        """Getter for cmis:baseId"""
-        return CmisId(self._getElementValue(CMIS_NS, 'baseId'))
-
-    def isCreatable(self):
-        """Getter for cmis:creatable"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'creatable'))
-
-    def isFileable(self):
-        """Getter for cmis:fileable"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'fileable'))
-
-    def isQueryable(self):
-        """Getter for cmis:queryable"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'queryable'))
-
-    def isFulltextIndexed(self):
-        """Getter for cmis:fulltextIndexed"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'fulltextIndexed'))
-
-    def isIncludedInSupertypeQuery(self):
-        """Getter for cmis:includedInSupertypeQuery"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'includedInSupertypeQuery'))
-
-    def isControllablePolicy(self):
-        """Getter for cmis:controllablePolicy"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'controllablePolicy'))
-
-    def isControllableACL(self):
-        """Getter for cmis:controllableACL"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'controllableACL'))
-
-    def getLink(self, rel, linkType):
-
-        """
-        Gets the HREF for the link element with the specified rel and linkType.
-
-        >>> from cmislib.model import ATOM_XML_FEED_TYPE
-        >>> docType.getLink('down', ATOM_XML_FEED_TYPE)
-        u'http://localhost:8080/alfresco/s/cmis/type/cmis:document/children'
-        """
-
-        linkElements = self.xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        for linkElement in linkElements:
-
-            if linkElement.attributes.has_key('rel') and linkElement.attributes.has_key('type'):
-                relAttr = linkElement.attributes['rel'].value
-                typeAttr = linkElement.attributes['type'].value
-
-                if relAttr == rel and linkType.match(typeAttr):
-                    return linkElement.attributes['href'].value
-
-    def getProperties(self):
-
-        """
-        Returns a list of :class:`Property` objects representing each property
-        defined for this type.
-
-        >>> objType = repo.getTypeDefinition('cmis:relationship')
-        >>> for prop in objType.properties:
-        ...    print 'Id:%s' % prop.id
-        ...    print 'Cardinality:%s' % prop.cardinality
-        ...    print 'Description:%s' % prop.description
-        ...    print 'Display name:%s' % prop.displayName
-        ...    print 'Local name:%s' % prop.localName
-        ...    print 'Local namespace:%s' % prop.localNamespace
-        ...    print 'Property type:%s' % prop.propertyType
-        ...    print 'Query name:%s' % prop.queryName
-        ...    print 'Updatability:%s' % prop.updatability
-        ...    print 'Inherited:%s' % prop.inherited
-        ...    print 'Orderable:%s' % prop.orderable
-        ...    print 'Queryable:%s' % prop.queryable
-        ...    print 'Required:%s' % prop.required
-        ...    print 'Open choice:%s' % prop.openChoice
-        """
-
-        if self.xmlDoc == None:
-            self.reload(includePropertyDefinitions='true')
-        # Currently, property defs don't have an enclosing element. And, the
-        # element name varies depending on type. Until that changes, I'm going
-        # to find all elements unique to a prop, then grab its parent node.
-        propTypeElements = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'propertyType')
-        if len(propTypeElements) <= 0:
-            self.reload(includePropertyDefinitions='true')
-            propTypeElements = self.xmlDoc.getElementsByTagNameNS(CMIS_NS, 'propertyType')
-            assert len(propTypeElements) > 0, 'Could not retrieve object type property definitions'
-        props = {}
-        for typeEl in propTypeElements:
-            prop = Property(typeEl.parentNode)
-            props[prop.id] = prop
-        return props
-
-    def reload(self, **kwargs):
-        """
-        This method will reload the object's data from the CMIS service.
-        """
-        if kwargs:
-            if self._kwargs:
-                self._kwargs.update(kwargs)
-            else:
-                self._kwargs = kwargs
-        templates = self._repository.getUriTemplates()
-        template = templates['typebyid']['template']
-        params = {'{id}': self._typeId}
-        byTypeIdUrl = multiple_replace(params, template)
-        result = self._cmisClient.get(byTypeIdUrl.encode('utf-8'), **kwargs)
-        if type(result) == HTTPError:
-            raise CmisException(result.code)
-
-        # instantiate CmisObject objects with the results and return the list
-        entryElements = result.getElementsByTagNameNS(ATOM_NS, 'entry')
-        assert(len(entryElements) == 1), "Expected entry element in result from calling %s" % byTypeIdUrl
-        self.xmlDoc = entryElements[0]
-
-    id = property(getTypeId)
-    localName = property(getLocalName)
-    localNamespace = property(getLocalNamespace)
-    displayName = property(getDisplayName)
-    queryName = property(getQueryName)
-    description = property(getDescription)
-    baseId = property(getBaseId)
-    creatable = property(isCreatable)
-    fileable = property(isFileable)
-    queryable = property(isQueryable)
-    fulltextIndexed = property(isFulltextIndexed)
-    includedInSupertypeQuery = property(isIncludedInSupertypeQuery)
-    controllablePolicy = property(isControllablePolicy)
-    controllableACL = property(isControllableACL)
-    properties = property(getProperties)
-
-
-class Property(object):
-
-    """
-    This class represents an attribute or property definition of an object
-    type.
-    """
-
-    def __init__(self, propNode):
-        """Constructor"""
-        self.xmlDoc = propNode
-        self.logger = logging.getLogger('cmislib.model.Property')
-        self.logger.info('Creating an instance of Property')
-
-    def __str__(self):
-        """To string"""
-        return self.getId()
-
-    def _getElementValue(self, namespace, elementName):
-
-        """
-        Utility method for retrieving element values from the object type XML.
-        """
-
-        els = self.xmlDoc.getElementsByTagNameNS(namespace, elementName)
-        if len(els) >= 1:
-            el = els[0]
-            if el and len(el.childNodes) >= 1:
-                return el.childNodes[0].data
-
-    def getId(self):
-        """Getter for cmis:id"""
-        return self._getElementValue(CMIS_NS, 'id')
-
-    def getLocalName(self):
-        """Getter for cmis:localName"""
-        return self._getElementValue(CMIS_NS, 'localName')
-
-    def getLocalNamespace(self):
-        """Getter for cmis:localNamespace"""
-        return self._getElementValue(CMIS_NS, 'localNamespace')
-
-    def getDisplayName(self):
-        """Getter for cmis:displayName"""
-        return self._getElementValue(CMIS_NS, 'displayName')
-
-    def getQueryName(self):
-        """Getter for cmis:queryName"""
-        return self._getElementValue(CMIS_NS, 'queryName')
-
-    def getDescription(self):
-        """Getter for cmis:description"""
-        return self._getElementValue(CMIS_NS, 'description')
-
-    def getPropertyType(self):
-        """Getter for cmis:propertyType"""
-        return self._getElementValue(CMIS_NS, 'propertyType')
-
-    def getCardinality(self):
-        """Getter for cmis:cardinality"""
-        return self._getElementValue(CMIS_NS, 'cardinality')
-
-    def getUpdatability(self):
-        """Getter for cmis:updatability"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'updatability'))
-
-    def isInherited(self):
-        """Getter for cmis:inherited"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'inherited'))
-
-    def isRequired(self):
-        """Getter for cmis:required"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'required'))
-
-    def isQueryable(self):
-        """Getter for cmis:queryable"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'queryable'))
-
-    def isOrderable(self):
-        """Getter for cmis:orderable"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'orderable'))
-
-    def isOpenChoice(self):
-        """Getter for cmis:openChoice"""
-        return parseBoolValue(self._getElementValue(CMIS_NS, 'openChoice'))
-
-    id = property(getId)
-    localName = property(getLocalName)
-    localNamespace = property(getLocalNamespace)
-    displayName = property(getDisplayName)
-    queryName = property(getQueryName)
-    description = property(getDescription)
-    propertyType = property(getPropertyType)
-    cardinality = property(getCardinality)
-    updatability = property(getUpdatability)
-    inherited = property(isInherited)
-    required = property(isRequired)
-    queryable = property(isQueryable)
-    orderable = property(isOrderable)
-    openChoice = property(isOpenChoice)
-
-
-class ACL(object):
-
-    """
-    Represents the Access Control List for an object.
-    """
-
-    def __init__(self, aceList=None, xmlDoc=None):
-
-        """
-        Constructor. Pass in either a list of :class:`ACE` objects or the XML
-        representation of the ACL. If you have only one ACE, don't worry about
-        the list--the constructor will convert it to a list for you.
-        """
-
-        if aceList:
-            self._entries = aceList
-        else:
-            self._entries = {}
-        if xmlDoc:
-            self._xmlDoc = xmlDoc
-            self._entries = self._getEntriesFromXml()
-        else:
-            self._xmlDoc = None
-
-        self.logger = logging.getLogger('cmislib.model.ACL')
-        self.logger.info('Creating an instance of ACL')
-
-    def addEntry(self, ace):
-
-        """
-        Adds an :class:`ACE` entry to the ACL.
-
-        >>> acl = folder.getACL()
-        >>> acl.addEntry(ACE('jpotts', 'cmis:read', 'true'))
-        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
-        >>> acl.getEntries()
-        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
-        """
-
-        self._entries[ace.principalId] = ace
-
-    def removeEntry(self, principalId):
-
-        """
-        Removes the :class:`ACE` entry given a specific principalId.
-
-        >>> acl.getEntries()
-        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>, 'jsmith': <cmislib.model.ACE object at 0x1005a2210>}
-        >>> acl.removeEntry('jsmith')
-        >>> acl.getEntries()
-        {u'GROUP_EVERYONE': <cmislib.model.ACE object at 0x100731410>, u'jdoe': <cmislib.model.ACE object at 0x100731150>, 'jpotts': <cmislib.model.ACE object at 0x1005a22d0>}
-        """
-
-        if self._entries.has_key(principalId):
-            del(self._entries[principalId])
-
-    def clearEntries(self):
-
-        """
-        Clears all :class:`ACE` entries from the ACL and removes the internal
-        XML representation of the ACL.
-
-        >>> acl = ACL()
-        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
-        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
-        >>> acl.entries
-        {'jpotts': <cmislib.model.ACE object at 0x1012c7310>, 'jsmith': <cmislib.model.ACE object at 0x100528490>}
-        >>> acl.getXmlDoc()
-        <xml.dom.minidom.Document instance at 0x1012cbb90>
-        >>> acl.clearEntries()
-        >>> acl.entries
-        >>> acl.getXmlDoc()
-        """
-
-        self._entries.clear()
-        self._xmlDoc = None
-
-    def getEntries(self):
-
-        """
-        Returns a dictionary of :class:`ACE` objects for each Access Control
-        Entry in the ACL. The key value is the ACE principalid.
-
-        >>> acl = ACL()
-        >>> acl.addEntry(ACE('jsmith', 'cmis:write', 'true'))
-        >>> acl.addEntry(ACE('jpotts', 'cmis:write', 'true'))
-        >>> for ace in acl.entries.values():
-        ...     print 'principal:%s has the following permissions...' % ace.principalId
-        ...     for perm in ace.permissions:
-        ...             print perm
-        ...
-        principal:jpotts has the following permissions...
-        cmis:write
-        principal:jsmith has the following permissions...
-        cmis:write
-        """
-
-        if self._entries:
-            return self._entries
-        else:
-            if self._xmlDoc:
-                # parse XML doc and build entry list
-                self._entries = self._getEntriesFromXml()
-                # then return it
-                return self._entries
-
-    def _getEntriesFromXml(self):
-
-        """
-        Helper method for getting the :class:`ACE` entries from an XML
-        representation of the ACL.
-        """
-
-        if not self._xmlDoc:
-            return
-        result = {}
-        # first child is the root node, cmis:acl
-        for e in self._xmlDoc.childNodes[0].childNodes:
-            if e.localName == 'permission':
-                # grab the principal/principalId element value
-                prinEl = e.getElementsByTagNameNS(CMIS_NS, 'principal')[0]
-                if prinEl and prinEl.childNodes:
-                    prinIdEl = prinEl.getElementsByTagNameNS(CMIS_NS, 'principalId')[0]
-                    if prinIdEl and prinIdEl.childNodes:
-                        principalId = prinIdEl.childNodes[0].data
-                # grab the permission values
-                permEls = e.getElementsByTagNameNS(CMIS_NS, 'permission')
-                perms = []
-                for permEl in permEls:
-                    if permEl and permEl.childNodes:
-                        perms.append(permEl.childNodes[0].data)
-                # grab the direct value
-                dirEl = e.getElementsByTagNameNS(CMIS_NS, 'direct')[0]
-                if dirEl and dirEl.childNodes:
-                    direct = dirEl.childNodes[0].data
-                # create an ACE
-                if (len(perms) > 0):
-                    ace = ACE(principalId, perms, direct)
-                    # append it to the dictionary
-                    result[principalId] = ace
-        return result
-
-    def getXmlDoc(self):
-
-        """
-        This method rebuilds the local XML representation of the ACL based on
-        the :class:`ACE` objects in the entries list and returns the resulting
-        XML Document.
-        """
-
-        if not self.getEntries():
-            return
-
-        xmlDoc = minidom.Document()
-        aclEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:acl')
-        aclEl.setAttribute('xmlns:cmis', CMIS_NS)
-        for ace in self.getEntries().values():
-            permEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:permission')
-            #principalId
-            prinEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:principal')
-            prinIdEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:principalId')
-            prinIdElText = xmlDoc.createTextNode(ace.principalId)
-            prinIdEl.appendChild(prinIdElText)
-            prinEl.appendChild(prinIdEl)
-            permEl.appendChild(prinEl)
-            #direct
-            directEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:direct')
-            directElText = xmlDoc.createTextNode(ace.direct)
-            directEl.appendChild(directElText)
-            permEl.appendChild(directEl)
-            #permissions
-            for perm in ace.permissions:
-                permItemEl = xmlDoc.createElementNS(CMIS_NS, 'cmis:permission')
-                permItemElText = xmlDoc.createTextNode(perm)
-                permItemEl.appendChild(permItemElText)
-                permEl.appendChild(permItemEl)
-            aclEl.appendChild(permEl)
-        xmlDoc.appendChild(aclEl)
-        self._xmlDoc = xmlDoc
-        return self._xmlDoc
-
-    entries = property(getEntries)
-
-
-class ACE(object):
-
-    """
-    Represents an individual Access Control Entry.
-    """
-
-    def __init__(self, principalId=None, permissions=None, direct=None):
-        """Constructor"""
-        self._principalId = principalId
-        if permissions:
-            if isinstance(permissions, str):
-                self._permissions = [permissions]
-            else:
-                self._permissions = permissions
-        self._direct = direct
-
-        self.logger = logging.getLogger('cmislib.model.ACE')
-        self.logger.info('Creating an instance of ACE')
-
-    @property
-    def principalId(self):
-        """Getter for principalId"""
-        return self._principalId
-
-    @property
-    def direct(self):
-        """Getter for direct"""
-        return self._direct
-
-    @property
-    def permissions(self):
-        """Getter for permissions"""
-        return self._permissions
-
-
-class ChangeEntry(object):
-
-    """
-    Represents a change log entry. Retrieve a list of change entries via
-    :meth:`Repository.getContentChanges`.
-
-    >>> for changeEntry in rs:
-    ...     changeEntry.objectId
-    ...     changeEntry.id
-    ...     changeEntry.changeType
-    ...     changeEntry.changeTime
-    ...
-    'workspace://SpacesStore/0e2dc775-16b7-4634-9e54-2417a196829b'
-    u'urn:uuid:0e2dc775-16b7-4634-9e54-2417a196829b'
-    u'created'
-    datetime.datetime(2010, 2, 11, 12, 55, 14)
-    'workspace://SpacesStore/bd768f9f-99a7-4033-828d-5b13f96c6923'
-    u'urn:uuid:bd768f9f-99a7-4033-828d-5b13f96c6923'
-    u'updated'
-    datetime.datetime(2010, 2, 11, 12, 55, 13)
-    'workspace://SpacesStore/572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
-    u'urn:uuid:572c2cac-6b26-4cd8-91ad-b2931fe5b3fb'
-    u'updated'
-    """
-
-    def __init__(self, cmisClient, repository, xmlDoc):
-        """Constructor"""
-        self._cmisClient = cmisClient
-        self._repository = repository
-        self._xmlDoc = xmlDoc
-        self._properties = {}
-        self._objectId = None
-        self._changeEntryId = None
-        self._changeType = None
-        self._changeTime = None
-        self.logger = logging.getLogger('cmislib.model.ChangeEntry')
-        self.logger.info('Creating an instance of ChangeEntry')
-
-    def getId(self):
-        """
-        Returns the unique ID of the change entry.
-        """
-        if self._changeEntryId == None:
-            self._changeEntryId = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'id')[0].firstChild.data
-        return self._changeEntryId
-
-    def getObjectId(self):
-        """
-        Returns the object ID of the object that changed.
-        """
-        if self._objectId == None:
-            props = self.getProperties()
-            self._objectId = CmisId(props['cmis:objectId'])
-        return self._objectId
-
-    def getChangeType(self):
-
-        """
-        Returns the type of change that occurred. The resulting value must be
-        one of:
-
-         - created
-         - updated
-         - deleted
-         - security
-        """
-
-        if self._changeType == None:
-            self._changeType = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeType')[0].firstChild.data
-        return self._changeType
-
-    def getACL(self):
-
-        """
-        Gets the :class:`ACL` object that is included with this Change Entry.
-        """
-
-        # if you call getContentChanges with includeACL=true, you will get a
-        # cmis:ACL entry. change entries don't appear to have a self URL so
-        # instead of doing a reload with includeACL set to true, we'll either
-        # see if the XML already has an ACL element and instantiate an ACL with
-        # it, or we'll get the ACL_REL link, invoke that, and return the result
-        if not self._repository.getCapabilities()['ACL']:
-            return
-        aclEls = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'acl')
-        aclUrl = self._getLink(ACL_REL)
-        if (len(aclEls) == 1):
-            return ACL(self._cmisClient, self._repository, aclEls[0])
-        elif aclUrl:
-            result = self._cmisClient.get(aclUrl.encode('utf-8'))
-            if type(result) == HTTPError:
-                raise CmisException(result.code)
-            return ACL(xmlDoc=result)
-
-    def getChangeTime(self):
-
-        """
-        Returns a datetime object representing the time the change occurred.
-        """
-
-        if self._changeTime == None:
-            self._changeTime = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'changeTime')[0].firstChild.data
-        return parseDateTimeValue(self._changeTime)
-
-    def getProperties(self):
-
-        """
-        Returns the properties of the change entry. Note that depending on the
-        capabilities of the repository ("capabilityChanges") the list may not
-        include the actual property values that changed.
-        """
-
-        if self._properties == {}:
-            propertiesElement = self._xmlDoc.getElementsByTagNameNS(CMIS_NS, 'properties')[0]
-            for node in [e for e in propertiesElement.childNodes if e.nodeType == e.ELEMENT_NODE]:
-                propertyName = node.attributes['propertyDefinitionId'].value
-                if node.childNodes and \
-                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0] and \
-                   node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes:
-                    propertyValue = parsePropValue(
-                       node.getElementsByTagNameNS(CMIS_NS, 'value')[0].childNodes[0].data,
-                       node.localName)
-                else:
-                    propertyValue = None
-                self._properties[propertyName] = propertyValue
-        return self._properties
-
-    def _getLink(self, rel):
-
-        """
-        Returns the HREF attribute of an Atom link element for the
-        specified rel.
-        """
-
-        linkElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'link')
-
-        for linkElement in linkElements:
-            if linkElement.attributes.has_key('rel'):
-                relAttr = linkElement.attributes['rel'].value
-
-                if relAttr == rel:
-                    return linkElement.attributes['href'].value
-
-    id = property(getId)
-    objectId = property(getObjectId)
-    changeTime = property(getChangeTime)
-    changeType = property(getChangeType)
-    properties = property(getProperties)
-
-
-class ChangeEntryResultSet(ResultSet):
-
-    """
-    A specialized type of :class:`ResultSet` that knows how to instantiate
-    :class:`ChangeEntry` objects. The parent class assumes children of
-    :class:`CmisObject` which doesn't work for ChangeEntries.
-    """
-
-    def __iter__(self):
-
-        """
-        Overriding to make it work with a list instead of a dict.
-        """
-
-        return iter(self.getResults())
-
-    def __getitem__(self, index):
-
-        """
-        Overriding to make it work with a list instead of a dict.
-        """
-
-        return self.getResults()[index]
-
-    def __len__(self):
-
-        """
-        Overriding to make it work with a list instead of a dict.
-        """
-
-        return len(self.getResults())
-
-    def getResults(self):
-
-        """
-        Overriding to make it work with a list instead of a dict.
-        """
-
-        if self._results:
-            return self._results
-
-        if self._xmlDoc:
-            entryElements = self._xmlDoc.getElementsByTagNameNS(ATOM_NS, 'entry')
-            entries = []
-            for entryElement in entryElements:
-                changeEntry = ChangeEntry(self._cmisClient, self._repository, entryElement)
-                entries.append(changeEntry)
-
-            self._results = entries
-
-        return self._results
-
-
-class Rendition(object):
-
-    """
-    This class represents a Rendition.
-    """
-
-    def __init__(self, propNode):
-        """Constructor"""
-        self.xmlDoc = propNode
-        self.logger = logging.getLogger('cmislib.model.Rendition')
-        self.logger.info('Creating an instance of Rendition')
-
-    def __str__(self):
-        """To string"""
-        return self.getStreamId()
-
-    def getStreamId(self):
-        """Getter for the rendition's stream ID"""
-        if self.xmlDoc.attributes.has_key('streamId'):
-            return self.xmlDoc.attributes['streamId'].value
-
-    def getMimeType(self):
-        """Getter for the rendition's mime type"""
-        if self.xmlDoc.attributes.has_key('type'):
-            return self.xmlDoc.attributes['type'].value
-
-    def getLength(self):
-        """Getter for the renditions's length"""
-        if self.xmlDoc.attributes.has_key('length'):
-            return self.xmlDoc.attributes['length'].value
-
-    def getTitle(self):
-        """Getter for the renditions's title"""
-        if self.xmlDoc.attributes.has_key('title'):
-            return self.xmlDoc.attributes['title'].value
-
-    def getKind(self):
-        """Getter for the renditions's kind"""
-        if self.xmlDoc.hasAttributeNS(CMISRA_NS, 'renditionKind'):
-            return self.xmlDoc.getAttributeNS(CMISRA_NS, 'renditionKind')
-
-    def getHeight(self):
-        """Getter for the renditions's height"""
-        if self.xmlDoc.attributes.has_key('height'):
-            return self.xmlDoc.attributes['height'].value
-
-    def getWidth(self):
-        """Getter for the renditions's width"""
-        if self.xmlDoc.attributes.has_key('width'):
-            return self.xmlDoc.attributes['width'].value
-
-    def getHref(self):
-        """Getter for the renditions's href"""
-        if self.xmlDoc.attributes.has_key('href'):
-            return self.xmlDoc.attributes['href'].value
-
-    def getRenditionDocumentId(self):
-        """Getter for the renditions's width"""
-        if self.xmlDoc.attributes.has_key('renditionDocumentId'):
-            return self.xmlDoc.attributes['renditionDocumentId'].value
-
-    streamId = property(getStreamId)
-    mimeType = property(getMimeType)
-    length = property(getLength)
-    title = property(getTitle)
-    kind = property(getKind)
-    height = property(getHeight)
-    width = property(getWidth)
-    href = property(getHref)
-    renditionDocumentId = property(getRenditionDocumentId)
-
-
-class CmisId(str):
-
-    """
-    This is a marker class to be used for Strings that are used as CMIS ID's.
-    Making the objects instances of this class makes it easier to create the
-    Atom entry XML with the appropriate type, ie, cmis:propertyId, instead of
-    cmis:propertyString.
-    """
-
-    pass
-
-
-class UriTemplate(dict):
-
-    """
-    Simple dictionary to represent the data stored in
-    a URI template entry.
-    """
-
-    def __init__(self, template, templateType, mediaType):
-
-        """
-        Constructor
-        """
-
-        dict.__init__(self)
-        self['template'] = template
-        self['type'] = templateType
-        self['mediaType'] = mediaType
-
-
-def parsePropValue(value, nodeName):
-
-    """
-    Returns a properly-typed object based on the type as specified in the
-    node's element name.
-    """
-
-    moduleLogger.debug('Inside parsePropValue')
-
-    if nodeName == 'propertyId':
-        return CmisId(value)
-    elif nodeName == 'propertyString':
-        return value
-    elif nodeName == 'propertyBoolean':
-        bDict = {'false': False, 'true': True}
-        return bDict[value.lower()]
-    elif nodeName == 'propertyInteger':
-        return int(value)
-    elif nodeName == 'propertyDecimal':
-        return float(value)
-    elif nodeName == 'propertyDateTime':
-        #%z doesn't seem to work, so I'm going to trunc the offset
-        #not all servers return microseconds, so those go too
-        return parseDateTimeValue(value)
-    else:
-        return value
-
-
-def parseDateTimeValue(value):
-
-    """
-    Utility function to return a datetime from a string.
-    """
-    return iso8601.parse_date(value)
-
-
-def parseBoolValue(value):
-
-    """
-    Utility function to parse booleans and none from strings
-    """
-
-    if value == 'false':
-        return False
-    elif value == 'true':
-        return True
-    elif value == 'none':
-        return None
-    else:
-        return value
-
-
-def toCMISValue(value):
-
-    """
-    Utility function to convert Python values to CMIS string values
-    """
-
-    if value == False:
-        return 'false'
-    elif value == True:
-        return 'true'
-    elif value == None:
-        return 'none'
-    else:
-        return value
-
-
-def multiple_replace(aDict, text):
-
-    """
-    Replace in 'text' all occurences of any key in the given
-    dictionary by its corresponding value.  Returns the new string.
-
-    See http://code.activestate.com/recipes/81330/
-    """
-
-    # Create a regular expression  from the dictionary keys
-    regex = re.compile("(%s)" % "|".join(map(re.escape, aDict.keys())))
-
-    # For each match, look-up corresponding value in dictionary
-    return regex.sub(lambda mo: aDict[mo.string[mo.start():mo.end()]], text)
-
-
-def getSpecializedObject(obj, **kwargs):
-
-    """
-    Returns an instance of the appropriate :class:`CmisObject` class or one
-    of its child types depending on the specified baseType.
-    """
-
-    moduleLogger.debug('Inside getSpecializedObject')
-
-    if 'cmis:baseTypeId' in obj.getProperties():
-        baseType = obj.getProperties()['cmis:baseTypeId']
-        if baseType == 'cmis:folder':
-            return Folder(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
-        if baseType == 'cmis:document':
-            return Document(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
-        if baseType == 'cmis:relationship':
-            return Relationship(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
-        if baseType == 'cmis:policy':
-            return Policy(obj._cmisClient, obj._repository, obj.getObjectId(), obj.xmlDoc, **kwargs)
-
-    # if the base type ID wasn't found in the props (this can happen when
-    # someone runs a query that doesn't select * or doesn't individually
-    # specify baseTypeId) or if the type isn't one of the known base
-    # types, give the object back
-    return obj
-
-
-def getEmptyXmlDoc():
-
-    """
-    Internal helper method that knows how to build an empty Atom entry.
-    """
-
-    moduleLogger.debug('Inside getEmptyXmlDoc')
-
-    entryXmlDoc = minidom.Document()
-    entryElement = entryXmlDoc.createElementNS(ATOM_NS, "entry")
-    entryElement.setAttribute('xmlns', ATOM_NS)
-    entryXmlDoc.appendChild(entryElement)
-    return entryXmlDoc
-
-
-def getEntryXmlDoc(repo=None, objectTypeId=None, properties=None, contentFile=None,
-                    contentType=None, contentEncoding=None):
-
-    """
-    Internal helper method that knows how to build an Atom entry based
-    on the properties and, optionally, the contentFile provided.
-    """
-
-    moduleLogger.debug('Inside getEntryXmlDoc')
-
-    entryXmlDoc = minidom.Document()
-    entryElement = entryXmlDoc.createElementNS(ATOM_NS, "entry")
-    entryElement.setAttribute('xmlns', ATOM_NS)
-    entryElement.setAttribute('xmlns:app', APP_NS)
-    entryElement.setAttribute('xmlns:cmisra', CMISRA_NS)
-    entryXmlDoc.appendChild(entryElement)
-
-    # if there is a File, encode it and add it to the XML
-    if contentFile:
-        mimetype = contentType
-        encoding = contentEncoding
-
-        # need to determine the mime type
-        if not mimetype and hasattr(contentFile, 'name'):
-            mimetype, encoding = mimetypes.guess_type(contentFile.name)
-
-        if not mimetype:
-            mimetype = 'application/binary'
-
-        if not encoding:
-            encoding = 'utf8'
-
-        # This used to be ATOM_NS content but there is some debate among
-        # vendors whether the ATOM_NS content must always be base64
-        # encoded. The spec does mandate that CMISRA_NS content be encoded
-        # and that element takes precedence over ATOM_NS content if it is
-        # present, so it seems reasonable to use CMIS_RA content for now
-        # and encode everything.
-
-        fileData = contentFile.read().encode("base64")
-        mediaElement = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:mediatype')
-        mediaElementText = entryXmlDoc.createTextNode(mimetype)
-        mediaElement.appendChild(mediaElementText)
-        base64Element = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:base64')
-        base64ElementText = entryXmlDoc.createTextNode(fileData)
-        base64Element.appendChild(base64ElementText)
-        contentElement = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:content')
-        contentElement.appendChild(mediaElement)
-        contentElement.appendChild(base64Element)
-        entryElement.appendChild(contentElement)
-
-    objectElement = entryXmlDoc.createElementNS(CMISRA_NS, 'cmisra:object')
-    objectElement.setAttribute('xmlns:cmis', CMIS_NS)
-    entryElement.appendChild(objectElement)
-
-    if properties:
-        # a name is required for most things, but not for a checkout
-        if properties.has_key('cmis:name'):
-            titleElement = entryXmlDoc.createElementNS(ATOM_NS, "title")
-            titleText = entryXmlDoc.createTextNode(properties['cmis:name'])
-            titleElement.appendChild(titleText)
-            entryElement.appendChild(titleElement)
-
-        propsElement = entryXmlDoc.createElementNS(CMIS_NS, 'cmis:properties')
-        objectElement.appendChild(propsElement)
-
-        typeDef = None
-        for propName, propValue in properties.items():
-            """
-            the name of the element here is significant: it includes the
-            data type. I should be able to figure out the right type based
-            on the actual type of the object passed in.
-
-            I could do a lookup to the type definition, but that doesn't
-            seem worth the performance hit
-            """
-            if (propValue == None or (type(propValue) == list and propValue[0] == None)):
-                # grab the prop type from the typeDef
-                if (typeDef == None):
-                    moduleLogger.debug('Looking up type def for: %s' % objectTypeId)
-                    typeDef = repo.getTypeDefinition(objectTypeId)
-                    #TODO what to do if type not found
-                propType = typeDef.properties[propName].propertyType
-            elif type(propValue) == list:
-                propType = type(propValue[0])
-            else:
-                propType = type(propValue)
-
-            propElementName, propValueStrList = getElementNameAndValues(propType, propName, propValue, type(propValue) == list)
-
-            propElement = entryXmlDoc.createElementNS(CMIS_NS, propElementName)
-            propElement.setAttribute('propertyDefinitionId', propName)
-            for val in propValueStrList:
-                if val == None:
-                    continue
-                valElement = entryXmlDoc.createElementNS(CMIS_NS, 'cmis:value')
-                valText = entryXmlDoc.createTextNode(val)
-                valElement.appendChild(valText)
-                propElement.appendChild(valElement)
-            propsElement.appendChild(propElement)
-
-    return entryXmlDoc
-
-
-def getElementNameAndValues(propType, propName, propValue, isList=False):
-
-    """
-    For a given property type, property name, and property value, this function
-    returns the appropriate CMIS Atom entry element name and value list.
-    """
-
-    moduleLogger.debug('Inside getElementNameAndValues')
-    moduleLogger.debug('propType:%s propName:%s isList:%s' % (propType, propName, isList))
-    if (propType == 'id' or propType == CmisId):
-        propElementName = 'cmis:propertyId'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                propValueStrList.append(val)
-        else:
-            propValueStrList = [propValue]
-    elif (propType == 'string' or propType == str):
-        propElementName = 'cmis:propertyString'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                propValueStrList.append(val)
-        else:
-            propValueStrList = [propValue]
-    elif (propType == 'datetime' or propType == datetime.datetime):
-        propElementName = 'cmis:propertyDateTime'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                if val != None:
-                    propValueStrList.append(val.isoformat())
-                else:
-                    propValueStrList.append(val)
-        else:
-            if propValue != None:
-                propValueStrList = [propValue.isoformat()]
-            else:
-                propValueStrList = [propValue]
-    elif (propType == 'boolean' or propType == bool):
-        propElementName = 'cmis:propertyBoolean'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                if val != None:
-                    propValueStrList.append(unicode(val).lower())
-                else:
-                    propValueStrList.append(val)
-        else:
-            if propValue != None:
-                propValueStrList = [unicode(propValue).lower()]
-            else:
-                propValueStrList = [propValue]
-    elif (propType == 'integer' or propType == int):
-        propElementName = 'cmis:propertyInteger'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                if val != None:
-                    propValueStrList.append(unicode(val))
-                else:
-                    propValueStrList.append(val)
-        else:
-            if propValue != None:
-                propValueStrList = [unicode(propValue)]
-            else:
-                propValueStrList = [propValue]
-    elif (propType == 'decimal' or propType == float):
-        propElementName = 'cmis:propertyDecimal'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                if val != None:
-                    propValueStrList.append(unicode(val))
-                else:
-                    propValueStrList.append(val)
-        else:
-            if propValue != None:
-                propValueStrList = [unicode(propValue)]
-            else:
-                propValueStrList = [propValue]
-    else:
-        propElementName = 'cmis:propertyString'
-        if isList:
-            propValueStrList = []
-            for val in propValue:
-                if val != None:
-                    propValueStrList.append(unicode(val))
-                else:
-                    propValueStrList.append(val)
-        else:
-            if propValue != None:
-                propValueStrList = [unicode(propValue)]
-            else:
-                propValueStrList = [propValue]
-
-    return propElementName, propValueStrList
diff --git a/src/cmislib/util.py b/src/cmislib/util.py
new file mode 100644
index 0000000..b85e6f5
--- /dev/null
+++ b/src/cmislib/util.py
@@ -0,0 +1,111 @@
+#
+#      Licensed to the Apache Software Foundation (ASF) under one
+#      or more contributor license agreements.  See the NOTICE file
+#      distributed with this work for additional information
+#      regarding copyright ownership.  The ASF licenses this file
+#      to you 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.
+#
+"""
+Module containing handy utility functions.
+"""
+import re
+import iso8601
+import logging
+from cmislib.domain import CmisId, Document, Folder
+
+moduleLogger = logging.getLogger('cmislib.util')
+
+def multiple_replace(aDict, text):
+
+    """
+    Replace in 'text' all occurences of any key in the given
+    dictionary by its corresponding value.  Returns the new string.
+
+    See http://code.activestate.com/recipes/81330/
+    """
+
+    # Create a regular expression  from the dictionary keys
+    regex = re.compile("(%s)" % "|".join(map(re.escape, aDict.keys())))
+
+    # For each match, look-up corresponding value in dictionary
+    return regex.sub(lambda mo: aDict[mo.string[mo.start():mo.end()]], text)
+
+def parsePropValue(value, nodeName):
+
+    """
+    Returns a properly-typed object based on the type as specified in the
+    node's element name.
+    """
+
+    moduleLogger.debug('Inside parsePropValue')
+
+    if nodeName == 'propertyId':
+        return CmisId(value)
+    elif nodeName == 'propertyString':
+        return value
+    elif nodeName == 'propertyBoolean':
+        bDict = {'false': False, 'true': True}
+        return bDict[value.lower()]
+    elif nodeName == 'propertyInteger':
+        return int(value)
+    elif nodeName == 'propertyDecimal':
+        return float(value)
+    elif nodeName == 'propertyDateTime':
+        #%z doesn't seem to work, so I'm going to trunc the offset
+        #not all servers return microseconds, so those go too
+        return parseDateTimeValue(value)
+    else:
+        return value
+
+
+def parseDateTimeValue(value):
+
+    """
+    Utility function to return a datetime from a string.
+    """
+    return iso8601.parse_date(value)
+
+
+def parseBoolValue(value):
+
+    """
+    Utility function to parse booleans and none from strings
+    """
+
+    if value == 'false':
+        return False
+    elif value == 'true':
+        return True
+    elif value == 'none':
+        return None
+    else:
+        return value
+
+
+def toCMISValue(value):
+
+    """
+    Utility function to convert Python values to CMIS string values
+    """
+
+    if value == False:
+        return 'false'
+    elif value == True:
+        return 'true'
+    elif value == None:
+        return 'none'
+    else:
+        return value
+
+
diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py
index 69a64e4..f99e5e4 100644
--- a/src/tests/cmislibtest.py
+++ b/src/tests/cmislibtest.py
@@ -23,7 +23,8 @@
 '''
 import unittest
 from unittest import TestSuite, TestLoader
-from cmislib.model import CmisClient, ACE
+from cmislib.model import CmisClient
+from cmislib.domain import ACE
 from cmislib.exceptions import \
                           ObjectNotFoundException, \
                           CmisException, \
@@ -1408,8 +1409,8 @@
         if not self._repo.getSupportedPermissions() in ['both', 'basic']:
             print 'Repository needs to support either both or basic permissions for this test'
             return
-        acl = self._testFolder.getACL()
-        acl.addEntry(ACE(settings.TEST_PRINCIPAL_ID, 'cmis:write', 'true'))
+        acl = self._testFolder.getACL()        
+        acl.addEntry(settings.TEST_PRINCIPAL_ID, 'cmis:write', 'true')
         acl = self._testFolder.applyACL(acl)
         # would be good to check that the permission we get back is what we set
         # but at least one server (Alf) appears to map the basic perm to a
diff --git a/src/tests/settings.py b/src/tests/settings.py
index 423886e..c70d009 100644
--- a/src/tests/settings.py
+++ b/src/tests/settings.py
@@ -22,8 +22,8 @@
 #
 # CMIS repository's service URL
 #REPOSITORY_URL = 'http://cmis.alfresco.com/s/cmis' # Alfresco demo
-#REPOSITORY_URL = 'http://localhost:8080/chemistry/atom' # Apache Chemistry
-REPOSITORY_URL = 'http://localhost:8080/alfresco/cmisatom'  # Alfresco 4.0
+REPOSITORY_URL = 'http://localhost:8080/chemistry/atom' # Apache Chemistry
+#REPOSITORY_URL = 'http://localhost:8080/alfresco/cmisatom'  # Alfresco 4.0
 #REPOSITORY_URL = 'http://localhost:8080/alfresco/s/api/cmis'  # Alfresco
 #REPOSITORY_URL = 'http://cmis.demo.nuxeo.org/nuxeo/atom/cmis' # Nuxeo demo
 #REPOSITORY_URL = 'http://localhost:8080/nuxeo/atom/cmis' # Nuxeo local
