diff --git a/lib/cmis_repository_wrapper.php b/lib/cmis_repository_wrapper.php
deleted file mode 100644
index c2a6d27..0000000
--- a/lib/cmis_repository_wrapper.php
+++ /dev/null
@@ -1,1355 +0,0 @@
-<?php
-# 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.
-
-define("HTTP_OK", 200);
-define("HTTP_CREATED", 201);
-define("HTTP_ACCEPTED", 202);
-define("HTTP_NONAUTHORITATIVE_INFORMATION", 203);
-define("HTTP_NO_CONTENT", 204);
-define("HTTP_RESET_CONTENT", 205);
-define("HTTP_PARTIAL_CONTENT", 206);
-define("HTTP_MULTIPLE_CHOICES", 300);
-define("HTTP_BAD_REQUEST", 400); // invalidArgument, filterNotValid
-define("HTTP_UNAUTHORIZED", 401);
-define("HTTP_FORBIDDEN", 403); // permissionDenied, streamNotSupported
-define("HTTP_NOT_FOUND", 404); // objectNotFound
-define("HTTP_METHOD_NOT_ALLOWED", 405); // notSupported
-define("HTTP_NOT_ACCEPTABLE", 406);
-define("HTTP_PROXY_AUTHENTICATION_REQUIRED", 407);
-define("xHTTP_REQUEST_TIMEOUT", 408); //Had to change this b/c HTTP_REQUEST_TIMEOUT conflicts with definition in Drupal 7
-define("HTTP_CONFLICT", 409); // constraint, contentAlreadyExists, versioning, updateConflict, nameConstraintViolation
-define("HTTP_UNSUPPORTED_MEDIA_TYPE", 415);
-define("HTTP_UNPROCESSABLE_ENTITY", 422);
-define("HTTP_INTERNAL_SERVER_ERROR", 500); // runtime, storage
-
-class CmisInvalidArgumentException extends Exception {}
-class CmisObjectNotFoundException extends Exception {}
-class CmisPermissionDeniedException extends Exception {}
-class CmisNotSupportedException extends Exception {}
-class CmisConstraintException extends Exception {}
-class CmisRuntimeException extends Exception {}
-
-class CMISRepositoryWrapper
-{
-    // Handles --
-    //   Workspace -- but only endpoints with a single repo
-    //   Entry -- but only for objects
-    //   Feeds -- but only for non-hierarchical feeds
-    // Does not handle --
-    //   -- Hierarchical Feeds
-    //   -- Types
-    //   -- Others?
-    // Only Handles Basic Auth
-    // Very Little Error Checking
-    // Does not work against pre CMIS 1.0 Repos
-    
-    var $url;
-    var $username;
-    var $password;
-    var $authenticated;
-    var $workspace;
-    var $last_request;
-    var $do_not_urlencode;
-    protected $_addlCurlOptions = array();
-    
-    static $namespaces = array (
-        "cmis" => "http://docs.oasis-open.org/ns/cmis/core/200908/",
-        "cmisra" => "http://docs.oasis-open.org/ns/cmis/restatom/200908/",
-        "atom" => "http://www.w3.org/2005/Atom",
-        "app" => "http://www.w3.org/2007/app",
-        
-    );
-
-    function __construct($url, $username = null, $password = null, $options = null, array $addlCurlOptions = array())
-    {
-        if (is_array($options) && $options["config:do_not_urlencode"]) {
-            $this->do_not_urlencode=true;
-        }
-        $this->_addlCurlOptions = $addlCurlOptions; // additional cURL options
-        
-        $this->connect($url, $username, $password, $options);
-    }
-
-    static function getOpUrl($url, $options = null)
-    {
-        if (is_array($options) && (count($options) > 0))
-        {
-            $needs_question = strstr($url, "?") === false;
-            return $url . ($needs_question ? "?" : "&") . http_build_query($options);
-        } else
-        {
-            return $url;
-        }
-    }
-    
-    function convertStatusCode($code, $message)
-    {
-        switch ($code) {
-            case HTTP_BAD_REQUEST:
-                return new CmisInvalidArgumentException($message, $code);
-            case HTTP_NOT_FOUND:
-                return new CmisObjectNotFoundException($message, $code);
-            case HTTP_FORBIDDEN:
-                return new CmisPermissionDeniedException($message, $code);
-            case HTTP_METHOD_NOT_ALLOWED:
-                return new CmisNotSupportedException($message, $code);
-            case HTTP_CONFLICT:
-                return new CmisConstraintException($message, $code);
-            default:
-                return new CmisRuntimeException($message, $code);
-            }
-    }
-
-    function connect($url, $username, $password, $options)
-    {
-        // TODO: Make this work with cookies
-        $this->url = $url;
-        $this->username = $username;
-        $this->password = $password;
-        $this->auth_options = $options;
-        $this->authenticated = false;
-        $retval = $this->doGet($this->url);
-        if ($retval->code == HTTP_OK || $retval->code == HTTP_CREATED)
-        {
-            $this->authenticated = true;
-            $this->workspace = CMISRepositoryWrapper :: extractWorkspace($retval->body);
-        }
-    }
-
-    function doGet($url)
-    {
-        $retval = $this->doRequest($url);
-        if ($retval->code != HTTP_OK)
-        {
-            throw $this->convertStatusCode($retval->code, $retval->body);
-        }
-        return $retval;
-    }
-
-    function doDelete($url)
-    {
-        $retval = $this->doRequest($url, "DELETE");
-        if ($retval->code != HTTP_NO_CONTENT)
-        {
-            throw $this->convertStatusCode($retval->code, $retval->body);
-        }
-        return $retval;
-    }
-
-    function doPost($url, $content, $contentType, $charset = null)
-    {
-        $retval = $this->doRequest($url, "POST", $content, $contentType);
-        if ($retval->code != HTTP_CREATED)
-        {
-            throw $this->convertStatusCode($retval->code, $retval->body);
-        }
-        return $retval;
-    }
-
-    function doPut($url, $content, $contentType, $charset = null)
-    {
-        $retval = $this->doRequest($url, "PUT", $content, $contentType);
-        if (($retval->code < HTTP_OK) || ($retval->code >= HTTP_MULTIPLE_CHOICES))
-        {
-            throw $this->convertStatusCode($retval->code, $retval->body);
-        }
-        return $retval;
-    }
-
-    function doRequest($url, $method = "GET", $content = null, $contentType = null, $charset = null)
-    {
-        // Process the HTTP request
-        // 'til now only the GET request has been tested
-        // Does not URL encode any inputs yet
-        if (is_array($this->auth_options))
-        {
-            $url = CMISRepositoryWrapper :: getOpUrl($url, $this->auth_options);
-        }
-        $session = curl_init($url);
-        curl_setopt($session, CURLOPT_HEADER, false);
-        curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
-        if ($this->username)
-        {
-            curl_setopt($session, CURLOPT_USERPWD, $this->username . ":" . $this->password);
-        }
-        curl_setopt($session, CURLOPT_CUSTOMREQUEST, $method);
-        if ($contentType)
-        {
-            curl_setopt($session, CURLOPT_HTTPHEADER, array (
-                "Content-Type: " . $contentType
-            ));
-        }
-        if ($content)
-        {
-            curl_setopt($session, CURLOPT_POSTFIELDS, $content);
-        }
-        if ($method == "POST")
-        {
-            curl_setopt($session, CURLOPT_POST, true);
-        }
-        
-        // apply addl. cURL options
-        // WARNING: this may override previously set options
-        if (count($this->_addlCurlOptions)) {
-            foreach ($this->_addlCurlOptions as $key => $value) {
-                curl_setopt($session, $key, $value);
-            }
-        }
-        
-        
-        //TODO: Make this storage optional
-        $retval = new stdClass();
-        $retval->url = $url;
-        $retval->method = $method;
-        $retval->content_sent = $content;
-        $retval->content_type_sent = $contentType;
-        $retval->body = curl_exec($session);
-        $retval->code = curl_getinfo($session, CURLINFO_HTTP_CODE);
-        $retval->content_type = curl_getinfo($session, CURLINFO_CONTENT_TYPE);
-        $retval->content_length = curl_getinfo($session, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
-        curl_close($session);
-        $this->last_request = $retval;
-        return $retval;
-    }
-
-    function getLastRequest()
-    {
-        return $this->last_request;
-    }
-
-    function getLastRequestBody()
-    {
-        return $this->last_request->body;
-    }
-
-    function getLastRequestCode()
-    {
-        return $this->last_request->code;
-    }
-
-    function getLastRequestContentType()
-    {
-        return $this->last_request->content_type;
-    }
-
-    function getLastRequestContentLength()
-    {
-        return $this->last_request->content_length;
-    }
-
-    function getLastRequestURL()
-    {
-        return $this->last_request->url;
-    }
-
-    function getLastRequestMethod()
-    {
-        return $this->last_request->method;
-    }
-
-    function getLastRequestContentTypeSent()
-    {
-        return $this->last_request->content_type_sent;
-    }
-
-    function getLastRequestContentSent()
-    {
-        return $this->last_request->content_sent;
-    }
-
-    // Static Utility Functions
-    static function processTemplate($template, $values = array ())
-    {
-        // Fill in the blanks -- 
-        $retval = $template;
-        if (is_array($values))
-        {
-            foreach ($values as $name => $value)
-            {
-                $retval = str_replace("{" . $name . "}", $value, $retval);
-            }
-        }
-        // Fill in any unpoupated variables with ""
-        return preg_replace("/{[a-zA-Z0-9_]+}/", "", $retval);
-
-    }
-
-    static function doXQuery($xmldata, $xquery)
-    {
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: doXQueryFromNode($doc, $xquery);
-    }
-
-    static function doXQueryFromNode($xmlnode, $xquery)
-    {
-        // Perform an XQUERY on a NODE
-        // Register the 4 CMIS namespaces
-        //THis may be a hopeless HACK!
-        //TODO: Review
-        if (!($xmlnode instanceof DOMDocument)) {
-            $xdoc=new DOMDocument();
-            $xnode = $xdoc->importNode($xmlnode,true);
-            $xdoc->appendChild($xnode);
-            $xpath = new DomXPath($xdoc);
-        } else {
-        	$xpath = new DomXPath($xmlnode);
-        }
-        foreach (CMISRepositoryWrapper :: $namespaces as $nspre => $nsuri)
-        {
-            $xpath->registerNamespace($nspre, $nsuri);
-        }
-        return $xpath->query($xquery);
-
-    }
-    static function getLinksArray($xmlnode)
-    {
-        // Gets the links of an object or a workspace
-        // Distinguishes between the two "down" links
-        //  -- the children link is put into the associative array with the "down" index
-        //  -- the descendants link is put into the associative array with the "down-tree" index
-        //  These links are distinquished by the mime type attribute, but these are probably the only two links that share the same rel ..
-        //    so this was done as a one off
-        $links = array ();
-        $link_nodes = $xmlnode->getElementsByTagName("link");
-        foreach ($link_nodes as $ln)
-        {
-            if ($ln->attributes->getNamedItem("rel")->nodeValue == "down" && $ln->attributes->getNamedItem("type")->nodeValue == "application/cmistree+xml")
-            {
-                //Descendents and Childredn share same "rel" but different document type
-                $links["down-tree"] = $ln->attributes->getNamedItem("href")->nodeValue;
-            } else
-            {
-                $links[$ln->attributes->getNamedItem("rel")->nodeValue] = $ln->attributes->getNamedItem("href")->nodeValue;
-            }
-        }
-        return $links;
-    }
-	static function extractAllowableActions($xmldata)
-    {
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: extractAllowableActionsFromNode($doc);
-    }
-    static function extractAllowableActionsFromNode($xmlnode)
-    {
-        $result = array();
-        $allowableActions = $xmlnode->getElementsByTagName("allowableActions");
-        if ($allowableActions->length > 0) {
-            foreach($allowableActions->item(0)->childNodes as $action)
-            {
-                if (isset($action->localName)) {
-                    $result[$action->localName] = (preg_match("/^true$/i", $action->nodeValue) > 0);
-                }
-            }
-        }
-        return $result;
-    }
-    static function extractObject($xmldata)
-    {
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: extractObjectFromNode($doc);
-
-    }
-    static function extractObjectFromNode($xmlnode)
-    {
-        // Extracts the contents of an Object and organizes them into:
-        //  -- Links
-        //  -- Properties
-        //  -- the Object ID
-        // RRM -- NEED TO ADD ALLOWABLEACTIONS
-        $retval = new stdClass();
-        $retval->links = CMISRepositoryWrapper :: getLinksArray($xmlnode);
-        $retval->properties = array ();
-        $prop_nodes = $xmlnode->getElementsByTagName("object")->item(0)->getElementsByTagName("properties")->item(0)->childNodes;
-        foreach ($prop_nodes as $pn)
-        {
-            if ($pn->attributes)
-            {
-                $propDefId = $pn->attributes->getNamedItem("propertyDefinitionId");
-                // TODO: Maybe use ->length=0 to even detect null values
-                if (!is_null($propDefId) && $pn->getElementsByTagName("value") && $pn->getElementsByTagName("value")->item(0))
-                {
-                	if ($pn->getElementsByTagName("value")->length > 1) {
-                		$retval->properties[$propDefId->nodeValue] = array();
-                		for ($idx=0;$idx < $pn->getElementsByTagName("value")->length;$idx++) {
-                			$retval->properties[$propDefId->nodeValue][$idx] = $pn->getElementsByTagName("value")->item($idx)->nodeValue;
-                		}
-                	} else {
-                		$retval->properties[$propDefId->nodeValue] = $pn->getElementsByTagName("value")->item(0)->nodeValue;
-                	}
-                }
-            }
-        }
-        $retval->uuid = $xmlnode->getElementsByTagName("id")->item(0)->nodeValue;
-        $retval->id = $retval->properties["cmis:objectId"];
-        //TODO: RRM FIX THIS
-        $children_node = $xmlnode->getElementsByTagName("children");
-        if (is_object($children_node)) {
-        	    $children_feed_c = $children_node->item(0);
-        }
-        if (is_object($children_feed_c)) {
-			$children_feed_l = $children_feed_c->getElementsByTagName("feed");
-        }
-        if (isset($children_feed_l) && is_object($children_feed_l) && is_object($children_feed_l->item(0))) {
-        	$children_feed = $children_feed_l->item(0);
-			$children_doc = new DOMDocument();
-			$xnode = $children_doc->importNode($children_feed,true); // Avoid Wrong Document Error
-			$children_doc->appendChild($xnode);
-	        $retval->children = CMISRepositoryWrapper :: extractObjectFeedFromNode($children_doc);
-        }
-		$retval->allowableActions = CMISRepositoryWrapper :: extractAllowableActionsFromNode($xmlnode);
-        return $retval;
-    }
-    
-    function handleSpaces($path)
-    {
-        return $this->do_not_urlencode ? $path : rawurlencode($path);
-    }
-
-    static function extractTypeDef($xmldata)
-    {
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: extractTypeDefFromNode($doc);
-
-    }
-    static function extractTypeDefFromNode($xmlnode)
-    {
-        // Extracts the contents of an Object and organizes them into:
-        //  -- Links
-        //  -- Properties
-        //  -- the Object ID
-        // RRM -- NEED TO ADD ALLOWABLEACTIONS
-        $retval = new stdClass();
-        $retval->links = CMISRepositoryWrapper :: getLinksArray($xmlnode);
-        $retval->properties = array ();
-        $retval->attributes = array ();
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmisra:type/*");
-        foreach ($result as $node)
-        {
-            if ((substr($node->nodeName, 0, 13) == "cmis:property") && (substr($node->nodeName, -10) == "Definition"))
-            {
-                $id = $node->getElementsByTagName("id")->item(0)->nodeValue;
-                $cardinality = $node->getElementsByTagName("cardinality")->item(0)->nodeValue;
-                $propertyType = $node->getElementsByTagName("propertyType")->item(0)->nodeValue;
-                // Stop Gap for now
-                $retval->properties[$id] = array (
-                    "cmis:propertyType" => $propertyType,
-                    "cmis:cardinality" => $cardinality,
-                    
-                );
-            } else
-            {
-                $retval->attributes[$node->nodeName] = $node->nodeValue;
-            }
-            $retval->id = $retval->attributes["cmis:id"];
-        }
-        //TODO: RRM FIX THIS
-        $children_node = $xmlnode->getElementsByTagName("children");
-        if (is_object($children_node)) {
-        	    $children_feed_c = $children_node->item(0);
-        }
-        if (is_object($children_feed_c)) {
-			$children_feed_l = $children_feed_c->getElementsByTagName("feed");
-        }
-        if (is_object($children_feed_l) && is_object($children_feed_l->item(0))) {
-        	$children_feed = $children_feed_l->item(0);
-			$children_doc = new DOMDocument();
-			$xnode = $children_doc->importNode($children_feed,true); // Avoid Wrong Document Error
-			$children_doc->appendChild($xnode);
-	        $retval->children = CMISRepositoryWrapper :: extractTypeFeedFromNode($children_doc);
-        }
-
-        /*
-         * 
-        
-        
-        
-        		$prop_nodes = $xmlnode->getElementsByTagName("object")->item(0)->getElementsByTagName("properties")->item(0)->childNodes;
-        		foreach ($prop_nodes as $pn) {
-        			if ($pn->attributes) {
-        				$retval->properties[$pn->attributes->getNamedItem("propertyDefinitionId")->nodeValue] = $pn->getElementsByTagName("value")->item(0)->nodeValue;
-        			}
-        		}
-                $retval->uuid=$xmlnode->getElementsByTagName("id")->item(0)->nodeValue;
-                $retval->id=$retval->properties["cmis:objectId"];
-         */
-        return $retval;
-    }
-
-    static function extractObjectFeed($xmldata)
-    {
-        //Assumes only one workspace for now
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: extractObjectFeedFromNode($doc);
-    }
-    static function extractObjectFeedFromNode($xmlnode)
-    {
-        // Process a feed and extract the objects
-        //   Does not handle hierarchy
-        //   Provides two arrays 
-        //   -- one sequential array (a list)
-        //   -- one hash table indexed by objectID
-        //   and a property "numItems" that holds the total number of items available.
-        $retval = new stdClass();
-        // extract total number of items
-        $numItemsNode = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "/atom:feed/cmisra:numItems");
-        $retval->numItems = $numItemsNode->length ? (int) $numItemsNode->item(0)->nodeValue : -1; // set to negative value if info is not available
-                
-        $retval->objectList = array ();
-        $retval->objectsById = array ();
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "/atom:feed/atom:entry");
-        foreach ($result as $node)
-        {
-            $obj = CMISRepositoryWrapper :: extractObjectFromNode($node);
-            $retval->objectsById[$obj->id] = $obj;
-            $retval->objectList[] = & $retval->objectsById[$obj->id];
-        }
-        return $retval;
-    }
-
-    static function extractTypeFeed($xmldata)
-    {
-        //Assumes only one workspace for now
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: extractTypeFeedFromNode($doc);
-    }
-    static function extractTypeFeedFromNode($xmlnode)
-    {
-        // Process a feed and extract the objects
-        //   Does not handle hierarchy
-        //   Provides two arrays 
-        //   -- one sequential array (a list)
-        //   -- one hash table indexed by objectID
-        $retval = new stdClass();
-        $retval->objectList = array ();
-        $retval->objectsById = array ();
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "/atom:feed/atom:entry");
-        foreach ($result as $node)
-        {
-            $obj = CMISRepositoryWrapper :: extractTypeDefFromNode($node);
-            $retval->objectsById[$obj->id] = $obj;
-            $retval->objectList[] = & $retval->objectsById[$obj->id];
-        }
-        return $retval;
-    }
-
-    static function extractWorkspace($xmldata)
-    {
-        //Assumes only one workspace for now
-        $doc = new DOMDocument();
-        $doc->loadXML($xmldata);
-        return CMISRepositoryWrapper :: extractWorkspaceFromNode($doc);
-    }
-    static function extractWorkspaceFromNode($xmlnode)
-    {
-        // Assumes only one workspace for now
-        // Load up the workspace object with arrays of
-        //  links
-        //  URI Templates
-        //  Collections
-        //  Capabilities
-        //  General Repository Information
-        $retval = new stdClass();
-        $retval->links = CMISRepositoryWrapper :: getLinksArray($xmlnode);
-        $retval->uritemplates = array ();
-        $retval->collections = array ();
-        $retval->capabilities = array ();
-        $retval->repositoryInfo = array ();
-        $retval->permissions = array();
-        $retval->permissionsMapping = array();
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmisra:uritemplate");
-        foreach ($result as $node)
-        {
-            $retval->uritemplates[$node->getElementsByTagName("type")->item(0)->nodeValue] = $node->getElementsByTagName("template")->item(0)->nodeValue;
-        }
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//app:collection");
-        foreach ($result as $node)
-        {
-            $retval->collections[$node->getElementsByTagName("collectionType")->item(0)->nodeValue] = $node->attributes->getNamedItem("href")->nodeValue;
-        }
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:capabilities/*");
-        foreach ($result as $node)
-        {
-            $retval->capabilities[$node->nodeName] = $node->nodeValue;
-        }
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmisra:repositoryInfo/*[name()!='cmis:capabilities' and name()!='cmis:aclCapability']");
-        foreach ($result as $node)
-        {
-            $retval->repositoryInfo[$node->nodeName] = $node->nodeValue;
-        }
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:aclCapability/cmis:permissions");
-        foreach ($result as $node)
-        {
-            $retval->permissions[$node->getElementsByTagName("permission")->item(0)->nodeValue] = $node->getElementsByTagName("description")->item(0)->nodeValue;
-        }
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:aclCapability/cmis:mapping");
-        foreach ($result as $node)
-        {
-            $key = $node->getElementsByTagName("key")->item(0)->nodeValue;
-            $values = array();
-            foreach ($node->getElementsByTagName("permission") as $value)
-            {
-                array_push($values, $value->nodeValue);
-            }
-            $retval->permissionsMapping[$key] = $values;
-        }
-        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:aclCapability/*[name()!='cmis:permissions' and name()!='cmis:mapping']");
-        foreach ($result as $node)
-        {
-            $retval->repositoryInfo[$node->nodeName] = $node->nodeValue;
-        }
-
-        return $retval;
-    }
-}
-
-// Option Contants for Array Indexing
-// -- Generally optional flags that control how much information is returned
-// -- Change log token is an anomoly -- but included in URL as parameter
-define("OPT_MAX_ITEMS", "maxItems");
-define("OPT_SKIP_COUNT", "skipCount");
-define("OPT_FILTER", "filter");
-define("OPT_INCLUDE_PROPERTY_DEFINITIONS", "includePropertyDefinitions");
-define("OPT_INCLUDE_RELATIONSHIPS", "includeRelationships");
-define("OPT_INCLUDE_POLICY_IDS", "includePolicyIds");
-define("OPT_RENDITION_FILTER", "renditionFilter");
-define("OPT_INCLUDE_ACL", "includeACL");
-define("OPT_INCLUDE_ALLOWABLE_ACTIONS", "includeAllowableActions");
-define("OPT_DEPTH", "depth");
-define("OPT_CHANGE_LOG_TOKEN", "changeLogToken");
-
-define("LINK_ALLOWABLE_ACTIONS", "http://docs.oasis-open.org/ns/cmis/link/200908/allowableactions");
-
-define("MIME_ATOM_XML", 'application/atom+xml');
-define("MIME_ATOM_XML_ENTRY", 'application/atom+xml;type=entry');
-define("MIME_ATOM_XML_FEED", 'application/atom+xml;type=feed');
-define("MIME_CMIS_TREE", 'application/cmistree+xml');
-define("MIME_CMIS_QUERY", 'application/cmisquery+xml');
-
-// Many Links have a pattern to them based upon objectId -- but can that be depended upon?
-
-class CMISService extends CMISRepositoryWrapper
-{
-    var $_link_cache;
-    var $_title_cache;
-    var $_objTypeId_cache;
-    var $_type_cache;
-    function __construct($url, $username, $password, $options = null, array $addlCurlOptions = array())
-    {
-        parent :: __construct($url, $username, $password, $options, $addlCurlOptions);
-        $this->_link_cache = array ();
-        $this->_title_cache = array ();
-        $this->_objTypeId_cache = array ();
-        $this->_type_cache = array ();
-    }
-
-    // Utility Methods -- Added Titles
-    // Should refactor to allow for single object	
-    function cacheObjectInfo($obj)
-    {
-        $this->_link_cache[$obj->id] = $obj->links;
-        $this->_title_cache[$obj->id] = $obj->properties["cmis:name"]; // Broad Assumption Here?
-        $this->_objTypeId_cache[$obj->id] = $obj->properties["cmis:objectTypeId"];
-    }
-
-    function cacheFeedInfo($objs)
-    {
-        foreach ($objs->objectList as $obj)
-        {
-            $this->cacheObjectInfo($obj);
-        }
-    }
-
-    function cacheTypeFeedInfo($typs)
-    {
-        foreach ($typs->objectList as $typ)
-        {
-            $this->cacheTypeInfo($typ);
-        }
-    }
-
-    function cacheTypeInfo($tDef)
-    {
-        // TODO: Fix Type Caching with missing properties
-        $this->_type_cache[$tDef->id] = $tDef;
-    }
-
-    function getPropertyType($typeId, $propertyId)
-    {
-        if ($this->_type_cache[$typeId]->properties)
-        {
-            return $this->_type_cache[$typeId]->properties[$propertyId]["cmis:propertyType"];
-        }
-        $obj = $this->getTypeDefinition($typeId);
-        return $obj->properties[$propertyId]["cmis:propertyType"];
-    }
-
-    function getObjectType($objectId)
-    {
-        if ($this->_objTypeId_cache[$objectId])
-        {
-            return $this->_objTypeId_cache[$objectId];
-        }
-        $obj = $this->getObject($objectId);
-        return $obj->properties["cmis:objectTypeId"];
-    }
-
-    function getTitle($objectId)
-    {
-        if ($this->_title_cache[$objectId])
-        {
-            return $this->_title_cache[$objectId];
-        }
-        $obj = $this->getObject($objectId);
-        return $obj->properties["cmis:name"];
-    }
-
-    function getTypeLink($typeId, $linkName)
-    {
-        if ($this->_type_cache[$typeId]->links)
-        {
-            return $this->_type_cache[$typeId]->links[$linkName];
-        }
-        $typ = $this->getTypeDefinition($typeId);
-        return $typ->links[$linkName];
-    }
-
-    function getLink($objectId, $linkName)
-    {
-        if ($this->_link_cache[$objectId][$linkName])
-        {
-            return $this->_link_cache[$objectId][$linkName];
-        }
-        $obj = $this->getObject($objectId);
-        return $obj->links[$linkName];
-    }
-
-    // Repository Services
-    function getRepositories()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function getRepositoryInfo()
-    {
-        return $this->workspace;
-    }
-
-    function getTypeDescendants($typeId=null, $depth, $options = array ())
-    {
-    	// TODO: Refactor Type Entries Caching
-        $varmap = $options;
-        if ($typeId) {
-	        $hash_values = $options;
-	        $hash_values['depth'] = $depth;
-	        $myURL = $this->getTypeLink($typeId, "down-tree");
-	        $myURL = CMISRepositoryWrapper :: getOpUrl ($myURL, $hash_values);
-        } else {
-        	$myURL = $this->processTemplate($this->workspace->collections['http://docs.oasis-open.org/ns/cmis/link/200908/typedescendants'], $varmap);       	
-        }
-        $ret = $this->doGet($myURL);
-        $typs = $this->extractTypeFeed($ret->body);
-        $this->cacheTypeFeedInfo($typs);
-        return $typs;
-    }
-
-    function getTypeChildren($typeId=null, $options = array ())
-    {
-    	// TODO: Refactor Type Entries Caching
-        $varmap = $options;
-        if ($typeId) {
-	        $myURL = $this->getTypeLink($typeId, "down");
-	        //TODO: Need GenURLQueryString Utility
-        } else {
-            //TODO: Need right URL
-        	$myURL = $this->processTemplate($this->workspace->collections['types'], $varmap);       	
-        }
-        $ret = $this->doGet($myURL);
-        $typs = $this->extractTypeFeed($ret->body);
-        $this->cacheTypeFeedInfo($typs);
-        return $typs;
-    }
-
-    function getTypeDefinition($typeId, $options = array ())
-    { // Nice to have
-        $varmap = $options;
-        $varmap["id"] = $typeId;
-        $myURL = $this->processTemplate($this->workspace->uritemplates['typebyid'], $varmap);
-        $ret = $this->doGet($myURL);
-        $obj = $this->extractTypeDef($ret->body);
-        $this->cacheTypeInfo($obj);
-        return $obj;
-    }
-
-    function getObjectTypeDefinition($objectId)
-    { // Nice to have
-        $myURL = $this->getLink($objectId, "describedby");
-        $ret = $this->doGet($myURL);
-        $obj = $this->extractTypeDef($ret->body);
-        $this->cacheTypeInfo($obj);
-        return $obj;
-    }
-    //Navigation Services
-    function getFolderTree($folderId, $depth, $options = array ())
-    {
-        $hash_values = $options;
-        $hash_values['depth'] = $depth;
-        $myURL = $this->getLink($folderId, "http://docs.oasis-open.org/ns/cmis/link/200908/foldertree");
-        $myURL = CMISRepositoryWrapper :: getOpUrl ($myURL, $hash_values);
-        $ret = $this->doGet($myURL);
-        $objs = $this->extractObjectFeed($ret->body);
-        $this->cacheFeedInfo($objs);
-        return $objs;
-    }
-
-    function getDescendants($folderId, $depth, $options = array ())
-    { // Nice to have
-        $hash_values = $options;
-        $hash_values['depth'] = $depth;
-        $myURL = $this->getLink($folderId, "down-tree");
-        $myURL = CMISRepositoryWrapper :: getOpUrl ($myURL, $hash_values);
-        $ret = $this->doGet($myURL);
-        $objs = $this->extractObjectFeed($ret->body);
-        $this->cacheFeedInfo($objs);
-        return $objs;
-    }
-
-    function getChildren($folderId, $options = array ())
-    {
-        $myURL = $this->getLink($folderId, "down");
-        //TODO: Need GenURLQueryString Utility
-        $ret = $this->doGet($myURL);
-        $objs = $this->extractObjectFeed($ret->body);
-        $this->cacheFeedInfo($objs);
-        return $objs;
-    }
-
-    function getFolderParent($folderId, $options = array ())
-    { //yes
-        $myURL = $this->getLink($folderId, "up");
-        //TODO: Need GenURLQueryString Utility
-        $ret = $this->doGet($myURL);
-        $obj = $this->extractObjectEntry($ret->body);
-        $this->cacheObjectInfo($obj);
-        return $obj;
-    }
-
-    function getObjectParents($objectId, $options = array ())
-    { // yes
-        $myURL = $this->getLink($objectId, "up");
-        //TODO: Need GenURLQueryString Utility
-        $ret = $this->doGet($myURL);
-        $objs = $this->extractObjectFeed($ret->body);
-        $this->cacheFeedInfo($objs);
-        return $objs;
-    }
-
-    function getCheckedOutDocs($options = array ())
-    {
-        $obj_url = $this->workspace->collections['checkedout'];
-        $ret = $this->doGet($obj_url);
-        $objs = $this->extractObjectFeed($ret->body);
-        $this->cacheFeedInfo($objs);
-        return $objs;
-    }
-
-    //Discovery Services
-
-    static function getQueryTemplate()
-    {
-        ob_start();
-        echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n";
-?>
-<cmis:query xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/"
-xmlns:cmism="http://docs.oasis-open.org/ns/cmis/messaging/200908/"
-xmlns:atom="http://www.w3.org/2005/Atom"
-xmlns:app="http://www.w3.org/2007/app"
-xmlns:cmisra="http://docs.oasisopen.org/ns/cmis/restatom/200908/">
-<cmis:statement>{q}</cmis:statement>
-<cmis:searchAllVersions>{searchAllVersions}</cmis:searchAllVersions>
-<cmis:includeAllowableActions>{includeAllowableActions}</cmis:includeAllowableActions>
-<cmis:includeRelationships>{includeRelationships}</cmis:includeRelationships>
-<cmis:renditionFilter>{renditionFilter}</cmis:renditionFilter>
-<cmis:maxItems>{maxItems}</cmis:maxItems>
-<cmis:skipCount>{skipCount}</cmis:skipCount>
-</cmis:query>
-<?php
-
-        return ob_get_clean();
-    }
-    function query($statement, $options = array ())
-    {
-        static $query_template;
-        if (!isset ($query_template))
-        {
-            $query_template = CMISService :: getQueryTemplate();
-        }
-        $hash_values = $options;
-        $hash_values['q'] = $statement;
-        $post_value = CMISRepositoryWrapper :: processTemplate($query_template, $hash_values);
-        $ret = $this->doPost($this->workspace->collections['query'], $post_value, MIME_CMIS_QUERY);
-        $objs = $this->extractObjectFeed($ret->body);
-        $this->cacheFeedInfo($objs);
-        return $objs;
-    }
-
-    function getContentChanges()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    //Object Services
-    static function getEntryTemplate()
-    {
-        ob_start();
-        echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n";
-?>
-<atom:entry xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/"
-xmlns:cmism="http://docs.oasis-open.org/ns/cmis/messaging/200908/"
-xmlns:atom="http://www.w3.org/2005/Atom"
-xmlns:app="http://www.w3.org/2007/app"
-xmlns:cmisra="http://docs.oasis-open.org/ns/cmis/restatom/200908/">
-<atom:title>{title}</atom:title>
-{SUMMARY}
-{CONTENT}
-<cmisra:object><cmis:properties>{PROPERTIES}</cmis:properties></cmisra:object>
-</atom:entry>
-<?php
-
-        return ob_get_clean();
-    }
-
-    static function getPropertyTemplate()
-    {
-        ob_start();
-?>
-		<cmis:property{propertyType} propertyDefinitionId="{propertyId}">
-			<cmis:value>{properties}</cmis:value>
-		</cmis:property{propertyType}>
-<?php
-
-        return ob_get_clean();
-    }
-
-    function processPropertyTemplates($objectType, $propMap)
-    {
-        static $propTemplate;
-        static $propertyTypeMap;
-        if (!isset ($propTemplate))
-        {
-            $propTemplate = CMISService :: getPropertyTemplate();
-        }
-        if (!isset ($propertyTypeMap))
-        { // Not sure if I need to do this like this
-            $propertyTypeMap = array (
-                "integer" => "Integer",
-                "boolean" => "Boolean",
-                "datetime" => "DateTime",
-                "decimal" => "Decimal",
-                "html" => "Html",
-                "id" => "Id",
-                "string" => "String",
-                "url" => "Url",
-                "xml" => "Xml",
-                
-            );
-        }
-        $propertyContent = "";
-        $hash_values = array ();
-        foreach ($propMap as $propId => $propValue)
-        {
-            $hash_values['propertyType'] = $propertyTypeMap[$this->getPropertyType($objectType, $propId)];
-            $hash_values['propertyId'] = $propId;
-            if (is_array($propValue))
-            {
-                $first_one = true;
-                $hash_values['properties'] = "";
-                foreach ($propValue as $val)
-                {
-                    //This is a bit of a hack
-                    if ($first_one)
-                    {
-                        $first_one = false;
-                    } else
-                    {
-                        $hash_values['properties'] .= "</cmis:value>\n<cmis:value>";
-                    }
-                    $hash_values['properties'] .= $val;
-                }
-            } else
-            {
-                $hash_values['properties'] = $propValue;
-            }
-            //echo "HASH:\n";
-            //print_r(array("template" =>$propTemplate, "Hash" => $hash_values));
-            $propertyContent .= CMISRepositoryWrapper :: processTemplate($propTemplate, $hash_values);
-        }
-        return $propertyContent;
-    }
-
-    static function getContentEntry($content, $content_type = "application/octet-stream")
-    {
-        static $contentTemplate;
-        if (!isset ($contentTemplate))
-        {
-            $contentTemplate = CMISService :: getContentTemplate();
-        }
-        if ($content)
-        {
-            return CMISRepositoryWrapper :: processTemplate($contentTemplate, array (
-                "content" => base64_encode($content
-            ), "content_type" => $content_type));
-        } else
-        {
-            return "";
-        }
-    }
-
-    static function getSummaryTemplate()
-    {
-        ob_start();
-?>
-		<atom:summary>{summary}</atom:summary>
-<?php
-
-        return ob_get_clean();
-    }
-
-    static function getContentTemplate()
-    {
-        ob_start();
-?>
-		<cmisra:content>
-			<cmisra:mediatype>
-				{content_type}
-			</cmisra:mediatype>
-			<cmisra:base64>
-				{content}
-			</cmisra:base64>
-		</cmisra:content>
-<?php
-
-        return ob_get_clean();
-    }
-    static function createAtomEntry($name, $properties)
-    {
-
-    }
-    function getObject($objectId, $options = array ())
-    {
-        $varmap = $options;
-        $varmap["id"] = $objectId;
-        $obj_url = $this->processTemplate($this->workspace->uritemplates['objectbyid'], $varmap);
-        $ret = $this->doGet($obj_url);
-        $obj = $this->extractObject($ret->body);
-        $this->cacheObjectInfo($obj);
-        return $obj;
-    }
-
-    function getObjectByPath($path, $options = array ())
-    {
-        $varmap = $options;
-        $varmap["path"] = $this->handleSpaces($path);
-        $obj_url = $this->processTemplate($this->workspace->uritemplates['objectbypath'], $varmap);
-        $ret = $this->doGet($obj_url);
-        $obj = $this->extractObject($ret->body);
-        $this->cacheObjectInfo($obj);
-        return $obj;
-    }
-
-    function getProperties($objectId, $options = array ())
-    {
-        // May need to set the options array default -- 
-        return $this->getObject($objectId, $options);
-    }
-
-    function getAllowableActions($objectId, $options = array ())
-    {
-        $myURL = $this->getLink($objectId, LINK_ALLOWABLE_ACTIONS);
-        $ret = $this->doGet($myURL);
-        $result = $this->extractAllowableActions($ret->body);
-        return $result;
-    }
-
-    function getRenditions($objectId, $options = array (
-        OPT_RENDITION_FILTER => "*"
-    ))
-    {
-        return getObject($objectId, $options);
-    }
-
-    function getContentStream($objectId, $options = array ())
-    { // Yes
-        $myURL = $this->getLink($objectId, "edit-media");
-        $ret = $this->doGet($myURL);
-        // doRequest stores the last request information in this object
-        return $ret->body;
-    }
-
-    function postObject($folderId, $objectName, $objectType, $properties = array (), $content = null, $content_type = "application/octet-stream", $options = array ())
-    { // Yes
-        $myURL = $this->getLink($folderId, "down");
-        // TODO: Need Proper Query String Handling
-        // Assumes that the 'down' link does not have a querystring in it
-        $myURL = CMISRepositoryWrapper :: getOpUrl($myURL, $options);
-        static $entry_template;
-        if (!isset ($entry_template))
-        {
-            $entry_template = CMISService :: getEntryTemplate();
-        }
-        if (is_array($properties))
-        {
-            $hash_values = $properties;
-        } else
-        {
-            $hash_values = array ();
-        }
-        if (!isset ($hash_values["cmis:objectTypeId"]))
-        {
-            $hash_values["cmis:objectTypeId"] = $objectType;
-        }
-        $properties_xml = $this->processPropertyTemplates($hash_values["cmis:objectTypeId"], $hash_values);
-        if (is_array($options))
-        {
-            $hash_values = $options;
-        } else
-        {
-            $hash_values = array ();
-        }
-        $hash_values["PROPERTIES"] = $properties_xml;
-        $hash_values["SUMMARY"] = CMISService :: getSummaryTemplate();
-        if ($content)
-        {
-            $hash_values["CONTENT"] = CMISService :: getContentEntry($content, $content_type);
-        }
-        if (!isset ($hash_values['title']))
-        {
-            $hash_values['title'] = $objectName;
-        }
-        if (!isset ($hash_values['summary']))
-        {
-            $hash_values['summary'] = $objectName;
-        }
-        $post_value = CMISRepositoryWrapper :: processTemplate($entry_template, $hash_values);
-        $ret = $this->doPost($myURL, $post_value, MIME_ATOM_XML_ENTRY);
-        // print "DO_POST\n";
-        // print_r($ret);
-        $obj = $this->extractObject($ret->body);
-        $this->cacheObjectInfo($obj);
-        return $obj;
-    }
-
-    function createDocument($folderId, $fileName, $properties = array (), $content = null, $content_type = "application/octet-stream", $options = array ())
-    { // Yes
-        return $this->postObject($folderId, $fileName, "cmis:document", $properties, $content, $content_type, $options);
-    }
-
-    function createDocumentFromSource()
-    { //Yes?
-        throw new CmisNotSupportedException("createDocumentFromSource is not supported by the AtomPub binding!");
-    }
-
-    function createFolder($folderId, $folderName, $properties = array (), $options = array ())
-    { // Yes
-        return $this->postObject($folderId, $folderName, "cmis:folder", $properties, null, null, $options);
-    }
-
-    function createRelationship()
-    { // Not in first Release
-        throw new Exception("Not Implemented");
-    }
-
-    function createPolicy()
-    { // Not in first Release
-        throw new Exception("Not Implemented");
-    }
-
-    function updateProperties($objectId, $properties = array (), $options = array ())
-    { // Yes
-        $varmap = $options;
-        $varmap["id"] = $objectId;
-        $objectName = $this->getTitle($objectId);
-        $objectType = $this->getObjectType($objectId);
-        $obj_url = $this->getLink($objectId, "edit");
-        $obj_url = CMISRepositoryWrapper :: getOpUrl($obj_url, $options);
-        static $entry_template;
-        if (!isset ($entry_template))
-        {
-            $entry_template = CMISService :: getEntryTemplate();
-        }
-        if (is_array($properties))
-        {
-            $hash_values = $properties;
-        } else
-        {
-            $hash_values = array ();
-        }
-        $properties_xml = $this->processPropertyTemplates($objectType, $hash_values);
-        if (is_array($options))
-        {
-            $hash_values = $options;
-        } else
-        {
-            $hash_values = array ();
-        }
-        $hash_values["PROPERTIES"] = $properties_xml;
-        $hash_values["SUMMARY"] = CMISService :: getSummaryTemplate();
-        if (!isset ($hash_values['title']))
-        {
-            $hash_values['title'] = $objectName;
-        }
-        if (!isset ($hash_values['summary']))
-        {
-            $hash_values['summary'] = $objectName;
-        }
-        $put_value = CMISRepositoryWrapper :: processTemplate($entry_template, $hash_values);
-	 	// print $put_value; // RRM DEBUG
-        $ret = $this->doPut($obj_url, $put_value, MIME_ATOM_XML_ENTRY);
-        $obj = $this->extractObject($ret->body);
-        $this->cacheObjectInfo($obj);
-        return $obj;
-    }
-
-    function moveObject($objectId, $targetFolderId, $sourceFolderId, $options = array ())
-    { //yes
-        $options['sourceFolderId'] = $sourceFolderId;
-        return $this->postObject($targetFolderId, $this->getTitle($objectId), $this->getObjectType($objectId), array (
-            "cmis:objectId" => $objectId
-        ), null, null, $options);
-    }
-
-    function deleteObject($objectId, $options = array ())
-    { //Yes
-        $varmap = $options;
-        $varmap["id"] = $objectId;
-        $obj_url = $this->getLink($objectId, "edit");
-        $ret = $this->doDelete($obj_url);
-        return;
-    }
-
-    function deleteTree()
-    { // Nice to have
-        throw new Exception("Not Implemented");
-    }
-
-    function setContentStream($objectId, $content, $content_type, $options = array ())
-    { //Yes
-        $myURL = $this->getLink($objectId, "edit-media");
-        $ret = $this->doPut($myURL, $content, $content_type);
-    }
-
-    function deleteContentStream($objectId, $options = array ())
-    { //yes
-        $myURL = $this->getLink($objectId, "edit-media");
-        $ret = $this->doDelete($myURL);
-        return;
-    }
-
-    //Versioning Services
-    function getPropertiesOfLatestVersion($objectId, $major =false, $options = array ())
-    {
-        return $this->getObjectOfLatestVersion($objectId, $major, $options);
-    }
-
-    function getObjectOfLatestVersion($objectId, $major = false, $options = array ())
-    {
-        return $this->getObject($objectId, $options); // Won't be able to handle major/minor distinction
-        // Need to add this -- "current-version"
-        /*
-         * Headers: CMIS-filter, CMIS-returnVersion (enumReturnVersion) 
-         * HTTP Arguments: filter, returnVersion 
-         * Enum returnVersion: This, Latest, Major
-         */
-    }
-
-    function getAllVersions()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function checkOut()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function checkIn()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function cancelCheckOut()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function deleteAllVersions()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    //Relationship Services
-    function getObjectRelationships()
-    {
-        // get stripped down version of object (for the links) and then get the relationships?
-        // Low priority -- can get all information when getting object
-        throw new Exception("Not Implemented");
-    }
-
-    //Multi-Filing Services
-    function addObjectToFolder()
-    { // Probably
-        throw new Exception("Not Implemented");
-    }
-
-    function removeObjectFromFolder()
-    { //Probably
-        throw new Exception("Not Implemented");
-    }
-
-    //Policy Services
-    function getAppliedPolicies()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function applyPolicy()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function removePolicy()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    //ACL Services
-    function getACL()
-    {
-        throw new Exception("Not Implemented");
-    }
-
-    function applyACL()
-    {
-        throw new Exception("Not Implemented");
-    }
-}
