You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2015/07/20 10:48:59 UTC

svn commit: r1691890 [3/14] - in /chemistry/portcmis: ./ PortCMIS/ PortCMIS/Properties/ PortCMIS/binding/ PortCMIS/binding/atompub/ PortCMIS/binding/browser/ PortCMIS/binding/browser/json/ PortCMIS/client/ PortCMIS/const/ PortCMIS/data/ PortCMIS/enum/ ...

Added: chemistry/portcmis/PortCMIS/binding/atompub/XmlConverter.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/PortCMIS/binding/atompub/XmlConverter.cs?rev=1691890&view=auto
==============================================================================
--- chemistry/portcmis/PortCMIS/binding/atompub/XmlConverter.cs (added)
+++ chemistry/portcmis/PortCMIS/binding/atompub/XmlConverter.cs Mon Jul 20 08:48:57 2015
@@ -0,0 +1,3258 @@
+/*
+* 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.
+*/
+
+using PortCMIS.Binding.AtomPub;
+using PortCMIS.Client.Impl;
+using PortCMIS.Data;
+using PortCMIS.Data.Extensions;
+using PortCMIS.Enums;
+using PortCMIS.Exceptions;
+using PortCMIS.Utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace PortCMIS.Binding.AtomPub
+{
+    class XmlConverter
+    {
+        // ---------------
+        // --- writers ---
+        // ---------------
+
+        public static void writeRepositoryInfo(XmlWriter writer, CmisVersion cmisVersion, string ns, IRepositoryInfo source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.TAG_REPOSITORY_INFO, ns);
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_ID, source.Id);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_NAME, source.Name);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_DESCRIPTION, source.Description);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_VENDOR, source.VendorName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_PRODUCT, source.ProductName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_PRODUCT_VERSION, source.ProductVersion);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_ROOT_FOLDER_ID, source.RootFolderId);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_CHANGE_LOG_TOKEN, source.LatestChangeLogToken);
+            writeRepositoryCapabilities(writer, cmisVersion, source.Capabilities);
+            writeAclCapabilities(writer, cmisVersion, source.AclCapabilities);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_CMIS_VERSION_SUPPORTED, source.CmisVersionSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_THIN_CLIENT_URI, source.ThinClientUri);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_CHANGES_INCOMPLETE, source.ChangesIncomplete);
+            if (source.ChangesOnType != null)
+            {
+                foreach (BaseTypeId baseType in source.ChangesOnType)
+                {
+                    if (cmisVersion == CmisVersion.Cmis_1_0 && baseType == BaseTypeId.CmisItem)
+                    {
+                        Logger.Warn("Receiver only understands CMIS 1.0 but the Changes On Type list in the Repository info contains the base type Item. "
+                                + "The Item base type has been removed from the list.");
+                        continue;
+                    }
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_CHANGES_ON_TYPE, baseType);
+                }
+            }
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_PRINCIPAL_ID_ANONYMOUS, source.PrincipalIdAnonymous);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_REPINFO_PRINCIPAL_ID_ANYONE, source.PrincipalIdAnyone);
+            if (cmisVersion != CmisVersion.Cmis_1_0 && source.ExtensionFeatures != null)
+            {
+                foreach (ExtensionFeature feature in source.ExtensionFeatures)
+                {
+                    writeExtendedFeatures(writer, cmisVersion, feature);
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeRepositoryCapabilities(XmlWriter writer, CmisVersion cmisVersion, IRepositoryCapabilities source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_REPINFO_CAPABILITIES, XmlConstants.NAMESPACE_CMIS);
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_ACL, source.AclCapability);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_ALL_VERSIONS_SEARCHABLE, source.IsAllVersionsSearchableSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_CHANGES, source.ChangesCapability);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_CONTENT_STREAM_UPDATABILITY, source.ContentStreamUpdatesCapability);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_GET_DESCENDANTS, source.IsGetDescendantsSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_GET_FOLDER_TREE, source.IsGetFolderTreeSupported);
+            if (cmisVersion != CmisVersion.Cmis_1_0)
+            {
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_ORDER_BY, source.OrderByCapability);
+            }
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_MULTIFILING, source.IsMultifilingSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_PWC_SEARCHABLE, source.IsPwcSearchableSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_PWC_UPDATABLE, source.IsPwcUpdatableSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_QUERY, source.QueryCapability);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_RENDITIONS, source.RenditionsCapability);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_UNFILING, source.IsUnfilingSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_VERSION_SPECIFIC_FILING, source.IsVersionSpecificFilingSupported);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_JOIN, source.JoinCapability);
+            if (cmisVersion != CmisVersion.Cmis_1_0)
+            {
+                if (source.CreatablePropertyTypes != null)
+                {
+                    ICreatablePropertyTypes creatablePropertyTypes = source.CreatablePropertyTypes;
+
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_CAP_CREATABLE_PROPERTY_TYPES, XmlConstants.NAMESPACE_CMIS);
+
+                    if (creatablePropertyTypes.CanCreate != null)
+                    {
+                        foreach (PropertyType pt in creatablePropertyTypes.CanCreate)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_CREATABLE_PROPERTY_TYPES_CANCREATE,
+                                    pt);
+                        }
+                    }
+
+                    writeExtensions(writer, creatablePropertyTypes);
+                    writer.WriteEndElement();
+                }
+                if (source.NewTypeSettableAttributes != null)
+                {
+                    INewTypeSettableAttributes newTypeSettableAttributes = source.NewTypeSettableAttributes;
+
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES, XmlConstants.NAMESPACE_CMIS);
+
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_ID,
+                            newTypeSettableAttributes.CanSetId);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_LOCALNAME,
+                            newTypeSettableAttributes.CanSetLocalName);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS,
+                            XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_LOCALNAMESPACE,
+                            newTypeSettableAttributes.CanSetLocalNamespace);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_DISPLAYNAME,
+                            newTypeSettableAttributes.CanSetDisplayName);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_QUERYNAME,
+                            newTypeSettableAttributes.CanSetQueryName);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_DESCRIPTION,
+                            newTypeSettableAttributes.CanSetDescription);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CREATEABLE,
+                            newTypeSettableAttributes.CanSetCreatable);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_FILEABLE,
+                            newTypeSettableAttributes.CanSetFileable);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_QUERYABLE,
+                            newTypeSettableAttributes.CanSetQueryable);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS,
+                            XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_FULLTEXTINDEXED,
+                            newTypeSettableAttributes.CanSetFulltextIndexed);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS,
+                            XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_INCLUDEDINSUPERTYTPEQUERY,
+                            newTypeSettableAttributes.CanSetIncludedInSupertypeQuery);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS,
+                            XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEPOLICY,
+                            newTypeSettableAttributes.CanSetControllablePolicy);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS,
+                            XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEACL,
+                            newTypeSettableAttributes.CanSetControllableAcl);
+
+                    writeExtensions(writer, newTypeSettableAttributes);
+                    writer.WriteEndElement();
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeAclCapabilities(XmlWriter writer, CmisVersion cmisVersion, IAclCapabilities source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_REPINFO_ACL_CAPABILITIES, XmlConstants.NAMESPACE_CMIS);
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACLCAP_SUPPORTED_PERMISSIONS, source.SupportedPermissions);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACLCAP_ACL_PROPAGATION, source.AclPropagation);
+            if (source.Permissions != null)
+            {
+                foreach (IPermissionDefinition pd in source.Permissions)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_ACLCAP_PERMISSIONS, XmlConstants.NAMESPACE_CMIS);
+
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACLCAP_PERMISSION_PERMISSION, pd.Id);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACLCAP_PERMISSION_DESCRIPTION, pd.Description);
+
+                    writeExtensions(writer, pd);
+                    writer.WriteEndElement();
+                }
+            }
+            if (source.PermissionMapping != null)
+            {
+                foreach (IPermissionMapping pm in source.PermissionMapping.Values)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_ACLCAP_PERMISSION_MAPPING, XmlConstants.NAMESPACE_CMIS);
+
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACLCAP_MAPPING_KEY, pm.Key);
+                    if (pm.Permissions != null)
+                    {
+                        foreach (String perm in pm.Permissions)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACLCAP_MAPPING_PERMISSION, perm);
+                        }
+                    }
+
+                    writeExtensions(writer, pm);
+                    writer.WriteEndElement();
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeExtendedFeatures(XmlWriter writer, CmisVersion cmisVersion, ExtensionFeature source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_REPINFO_EXTENDED_FEATURES, XmlConstants.NAMESPACE_CMIS);
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_ID, source.Id);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_URL, source.Url);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_COMMON_NAME, source.CommonName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_VERSION_LABEL, source.VersionLabel);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_DESCRIPTION, source.Description);
+            if (source.FeatureData != null)
+            {
+                foreach (KeyValuePair<string, string> data in source.FeatureData)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_FEATURE_DATA, XmlConstants.NAMESPACE_CMIS);
+
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_DATA_KEY, data.Key);
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_FEATURE_DATA_VALUE, data.Value);
+
+                    writer.WriteEndElement();
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        // --------------------------
+        // --- definition writers ---
+        // --------------------------
+
+        public static void writeTypeDefinition(XmlWriter writer, CmisVersion cmisVersion, string ns, ITypeDefinition source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            if (cmisVersion == CmisVersion.Cmis_1_0)
+            {
+                if (source.BaseTypeId == BaseTypeId.CmisItem)
+                {
+                    Logger.Warn("Receiver only understands CMIS 1.0. It may not able to handle an Item type definition.");
+                }
+                else if (source.BaseTypeId == BaseTypeId.CmisSecondary)
+                {
+                    Logger.Warn("Receiver only understands CMIS 1.0. It may not able to handle a Secondary type definition.");
+                }
+            }
+
+            writer.WriteStartElement(XmlConstants.TAG_TYPE, ns);
+            writer.WriteAttributeString("xmlns", XmlConstants.PREFIX_XSI, null, XmlConstants.NAMESPACE_XSI);
+            string prefix = writer.LookupPrefix(ns);
+            if (prefix != null)
+            {
+                writer.WriteAttributeString("xmlns", prefix, null, ns);
+            }
+
+            if (source.BaseTypeId == BaseTypeId.CmisDocument)
+            {
+                writer.WriteAttributeString(XmlConstants.PREFIX_XSI, "type", XmlConstants.NAMESPACE_XSI, XmlConstants.PREFIX_CMIS + ":" + XmlConstants.ATTR_DOCUMENT_TYPE);
+            }
+            else if (source.BaseTypeId == BaseTypeId.CmisFolder)
+            {
+                writer.WriteAttributeString(XmlConstants.PREFIX_XSI, "type", XmlConstants.NAMESPACE_XSI, XmlConstants.PREFIX_CMIS + ":" + XmlConstants.ATTR_FOLDER_TYPE);
+            }
+            else if (source.BaseTypeId == BaseTypeId.CmisRelationship)
+            {
+                writer.WriteAttributeString(XmlConstants.PREFIX_XSI, "type", XmlConstants.NAMESPACE_XSI, XmlConstants.PREFIX_CMIS + ":" + XmlConstants.ATTR_RELATIONSHIP_TYPE);
+            }
+            else if (source.BaseTypeId == BaseTypeId.CmisPolicy)
+            {
+                writer.WriteAttributeString(XmlConstants.PREFIX_XSI, "type", XmlConstants.NAMESPACE_XSI, XmlConstants.PREFIX_CMIS + ":" + XmlConstants.ATTR_POLICY_TYPE);
+            }
+            else if (source.BaseTypeId == BaseTypeId.CmisItem)
+            {
+                writer.WriteAttributeString(XmlConstants.PREFIX_XSI, "type", XmlConstants.NAMESPACE_XSI, XmlConstants.PREFIX_CMIS + ":" + XmlConstants.ATTR_ITEM_TYPE);
+            }
+            else if (source.BaseTypeId == BaseTypeId.CmisSecondary)
+            {
+                writer.WriteAttributeString(XmlConstants.PREFIX_XSI, "type", XmlConstants.NAMESPACE_XSI, XmlConstants.PREFIX_CMIS + ":" + XmlConstants.ATTR_SECONDARY_TYPE);
+            }
+            else
+            {
+                throw new CmisRuntimeException("Type definition has no base type id!");
+            }
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_ID, source.Id);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_LOCALNAME, source.LocalName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_LOCALNAMESPACE, source.LocalNamespace);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_DISPLAYNAME, source.DisplayName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_QUERYNAME, source.QueryName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_DESCRIPTION, source.Description);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_BASE_ID, source.BaseTypeId);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_PARENT_ID, source.ParentTypeId);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_CREATABLE, source.IsCreatable);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_FILEABLE, source.IsFileable);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_QUERYABLE, source.IsQueryable);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_FULLTEXT_INDEXED, source.IsFulltextIndexed);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_INCLUDE_IN_SUPERTYPE_QUERY, source.IsIncludedInSupertypeQuery);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_CONTROLABLE_POLICY, source.IsControllablePolicy);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_CONTROLABLE_ACL, source.IsControllableAcl);
+            if (cmisVersion != CmisVersion.Cmis_1_0 && source.TypeMutability != null)
+            {
+                ITypeMutability tm = source.TypeMutability;
+
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_TYPE_MUTABILITY, XmlConstants.NAMESPACE_CMIS);
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_TYPE_MUTABILITY_CREATE, tm.CanCreate);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_TYPE_MUTABILITY_UPDATE, tm.CanUpdate);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_TYPE_MUTABILITY_DELETE, tm.CanDelete);
+
+                writeExtensions(writer, tm);
+                writer.WriteEndElement();
+            }
+            if (source.PropertyDefinitions != null)
+            {
+                foreach (IPropertyDefinition pd in source.PropertyDefinitions)
+                {
+                    writePropertyDefinition(writer, cmisVersion, pd);
+                }
+            }
+
+            if (source is DocumentTypeDefinition)
+            {
+                DocumentTypeDefinition docDef = (DocumentTypeDefinition)source;
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_VERSIONABLE, docDef.IsVersionable);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_CONTENTSTREAM_ALLOWED, docDef.ContentStreamAllowed);
+            }
+
+            if (source is RelationshipTypeDefinition)
+            {
+                RelationshipTypeDefinition relDef = (RelationshipTypeDefinition)source;
+                if (relDef.AllowedSourceTypeIds != null)
+                {
+                    foreach (String id in relDef.AllowedSourceTypeIds)
+                    {
+                        if (id != null)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_ALLOWED_SOURCE_TYPES, id);
+                        }
+                    }
+                }
+                if (relDef.AllowedTargetTypeIds != null)
+                {
+                    foreach (String id in relDef.AllowedTargetTypeIds)
+                    {
+                        if (id != null)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_TYPE_ALLOWED_TARGET_TYPES, id);
+                        }
+                    }
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writePropertyDefinition(XmlWriter writer, CmisVersion cmisVersion, IPropertyDefinition source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            //if (source.PropertyType == null)
+            //{
+            //    throw new CmisRuntimeException("Property type for property definition '" + source.Id + "' is not set!");
+            //}
+
+            switch (source.PropertyType)
+            {
+                case PropertyType.String:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_STRING, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.Id:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_ID, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.Integer:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_INTEGER, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.Boolean:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_BOOLEAN, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.DateTime:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_DATETIME, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.Decimal:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_DECIMAL, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.Html:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_HTML, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                case PropertyType.Uri:
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_TYPE_PROP_DEF_URI, XmlConstants.NAMESPACE_CMIS);
+                    break;
+                default:
+                    throw new CmisRuntimeException("Property defintion has no property type!");
+            }
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_ID, source.Id);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_LOCALNAME, source.LocalName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_LOCALNAMESPACE, source.LocalNamespace);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_DISPLAYNAME, source.DisplayName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_QUERYNAME, source.QueryName);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_DESCRIPTION, source.Description);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_PROPERTY_TYPE, source.PropertyType);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CARDINALITY, source.Cardinality);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_UPDATABILITY, source.Updatability);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_INHERITED, source.IsInherited);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_REQUIRED, source.IsRequired);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_QUERYABLE, source.IsQueryable);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_ORDERABLE, source.IsOrderable);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_OPENCHOICE, source.IsOpenChoice);
+
+            if (source is IPropertyStringDefinition)
+            {
+                IPropertyStringDefinition def = (IPropertyStringDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.String);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MAX_LENGTH, def.MaxLength);
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<string> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<string>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is IPropertyIdDefinition)
+            {
+                IPropertyIdDefinition def = (IPropertyIdDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.Id);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<string> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<string>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is IPropertyIntegerDefinition)
+            {
+                IPropertyIntegerDefinition def = (IPropertyIntegerDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.Integer);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MAX_VALUE, def.MaxValue);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MIN_VALUE, def.MinValue);
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<BigInteger> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<BigInteger>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is IPropertyBooleanDefinition)
+            {
+                IPropertyBooleanDefinition def = (IPropertyBooleanDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.Boolean);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<bool> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<bool>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is PropertyDateTimeDefinition)
+            {
+                IPropertyDateTimeDefinition def = (IPropertyDateTimeDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.DateTime);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_RESOLUTION, def.DateTimeResolution);
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<DateTime> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<DateTime>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is IPropertyDecimalDefinition)
+            {
+                IPropertyDecimalDefinition def = (IPropertyDecimalDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.Decimal);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MAX_VALUE, def.MaxValue);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MIN_VALUE, def.MinValue);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_PRECISION, def.Precision);
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<decimal?> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<decimal?>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is IPropertyHtmlDefinition)
+            {
+                IPropertyHtmlDefinition def = (IPropertyHtmlDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.Html);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<string> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<string>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+            else if (source is IPropertyUriDefinition)
+            {
+                IPropertyUriDefinition def = (IPropertyUriDefinition)source;
+
+                if (def.DefaultValue != null)
+                {
+                    PropertyData prop = new PropertyData(PropertyType.Uri);
+                    prop.AddValue(def.DefaultValue);
+                    writeProperty(writer, prop, true);
+                }
+
+                if (def.Choices != null)
+                {
+                    foreach (IChoice<string> c in def.Choices)
+                    {
+                        if (c != null)
+                        {
+                            writeChoice<string>(writer, source.PropertyType, c);
+                        }
+                    }
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeChoice<T>(XmlWriter writer, PropertyType propType, IChoice<T> source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CHOICE, XmlConstants.NAMESPACE_CMIS);
+
+            if (source.DisplayName != null)
+            {
+                writer.WriteAttributeString(XmlConstants.ATTR_PROPERTY_TYPE_CHOICE_DISPLAYNAME, source.DisplayName);
+            }
+
+            if (source.Value != null)
+            {
+                switch (propType)
+                {
+                    case PropertyType.String:
+                    case PropertyType.Id:
+                    case PropertyType.Html:
+                    case PropertyType.Uri:
+                        foreach (string value in (IList<string>)source.Value)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CHOICE_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.Integer:
+                        foreach (BigInteger value in (IList<BigInteger>)source.Value)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CHOICE_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.Boolean:
+                        foreach (bool? value in (IList<bool?>)source.Value)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CHOICE_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.DateTime:
+                        foreach (DateTime value in (IList<DateTime>)source.Value)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CHOICE_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.Decimal:
+                        foreach (decimal? value in (IList<decimal?>)source.Value)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_CHOICE_VALUE, value);
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            if (source.Choices != null)
+            {
+                foreach (Choice<T> c in source.Choices)
+                {
+                    if (c != null)
+                    {
+                        writeChoice<T>(writer, propType, c);
+                    }
+                }
+            }
+
+            writer.WriteEndElement();
+        }
+
+        // -----------------------
+        // --- object writers ---
+        // -----------------------
+
+        public static void writeObject(XmlWriter writer, CmisVersion cmisVersion, string ns, IObjectData source)
+        {
+            writeObject(writer, cmisVersion, false, XmlConstants.TAG_OBJECT, ns, source);
+        }
+
+        public static void writeObject(XmlWriter writer, CmisVersion cmisVersion, bool root, string name, string ns, IObjectData source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            if (cmisVersion == CmisVersion.Cmis_1_0)
+            {
+                if (source.BaseTypeId == BaseTypeId.CmisItem)
+                {
+                    Logger.Warn("Receiver only understands CMIS 1.0. It may not be able to handle an Item object.");
+                }
+            }
+
+            if (root)
+            {
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, name, XmlConstants.NAMESPACE_CMIS);
+                writer.WriteAttributeString("xmlns", XmlConstants.PREFIX_CMIS, null, XmlConstants.NAMESPACE_CMIS);
+            }
+            else
+            {
+                writer.WriteStartElement(name, ns);
+            }
+
+            if (source.Properties != null)
+            {
+                IProperties properties = source.Properties;
+
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_OBJECT_PROPERTIES, XmlConstants.NAMESPACE_CMIS);
+
+                if (properties.PropertyList != null)
+                {
+                    foreach (PropertyData property in properties.PropertyList)
+                    {
+                        writeProperty(writer, property, false);
+                    }
+                }
+
+                writeExtensions(writer, properties);
+                writer.WriteEndElement();
+            }
+            if (source.AllowableActions != null)
+            {
+                writeAllowableActions(writer, cmisVersion, false, source.AllowableActions);
+            }
+            if (source.Relationships != null)
+            {
+                foreach (IObjectData rel in source.Relationships)
+                {
+                    if (rel != null)
+                    {
+                        writeObject(writer, cmisVersion, false, XmlConstants.TAG_OBJECT_RELATIONSHIP, XmlConstants.NAMESPACE_CMIS, rel);
+                    }
+                }
+            }
+            if (source.ChangeEventInfo != null)
+            {
+                IChangeEventInfo info = source.ChangeEventInfo;
+
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_OBJECT_CHANGE_EVENT_INFO, XmlConstants.NAMESPACE_CMIS);
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CHANGE_EVENT_TYPE, info.ChangeType);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_CHANGE_EVENT_TIME, info.ChangeTime);
+
+                writeExtensions(writer, info);
+                writer.WriteEndElement();
+            }
+            if (source.Acl != null)
+            {
+                writeAcl(writer, cmisVersion, false, source.Acl);
+            }
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_OBJECT_EXACT_ACL, source.IsExactAcl);
+            if (source.PolicyIds != null)
+            {
+                IPolicyIdList pids = source.PolicyIds;
+
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_OBJECT_POLICY_IDS, XmlConstants.NAMESPACE_CMIS);
+
+                if (pids.PolicyIds != null)
+                {
+                    foreach (string id in pids.PolicyIds)
+                    {
+                        if (id != null)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_POLICY_ID, id);
+                        }
+                    }
+                }
+
+                writeExtensions(writer, pids);
+                writer.WriteEndElement();
+            }
+            if (source.Renditions != null)
+            {
+                foreach (IRenditionData rend in source.Renditions)
+                {
+                    if (rend != null)
+                    {
+                        writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_OBJECT_RENDITION, XmlConstants.NAMESPACE_CMIS);
+
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_STREAM_ID, rend.StreamId);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_MIMETYPE, rend.MimeType);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_LENGTH, rend.Length);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_KIND, rend.Kind);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_TITLE, rend.Title);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_HEIGHT, rend.Height);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_WIDTH, rend.Width);
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_RENDITION_DOCUMENT_ID, rend.RenditionDocumentId);
+
+                        writeExtensions(writer, rend);
+                        writer.WriteEndElement();
+                    }
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeProperty(XmlWriter writer, IPropertyData source, bool isDefaultValue)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            if (isDefaultValue)
+            {
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROPERTY_TYPE_DEAULT_VALUE, XmlConstants.NAMESPACE_CMIS);
+            }
+            else
+            {
+                if (source.PropertyType == PropertyType.String)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_STRING, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.Id)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_ID, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.Integer)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_INTEGER, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.Boolean)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_BOOLEAN, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.DateTime)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_DATETIME, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.Decimal)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_DECIMAL, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.Html)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_HTML, XmlConstants.NAMESPACE_CMIS);
+                }
+                else if (source.PropertyType == PropertyType.Uri)
+                {
+                    writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_PROP_URI, XmlConstants.NAMESPACE_CMIS);
+                }
+                else
+                {
+                    throw new CmisRuntimeException("Invalid property datatype!");
+                }
+            }
+
+            if (source.Id != null)
+            {
+                writer.WriteAttributeString(XmlConstants.ATTR_PROPERTY_ID, source.Id);
+            }
+            if (source.DisplayName != null)
+            {
+                writer.WriteAttributeString(XmlConstants.ATTR_PROPERTY_DISPLAYNAME, source.DisplayName);
+            }
+            if (source.LocalName != null)
+            {
+                writer.WriteAttributeString(XmlConstants.ATTR_PROPERTY_LOCALNAME, source.LocalName);
+            }
+            if (source.QueryName != null)
+            {
+                writer.WriteAttributeString(XmlConstants.ATTR_PROPERTY_QUERYNAME, source.QueryName);
+            }
+
+            if (source.Values != null)
+            {
+
+                switch (source.PropertyType)
+                {
+                    case PropertyType.String:
+                    case PropertyType.Id:
+                    case PropertyType.Html:
+                    case PropertyType.Uri:
+                        foreach (string value in (IList<string>)source.Values)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.Integer:
+                        foreach (BigInteger value in (IList<BigInteger>)source.Values)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.Boolean:
+                        foreach (bool value in (IList<bool>)source.Values)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.DateTime:
+                        foreach (DateTime value in (IList<DateTime>)source.Values)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_VALUE, value);
+                        }
+                        break;
+                    case PropertyType.Decimal:
+                        foreach (decimal value in (IList<decimal>)source.Values)
+                        {
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_VALUE, value);
+                        }
+                        break;
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeAllowableActions(XmlWriter writer, CmisVersion cmisVersion, bool root, IAllowableActions source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            if (root)
+            {
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, "allowableActions", XmlConstants.NAMESPACE_CMIS);
+                writer.WriteAttributeString("xmlns", XmlConstants.PREFIX_CMIS, null, XmlConstants.NAMESPACE_CMIS);
+            }
+            else
+            {
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_OBJECT_ALLOWABLE_ACTIONS, XmlConstants.NAMESPACE_CMIS);
+            }
+
+            if (source.Actions != null)
+            {
+                var values = Enum.GetValues(typeof(PortCMIS.Enums.Action));
+                foreach (var value in values)
+                {
+                    PortCMIS.Enums.Action action = (PortCMIS.Enums.Action)Enum.ToObject(typeof(PortCMIS.Enums.Action), value);
+                    if (source.Actions.Contains(action))
+                    {
+                        if (action == PortCMIS.Enums.Action.CanCreateItem && cmisVersion == CmisVersion.Cmis_1_0)
+                        {
+                            Logger.Warn("Receiver only understands CMIS 1.0 but the Allowable Actions contain the canCreateItem action. "
+                                    + "The canCreateItem action has been removed from the Allowable Actions.");
+                            continue;
+                        }
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, action.GetCmisValue(), true);
+                    }
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        public static void writeAcl(XmlWriter writer, CmisVersion cmisVersion, bool root, IAcl source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            if (root)
+            {
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, "acl", XmlConstants.NAMESPACE_CMIS);
+                writer.WriteAttributeString("xmlns", XmlConstants.PREFIX_CMIS, null, XmlConstants.NAMESPACE_CMIS);
+            }
+            else
+            {
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_OBJECT_ACL, XmlConstants.NAMESPACE_CMIS);
+            }
+
+            if (source.Aces != null)
+            {
+                foreach (IAce ace in source.Aces)
+                {
+                    if (ace != null)
+                    {
+                        writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_ACL_PERMISSISONS, XmlConstants.NAMESPACE_CMIS);
+
+                        if (ace.Principal != null)
+                        {
+                            IPrincipal principal = ace.Principal;
+
+                            writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_ACE_PRINCIPAL, XmlConstants.NAMESPACE_CMIS);
+
+                            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACE_PRINCIPAL_ID, principal.Id);
+
+                            writeExtensions(writer, principal);
+                            writer.WriteEndElement();
+                        }
+                        if (ace.Permissions != null)
+                        {
+                            foreach (String perm in ace.Permissions)
+                            {
+                                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACE_PERMISSIONS, perm);
+                            }
+                        }
+                        XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACE_IS_DIRECT, ace.IsDirect);
+
+                        writeExtensions(writer, ace);
+                        writer.WriteEndElement();
+                    }
+                }
+            }
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        // -------------
+        // --- query ---
+        // -------------
+
+        public static void writeQuery(XmlWriter writer, CmisVersion cmisVersion, QueryType source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.TAG_QUERY, XmlConstants.NAMESPACE_CMIS);
+            writer.WriteAttributeString("xmlns", XmlConstants.PREFIX_CMIS, null, XmlConstants.NAMESPACE_CMIS);
+
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_STATEMENT, source.Statement);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_SEARCHALLVERSIONS, source.SearchAllVersions);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_INCLUDEALLOWABLEACTIONS, source.IncludeAllowableActions);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_INCLUDERELATIONSHIPS, source.IncludeRelationships);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_RENDITIONFILTER, source.RenditionFilter);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_MAXITEMS, source.MaxItems);
+            XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_QUERY_SKIPCOUNT, source.SkipCount);
+
+            writeExtensions(writer, source);
+            writer.WriteEndElement();
+        }
+
+        // -------------------
+        // --- bulk update ---
+        // -------------------
+
+        public static void writeBulkUpdate(XmlWriter writer, String ns, BulkUpdate bulkUpdate)
+        {
+            if (bulkUpdate == null || bulkUpdate.ObjectIdAndChangeToken == null)
+            {
+                return;
+            }
+
+            writer.WriteStartElement(XmlConstants.TAG_BULK_UPDATE, ns);
+
+            foreach (IBulkUpdateObjectIdAndChangeToken idAndToken in bulkUpdate.ObjectIdAndChangeToken)
+            {
+                if (idAndToken == null)
+                {
+                    continue;
+                }
+
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_BULK_UPDATE_ID_AND_TOKEN, XmlConstants.NAMESPACE_CMIS);
+
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_IDANDTOKEN_ID, idAndToken.Id);
+                XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_IDANDTOKEN_CHANGETOKEN, idAndToken.ChangeToken);
+
+                writeExtensions(writer, idAndToken);
+                writer.WriteEndElement();
+            }
+
+            if (bulkUpdate.Properties != null)
+            {
+                Properties properties = bulkUpdate.Properties;
+                writer.WriteStartElement(XmlConstants.PREFIX_CMIS, XmlConstants.TAG_BULK_UPDATE_PROPERTIES, XmlConstants.NAMESPACE_CMIS);
+
+                if (properties.PropertyList != null)
+                {
+                    foreach (PropertyData property in properties.PropertyList)
+                    {
+                        writeProperty(writer, property, false);
+                    }
+                }
+
+                writeExtensions(writer, properties);
+                writer.WriteEndElement();
+            }
+
+            if (bulkUpdate.AddSecondaryTypeIds != null)
+            {
+                foreach (string id in bulkUpdate.AddSecondaryTypeIds)
+                {
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_BULK_UPDATE_ADD_SECONDARY_TYPES, id);
+                }
+            }
+
+            if (bulkUpdate.RemoveSecondaryTypeIds != null)
+            {
+                foreach (string id in bulkUpdate.RemoveSecondaryTypeIds)
+                {
+                    XmlUtils.write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_BULK_UPDATE_REMOVE_SECONDARY_TYPES, id);
+                }
+            }
+
+            writer.WriteEndElement();
+        }
+
+        // -------------------------
+        // --- extension writers ---
+        // -------------------------
+
+        public static void writeExtensions(XmlWriter writer, IExtensionsData source)
+        {
+            if (source == null)
+            {
+                return;
+            }
+
+            IList<string> ns = new List<string>();
+
+            if (source.Extensions != null)
+            {
+                foreach (ICmisExtensionElement element in source.Extensions)
+                {
+                    if (element == null)
+                    {
+                        continue;
+                    }
+
+                    writeExtensionElement(writer, element, ns);
+                }
+            }
+        }
+
+        private static void writeExtensionElement(XmlWriter writer, ICmisExtensionElement source, IList<string> ns)
+        {
+            if (source == null || source.Name == null)
+            {
+                return;
+            }
+
+            bool addedNamespace = false;
+
+            if (source.Namespace != null)
+            {
+                string prefix = writer.LookupPrefix(source.Namespace);
+                if (prefix == null)
+                {
+                    int p = ns.IndexOf(source.Namespace);
+
+                    if (p == -1)
+                    {
+                        prefix = "e" + (ns.Count + 1);
+                        ns.Add(source.Namespace);
+                        addedNamespace = true;
+                    }
+                    else
+                    {
+                        prefix = "e" + (p + 1);
+                    }
+                }
+
+                writer.WriteStartElement(prefix, source.Name, source.Namespace);
+
+                if (addedNamespace)
+                {
+                    writer.WriteAttributeString("xmlns", prefix, null, source.Namespace);
+                }
+            }
+            else
+            {
+                writer.WriteStartElement(source.Name);
+            }
+
+            if (source.Attributes != null)
+            {
+                foreach (KeyValuePair<string, string> attr in source.Attributes)
+                {
+                    writer.WriteAttributeString(attr.Key, attr.Value);
+                }
+            }
+
+            if (source.Value != null)
+            {
+                writer.WriteString(source.Value);
+            }
+            else
+            {
+                if (source.Children != null)
+                {
+                    foreach (ICmisExtensionElement child in source.Children)
+                    {
+                        writeExtensionElement(writer, child, ns);
+                    }
+                }
+            }
+
+            writer.WriteEndElement();
+
+            if (addedNamespace)
+            {
+                ns.RemoveAt(ns.Count - 1);
+            }
+        }
+
+        // ---------------
+        // --- parsers ---
+        // ---------------
+
+        public static RepositoryInfo convertRepositoryInfo(XmlReader parser)
+        {
+            return REPOSITORY_INFO_PARSER.walk(parser);
+        }
+
+        public static ITypeDefinition convertTypeDefinition(XmlReader parser)
+        {
+            return TYPE_DEF_PARSER.walk(parser);
+        }
+
+        public static IObjectData convertObject(XmlReader parser)
+        {
+            return OBJECT_PARSER.walk(parser);
+        }
+
+        public static QueryType convertQuery(XmlReader parser)
+        {
+            return QUERY_PARSER.walk(parser);
+        }
+
+        public static IAllowableActions convertAllowableActions(XmlReader parser)
+        {
+            return ALLOWABLE_ACTIONS_PARSER.walk(parser);
+        }
+
+        public static IAcl convertAcl(XmlReader parser)
+        {
+            return ACL_PARSER.walk(parser);
+        }
+
+        public static BulkUpdate convertBulkUpdate(XmlReader parser)
+        {
+            return BULK_UPDATE_PARSER.walk(parser);
+        }
+
+        // ------------------------------
+        // --- repository info parser ---
+        // ------------------------------
+
+        private static readonly RepositoryInfoParser REPOSITORY_INFO_PARSER = new RepositoryInfoParser();
+        private class RepositoryInfoParser : XMLWalker<RepositoryInfo>
+        {
+            protected override RepositoryInfo prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new RepositoryInfo();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, RepositoryInfo target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_ID))
+                    {
+                        target.Id = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_NAME))
+                    {
+                        target.Name = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_DESCRIPTION))
+                    {
+                        target.Description = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_VENDOR))
+                    {
+                        target.VendorName = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_PRODUCT))
+                    {
+                        target.ProductName = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_PRODUCT_VERSION))
+                    {
+                        target.ProductVersion = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_ROOT_FOLDER_ID))
+                    {
+                        target.RootFolderId = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_CHANGE_LOG_TOKEN))
+                    {
+                        target.LatestChangeLogToken = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_CAPABILITIES))
+                    {
+                        target.Capabilities = CAPABILITIES_PARSER.walk(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_ACL_CAPABILITIES))
+                    {
+                        target.AclCapabilities = ACL_CAPABILITIES_PARSER.walk(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_CMIS_VERSION_SUPPORTED))
+                    {
+                        target.CmisVersionSupported = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_THIN_CLIENT_URI))
+                    {
+                        target.ThinClientUri = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_CHANGES_INCOMPLETE))
+                    {
+                        target.ChangesIncomplete = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_CHANGES_ON_TYPE))
+                    {
+                        target.ChangesOnType = addToList(target.ChangesOnType, readEnum<BaseTypeId>(parser));
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_PRINCIPAL_ID_ANONYMOUS))
+                    {
+                        target.PrincipalIdAnonymous = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_PRINCIPAL_ID_ANYONE))
+                    {
+                        target.PrincipalIdAnyone = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_REPINFO_EXTENDED_FEATURES))
+                    {
+                        target.ExtensionFeatures = addToList(target.ExtensionFeatures, EXTENDED_FEATURES_PARSER.walk(parser));
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+        private static readonly CapabilitiesParser CAPABILITIES_PARSER = new CapabilitiesParser();
+        private class CapabilitiesParser : XMLWalker<RepositoryCapabilities>
+        {
+            protected override RepositoryCapabilities prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new RepositoryCapabilities();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, RepositoryCapabilities target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_CAP_ACL))
+                    {
+                        target.AclCapability = readEnum<CapabilityAcl>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_ALL_VERSIONS_SEARCHABLE))
+                    {
+                        target.IsAllVersionsSearchableSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_CHANGES))
+                    {
+                        target.ChangesCapability = readEnum<CapabilityChanges>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_CONTENT_STREAM_UPDATABILITY))
+                    {
+                        target.ContentStreamUpdatesCapability = readEnum<CapabilityContentStreamUpdates>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_GET_DESCENDANTS))
+                    {
+                        target.IsGetDescendantsSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_GET_FOLDER_TREE))
+                    {
+                        target.IsGetFolderTreeSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_ORDER_BY))
+                    {
+                        target.OrderByCapability = readEnum<CapabilityOrderBy>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_MULTIFILING))
+                    {
+                        target.IsMultifilingSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_PWC_SEARCHABLE))
+                    {
+                        target.IsPwcSearchableSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_PWC_UPDATABLE))
+                    {
+                        target.IsPwcUpdatableSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_QUERY))
+                    {
+                        target.QueryCapability = readEnum<CapabilityQuery>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_RENDITIONS))
+                    {
+                        target.RenditionsCapability = readEnum<CapabilityRenditions>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_UNFILING))
+                    {
+                        target.IsUnfilingSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_VERSION_SPECIFIC_FILING))
+                    {
+                        target.IsVersionSpecificFilingSupported = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_JOIN))
+                    {
+                        target.JoinCapability = readEnum<CapabilityJoin>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_CREATABLE_PROPERTY_TYPES))
+                    {
+                        target.CreatablePropertyTypes = CREATABLE_PROPERTY_TYPES_PARSER.walk(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES))
+                    {
+                        target.NewTypeSettableAttributes = NEW_TYPES_SETTABLE_ATTRIBUTES_PARSER.walk(parser);
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+        private static readonly CreatablePropertyTypesParser CREATABLE_PROPERTY_TYPES_PARSER = new CreatablePropertyTypesParser();
+        private class CreatablePropertyTypesParser : XMLWalker<CreatablePropertyTypes>
+        {
+            protected override CreatablePropertyTypes prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new CreatablePropertyTypes();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, CreatablePropertyTypes target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_CAP_CREATABLE_PROPERTY_TYPES_CANCREATE))
+                    {
+                        target.CanCreate.Add(readEnum<PropertyType>(parser));
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };
+
+        private static readonly NewTypesSettableAttributesParser NEW_TYPES_SETTABLE_ATTRIBUTES_PARSER = new NewTypesSettableAttributesParser();
+        private class NewTypesSettableAttributesParser : XMLWalker<NewTypeSettableAttributes>
+        {
+            protected override NewTypeSettableAttributes prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new NewTypeSettableAttributes();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, NewTypeSettableAttributes target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_ID))
+                    {
+                        target.CanSetId = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_LOCALNAME))
+                    {
+                        target.CanSetLocalName = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_LOCALNAMESPACE))
+                    {
+                        target.CanSetLocalNamespace = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_DISPLAYNAME))
+                    {
+                        target.CanSetDisplayName = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_QUERYNAME))
+                    {
+                        target.CanSetQueryName = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_DESCRIPTION))
+                    {
+                        target.CanSetDescription = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CREATEABLE))
+                    {
+                        target.CanSetCreatable = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_FILEABLE))
+                    {
+                        target.CanSetFileable = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_QUERYABLE))
+                    {
+                        target.CanSetQueryable = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_FULLTEXTINDEXED))
+                    {
+                        target.CanSetFulltextIndexed = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_INCLUDEDINSUPERTYTPEQUERY))
+                    {
+                        target.CanSetIncludedInSupertypeQuery = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEPOLICY))
+                    {
+                        target.CanSetControllablePolicy = readBoolean(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEACL))
+                    {
+                        target.CanSetControllableAcl = readBoolean(parser);
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+
+        private static readonly AclCapabilitiesParser ACL_CAPABILITIES_PARSER = new AclCapabilitiesParser();
+        private class AclCapabilitiesParser : XMLWalker<AclCapabilities>
+        {
+            protected override AclCapabilities prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new AclCapabilities();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, AclCapabilities target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_SUPPORTED_PERMISSIONS))
+                    {
+                        target.SupportedPermissions = readEnum<SupportedPermissions>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_ACL_PROPAGATION))
+                    {
+                        target.AclPropagation = readEnum<AclPropagation>(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_PERMISSIONS))
+                    {
+                        target.Permissions = addToList(target.Permissions, PERMISSION_DEFINITION_PARSER.walk(parser));
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_PERMISSION_MAPPING))
+                    {
+                        PermissionMapping pm = PERMISSION_MAPPING_PARSER.walk(parser);
+
+                        IDictionary<string, IPermissionMapping> mapping = target.PermissionMapping;
+                        mapping.Add(pm.Key, pm);
+
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+
+        private static readonly PermissionDefinitionParser PERMISSION_DEFINITION_PARSER = new PermissionDefinitionParser();
+        private class PermissionDefinitionParser : XMLWalker<PermissionDefinition>
+        {
+            protected override PermissionDefinition prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new PermissionDefinition();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, PermissionDefinition target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_PERMISSION_PERMISSION))
+                    {
+                        target.Id = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_PERMISSION_DESCRIPTION))
+                    {
+                        target.Description = readText(parser);
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+
+        private static readonly PermissionMappingParser PERMISSION_MAPPING_PARSER = new PermissionMappingParser();
+        private class PermissionMappingParser : XMLWalker<PermissionMapping>
+        {
+            protected override PermissionMapping prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new PermissionMapping();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, PermissionMapping target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_MAPPING_KEY))
+                    {
+                        target.Key = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_ACLCAP_MAPPING_PERMISSION))
+                    {
+                        target.Permissions = addToList(target.Permissions, readText(parser));
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+        private static readonly ExtensionFeatureParser EXTENDED_FEATURES_PARSER = new ExtensionFeatureParser();
+        private class ExtensionFeatureParser : XMLWalker<ExtensionFeature>
+        {
+            protected override ExtensionFeature prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new ExtensionFeature();
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, ExtensionFeature target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_ID))
+                    {
+                        target.Id = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_URL))
+                    {
+                        target.Url = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_COMMON_NAME))
+                    {
+                        target.CommonName = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_VERSION_LABEL))
+                    {
+                        target.VersionLabel = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_DESCRIPTION))
+                    {
+                        target.Description = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_DATA))
+                    {
+                        String[] data = FEATURE_DATA_PARSER.walk(parser);
+
+                        IDictionary<string, string> featureData = target.FeatureData;
+                        featureData.Add(data[0], data[1]);
+
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+        private static readonly FetaureDataParser FEATURE_DATA_PARSER = new FetaureDataParser();
+        private class FetaureDataParser : XMLWalker<string[]>
+        {
+            protected override string[] prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                return new string[2];
+            }
+
+            protected override bool read(XmlReader parser, string localname, string ns, string[] target)
+            {
+                if (isCmisNamespace(ns))
+                {
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_DATA_KEY))
+                    {
+                        target[0] = readText(parser);
+                        return true;
+                    }
+
+                    if (isTag(localname, XmlConstants.TAG_FEATURE_DATA_VALUE))
+                    {
+                        target[1] = readText(parser);
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+        };
+
+        // --------------------------
+        // --- definition parsers ---
+        // --------------------------
+
+        private static readonly TypeDefParser TYPE_DEF_PARSER = new TypeDefParser();
+        private class TypeDefParser : XMLWalker<AbstractTypeDefinition>
+        {
+            protected override AbstractTypeDefinition prepareTarget(XmlReader parser, string localname, string ns)
+            {
+                AbstractTypeDefinition result = null;
+
+                string typeAttr = parser.GetAttribute("type", XmlConstants.NAMESPACE_XSI);
+                if (typeAttr != null)
+                {
+                    if (typeAttr.EndsWith(XmlConstants.ATTR_DOCUMENT_TYPE))

[... 1413 lines stripped ...]