chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From f...@apache.org
Subject svn commit: r1741415 - in /chemistry/portcmis/trunk/PortCMIS: binding/ binding/atompub/ binding/browser/ client/ data/
Date Thu, 28 Apr 2016 11:46:18 GMT
Author: fmui
Date: Thu Apr 28 11:46:18 2016
New Revision: 1741415

URL: http://svn.apache.org/viewvc?rev=1741415&view=rev
Log:
PortCMIS: more AtomPub code

Modified:
    chemistry/portcmis/trunk/PortCMIS/binding/Services.cs
    chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubBinding.cs
    chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubUtils.cs
    chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlConverter.cs
    chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlUtils.cs
    chemistry/portcmis/trunk/PortCMIS/binding/browser/BrowserBinding.cs
    chemistry/portcmis/trunk/PortCMIS/client/SessionParameter.cs
    chemistry/portcmis/trunk/PortCMIS/data/DataImpl.cs

Modified: chemistry/portcmis/trunk/PortCMIS/binding/Services.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/binding/Services.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/binding/Services.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/binding/Services.cs Thu Apr 28 11:46:18 2016
@@ -143,11 +143,11 @@ namespace PortCMIS.Binding.Services
             IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
             IExtensionsData extension);
 
-        IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+        IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
             string filter, bool? includeAllowableActions, IncludeRelationships? includeRelationships,
             string renditionFilter, bool? includePolicyIds, bool? includeAcl, IExtensionsData extension);
 
-        IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+        IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
             string filter, IExtensionsData extension);
 
         IList<IObjectData> GetAllVersions(string repositoryId, string objectId, string versionSeriesId, string filter,

Modified: chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubBinding.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubBinding.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubBinding.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubBinding.cs Thu Apr 28 11:46:18 2016
@@ -150,11 +150,11 @@ namespace PortCMIS.Binding.AtomPub
             ID, PATH
         }
 
-        protected const string NAME_COLLECTION = "collection";
-        protected const string NAME_URI_TEMPLATE = "uritemplate";
-        protected const string NAME_PATH_SEGMENT = "pathSegment";
-        protected const string NAME_RELATIVE_PATH_SEGMENT = "relativePathSegment";
-        protected const string NAME_NUM_ITEMS = "numItems";
+        protected const string NameCollection = "collection";
+        protected const string NameUriTemplate = "uritemplate";
+        protected const string NamePathSegment = "pathSegment";
+        protected const string NameRelativePathSegment = "relativePathSegment";
+        protected const string NameNumItems = "numItems";
 
         private BindingSession session;
 
@@ -649,17 +649,17 @@ namespace PortCMIS.Binding.AtomPub
             return name == element.LocalName;
         }
 
-        protected bool isStr(string name, AtomElement element)
+        protected bool IsStr(string name, AtomElement element)
         {
             return Matches(name, element) && (element.Object is string);
         }
 
-        protected bool isInt(string name, AtomElement element)
+        protected bool IsInt(string name, AtomElement element)
         {
             return Matches(name, element) && (element.Object is BigInteger);
         }
 
-        protected bool isNextLink(AtomElement element)
+        protected bool IsNextLink(AtomElement element)
         {
             return BindingConstants.RelNext == ((AtomLink)element.Object).Rel;
         }
@@ -726,7 +726,7 @@ namespace PortCMIS.Binding.AtomPub
         /// <summary>
         /// Creates a CMIS object that only contains an ID in the property list.
         /// </summary>
-        protected IObjectData createIdObject(string objectId)
+        protected IObjectData CreateIdObject(string objectId)
         {
             ObjectData obj = new ObjectData();
 
@@ -810,7 +810,7 @@ namespace PortCMIS.Binding.AtomPub
         /// Performs a POST on an URL, checks the response code and consumes the
         /// response.
         /// </summary>
-        protected void postAndConsume(UrlBuilder url, HttpContent content)
+        protected void PostAndConsume(UrlBuilder url, HttpContent content)
         {
             IResponse resp = Post(url, content);
             IOUtils.ConsumeAndClose(resp.Stream);
@@ -1003,7 +1003,7 @@ namespace PortCMIS.Binding.AtomPub
 
                 foreach (AtomElement element in ws.Elements)
                 {
-                    if (Matches(NAME_COLLECTION, element))
+                    if (Matches(NameCollection, element))
                     {
                         Dictionary<string, string> colMap = (Dictionary<string, string>)element.Object;
                         string collectionType;
@@ -1017,7 +1017,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         AddRepositoryLink(ws.Id, (AtomLink)element.Object);
                     }
-                    else if (Matches(NAME_URI_TEMPLATE, element))
+                    else if (Matches(NameUriTemplate, element))
                     {
                         Dictionary<string, string> tempMap = (Dictionary<string, string>)element.Object;
                         string type;
@@ -1165,8 +1165,8 @@ namespace PortCMIS.Binding.AtomPub
         /// <summary>
         /// Retrieves the ACL of an object.
         /// </summary>
-        public IAcl GetAclInternal(string repositoryId, string objectId, Boolean onlyBasicPermissions,
-                ExtensionsData extension)
+        public IAcl GetAclInternal(string repositoryId, string objectId, bool? onlyBasicPermissions,
+                IExtensionsData extension)
         {
 
             // find the link
@@ -1208,10 +1208,10 @@ namespace PortCMIS.Binding.AtomPub
             // update
             IResponse resp = Put(aclUrl, new AtomPubHttpContent(BindingConstants.MediaTypeAcl, (stream) =>
             {
-                using (XmlWriter writer = XmlUtils.createWriter(stream))
+                using (XmlWriter writer = XmlUtils.CreateWriter(stream))
                 {
                     XmlUtils.StartXmlDocument(writer);
-                    XmlConverter.writeAcl(writer, cmisVersion, true, acl);
+                    XmlConverter.WriteAcl(writer, cmisVersion, true, acl);
                     XmlUtils.EndXmlDocument(writer);
                 }
             }));
@@ -1294,12 +1294,12 @@ namespace PortCMIS.Binding.AtomPub
             {
                 if (element.Object is AtomLink)
                 {
-                    if (isNextLink(element))
+                    if (IsNextLink(element))
                     {
                         result.HasMoreItems = true;
                     }
                 }
-                else if (isInt(NAME_NUM_ITEMS, element))
+                else if (IsInt(NameNumItems, element))
                 {
                     result.NumItems = (BigInteger)element.Object;
                 }
@@ -1529,9 +1529,9 @@ namespace PortCMIS.Binding.AtomPub
 
             // post the new type definition
             IResponse resp = Put(new UrlBuilder(link), new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
-                {
-                    entryWriter.Write(stream);
-                }));
+            {
+                entryWriter.Write(stream);
+            }));
 
             // parse the response
             AtomEntry entry = Parse<AtomEntry>(resp.Stream);
@@ -1625,12 +1625,12 @@ namespace PortCMIS.Binding.AtomPub
             {
                 if (element.Object is AtomLink)
                 {
-                    if (isNextLink(element))
+                    if (IsNextLink(element))
                     {
                         result.HasMoreItems = true;
                     }
                 }
-                else if (isInt(NAME_NUM_ITEMS, element))
+                else if (IsInt(NameNumItems, element))
                 {
                     result.NumItems = (BigInteger)element.Object;
                 }
@@ -1659,7 +1659,7 @@ namespace PortCMIS.Binding.AtomPub
                             {
                                 AddLink(repositoryId, entry.Id, (AtomLink)element.Object);
                             }
-                            else if (isStr(NAME_PATH_SEGMENT, element))
+                            else if (IsStr(NamePathSegment, element))
                             {
                                 pathSegment = (string)element.Object;
                             }
@@ -1784,7 +1784,7 @@ namespace PortCMIS.Binding.AtomPub
                         {
                             objectInFolder = new ObjectInFolderData() { Object = (IObjectData)element.Object };
                         }
-                        else if (isStr(NAME_PATH_SEGMENT, element))
+                        else if (IsStr(NamePathSegment, element))
                         {
                             pathSegment = (string)element.Object;
                         }
@@ -1890,7 +1890,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         result = new ObjectParentData() { Object = (ObjectData)element.Object };
                     }
-                    else if (isStr(NAME_RELATIVE_PATH_SEGMENT, element))
+                    else if (IsStr(NameRelativePathSegment, element))
                     {
                         relativePathSegment = (string)element.Object;
                     }
@@ -2009,12 +2009,12 @@ namespace PortCMIS.Binding.AtomPub
             {
                 if (element.Object is AtomLink)
                 {
-                    if (isNextLink(element))
+                    if (IsNextLink(element))
                     {
                         result.HasMoreItems = true;
                     }
                 }
-                else if (isInt(NAME_NUM_ITEMS, element))
+                else if (IsInt(NameNumItems, element))
                 {
                     result.NumItems = (BigInteger)element.Object;
                 }
@@ -2643,7 +2643,7 @@ namespace PortCMIS.Binding.AtomPub
             }
 
             // set up object and writer
-            AtomEntryWriter entryWriter = new AtomEntryWriter(createIdObject(objectId), GetCmisVersion(repositoryId));
+            AtomEntryWriter entryWriter = new AtomEntryWriter(CreateIdObject(objectId), GetCmisVersion(repositoryId));
 
             // post move request
             IResponse resp = Post(url, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
@@ -2873,7 +2873,6 @@ namespace PortCMIS.Binding.AtomPub
             }
 
             // send content
-
             IResponse resp = Put(url, headers, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
             {
                 content.CopyTo(stream);
@@ -2906,38 +2905,303 @@ namespace PortCMIS.Binding.AtomPub
 
         public void CheckOut(string repositoryId, ref string objectId, IExtensionsData extension, out bool? contentCopied)
         {
-            contentCopied = false;
+            if (objectId == null || objectId.Length == 0)
+            {
+                throw new CmisInvalidArgumentException("Object ID must be set!");
+            }
+
+            // find the link
+            string link = LoadCollection(repositoryId, BindingConstants.CollectionCheckedout);
+
+            if (link == null)
+            {
+                throw new CmisObjectNotFoundException("Unknown repository or checkedout collection not supported!");
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+
+            // workaround for SharePoint 2010 - see CMIS-362
+            if (Session.GetValue(SessionParameter.IncludeObjectIdUrlParamOnCheckout, false))
+            {
+                url.AddParameter("objectId", objectId);
+            }
+
+            // set up object and writer
+            AtomEntryWriter entryWriter = new AtomEntryWriter(CreateIdObject(objectId), GetCmisVersion(repositoryId));
+
+            // post check out request
+            IResponse resp = Post(url, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
+            {
+                entryWriter.Write(stream);
+            }));
+
+            // parse the response
+            AtomEntry entry = Parse<AtomEntry>(resp.Stream);
+
+            objectId = entry.Id;
+
+            LockLinks();
+            try
+            {
+                // clean up cache
+                RemoveLinks(repositoryId, entry.Id);
+
+                // walk through the entry
+                foreach (AtomElement element in entry.Elements)
+                {
+                    if (element.Object is AtomLink)
+                    {
+                        AddLink(repositoryId, entry.Id, (AtomLink)element.Object);
+                    }
+                }
+            }
+            finally
+            {
+                UnlockLinks();
+            }
+
+            contentCopied = null;
         }
 
         public void CancelCheckOut(string repositoryId, string objectId, IExtensionsData extension)
         {
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelSelf, BindingConstants.MediaTypeEntry);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelSelf, BindingConstants.MediaTypeEntry);
+            }
 
+            // prefer working copy link if available
+            // (workaround for non-compliant repositories)
+            string wcLink = GetLink(repositoryId, objectId, BindingConstants.RelWorkingCopy, BindingConstants.MediaTypeEntry);
+            if (wcLink != null)
+            {
+                link = wcLink;
+            }
+
+            Delete(new UrlBuilder(link));
         }
 
         public void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
             IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
             IExtensionsData extension)
         {
+            // we need an object id
+            if (objectId == null || objectId.Length == 0)
+            {
+                throw new CmisInvalidArgumentException("Object ID must be set!");
+            }
+
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelSelf, BindingConstants.MediaTypeEntry);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelSelf, BindingConstants.MediaTypeEntry);
+            }
+
+            // prefer working copy link if available
+            // (workaround for non-compliant repositories)
+            string wcLink = GetLink(repositoryId, objectId, BindingConstants.RelWorkingCopy, BindingConstants.MediaTypeEntry);
+            if (wcLink != null)
+            {
+                link = wcLink;
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamCheckinComment, checkinComment);
+            url.AddParameter(BindingConstants.ParamMajor, major);
+            url.AddParameter(BindingConstants.ParamCheckIn, "true");
+
+            // workaround for SharePoint - check in without property change
+            if (Session.GetValue(SessionParameter.AddNameOnCheckIn, false))
+            {
+                if (properties == null || properties.PropertyList.Count == 0)
+                {
+                    properties = new Properties();
+
+                    try
+                    {
+                        string name = null;
+
+                        // fetch the current name
+                        IObjectData obj = GetObjectInternal(repositoryId, IdentifierType.ID, objectId, ReturnVersion.This,
+                            "cmis:objectId,cmis:name", false, IncludeRelationships.None, "cmis:none", false, false, null);
+
+                        if (obj != null && obj.Properties != null && obj.Properties[PropertyIds.Name] != null)
+                        {
+                            name = obj.Properties[PropertyIds.Name].FirstValue as string;
+                        }
+
+                        if (name == null)
+                        {
+                            throw new CmisRuntimeException("Could not determine the name of the PWC!");
+                        }
+
+                        // set the document name to the same value - silly, but
+                        // SharePoint requires that at least one property value has
+                        // to be changed and the name is the only reliable property
+                        PropertyData newNameProp = new PropertyData(PropertyType.String);
+                        newNameProp.Id = PropertyIds.Name;
+                        newNameProp.AddValue(name);
+                        ((Properties)properties).AddProperty(newNameProp);
+                    }
+                    catch (CmisBaseException e)
+                    {
+                        throw new CmisRuntimeException("Could not determine the name of the PWC: " + e.ToString(), e);
+                    }
+                }
+            }
+
+            // set up writer
+            AtomEntryWriter entryWriter = new AtomEntryWriter(CreateObject(properties, null, policies), GetCmisVersion(repositoryId), contentStream);
+
+            // update
+
+            IResponse resp = Put(url, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
+            {
+                entryWriter.Write(stream);
+            }));
+
+            // parse new entry
+            AtomEntry entry = Parse<AtomEntry>(resp.Stream);
+
+            // we expect a CMIS entry
+            if (entry.Id == null)
+            {
+                throw new CmisConnectionException("Received Atom entry is not a CMIS entry!");
+            }
+
+            // set object id
+            objectId = entry.Id;
+
+            Acl originalAces = null;
+
+            LockLinks();
+            try
+            {
+                // clean up cache
+                RemoveLinks(repositoryId, entry.Id);
 
+                // walk through the entry
+                foreach (AtomElement element in entry.Elements)
+                {
+                    if (element.Object is AtomLink)
+                    {
+                        AddLink(repositoryId, entry.Id, (AtomLink)element.Object);
+                    }
+                    else if (element.Object is IObjectData)
+                    {
+                        // extract current ACL
+                        IObjectData objectData = (IObjectData)element.Object;
+                        if (objectData.Acl != null)
+                        {
+                            originalAces = new Acl() { Aces = objectData.Acl.Aces };
+                            originalAces.IsExact = objectData.IsExactAcl;
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                UnlockLinks();
+            }
+
+            // handle ACL modifications
+            if (originalAces != null && IsAclMergeRequired(addAces, removeAces))
+            {
+                // merge and update ACL
+                IAcl newACL = MergeAcls(originalAces, addAces, removeAces);
+                if (newACL != null)
+                {
+                    UpdateAcl(repositoryId, entry.Id, newACL, null);
+                }
+            }
         }
 
-        public IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+        public IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
             string filter, bool? includeAllowableActions, IncludeRelationships? includeRelationships,
             string renditionFilter, bool? includePolicyIds, bool? includeAcl, IExtensionsData extension)
         {
-            return null;
+            ReturnVersion returnVersion = (major == true ? ReturnVersion.LatestMajor : ReturnVersion.Latest);
+
+            return GetObjectInternal(repositoryId, IdentifierType.ID, objectId, returnVersion, filter,
+                    includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds, includeAcl, extension);
         }
 
-        public IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+        public IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
             string filter, IExtensionsData extension)
         {
-            return null;
+            ReturnVersion returnVersion = (major == true ? ReturnVersion.LatestMajor : ReturnVersion.Latest);
+
+            IObjectData objectData = GetObjectInternal(repositoryId, IdentifierType.ID, objectId, returnVersion, filter,
+                    false, IncludeRelationships.None, "cmis:none", false, false, extension);
+
+            return objectData.Properties;
         }
 
         public IList<IObjectData> GetAllVersions(string repositoryId, string objectId, string versionSeriesId, string filter,
             bool? includeAllowableActions, IExtensionsData extension)
         {
-            return null;
+            IList<IObjectData> result = new List<IObjectData>();
+
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelVersionHistory, BindingConstants.MediaTypeFeed);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelVersionHistory, BindingConstants.MediaTypeFeed);
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamFilter, filter);
+            url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+
+            // read and parse
+            IResponse resp = Read(url);
+            AtomFeed feed = Parse<AtomFeed>(resp.Stream);
+
+            // get the versions
+            if (feed.Entries.Count > 0)
+            {
+                foreach (AtomEntry entry in feed.Entries)
+                {
+                    IObjectData version = null;
+
+                    LockLinks();
+                    try
+                    {
+                        // clean up cache
+                        RemoveLinks(repositoryId, entry.Id);
+
+                        // walk through the entry
+                        foreach (AtomElement element in entry.Elements)
+                        {
+                            if (element.Object is AtomLink)
+                            {
+                                AddLink(repositoryId, entry.Id, (AtomLink)element.Object);
+                            }
+                            else if (element.Object is IObjectData)
+                            {
+                                version = (IObjectData)element.Object;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        UnlockLinks();
+                    }
+
+                    if (version != null)
+                    {
+                        result.Add(version);
+                    }
+                }
+            }
+
+            return result;
         }
     }
 
@@ -2979,10 +3243,12 @@ namespace PortCMIS.Binding.AtomPub
             // post the query and parse results
             IResponse resp = Post(url, new AtomPubHttpContent(BindingConstants.MediaTypeQuery, (stream) =>
             {
-                XmlWriter writer = XmlUtils.createWriter(stream);
-                XmlUtils.StartXmlDocument(writer);
-                XmlConverter.writeQuery(writer, cmisVersion, query);
-                XmlUtils.EndXmlDocument(writer);
+                using (XmlWriter writer = XmlUtils.CreateWriter(stream))
+                {
+                    XmlUtils.StartXmlDocument(writer);
+                    XmlConverter.WriteQuery(writer, cmisVersion, query);
+                    XmlUtils.EndXmlDocument(writer);
+                }
             }));
 
             AtomFeed feed = Parse<AtomFeed>(resp.Stream);
@@ -2992,12 +3258,12 @@ namespace PortCMIS.Binding.AtomPub
             {
                 if (element.Object is AtomLink)
                 {
-                    if (isNextLink(element))
+                    if (IsNextLink(element))
                     {
                         result.HasMoreItems = true;
                     }
                 }
-                else if (isInt(NAME_NUM_ITEMS, element))
+                else if (IsInt(NameNumItems, element))
                 {
                     result.NumItems = (BigInteger)element.Object;
                 }
@@ -3034,7 +3300,88 @@ namespace PortCMIS.Binding.AtomPub
         public IObjectList GetContentChanges(string repositoryId, ref string changeLogToken, bool? includeProperties,
             string filter, bool? includePolicyIds, bool? includeAcl, BigInteger? maxItems, IExtensionsData extension)
         {
-            return null;
+            ObjectList result = new ObjectList();
+
+            // find the link
+            string link = null;
+            UrlBuilder url = null;
+
+            // if the application didn't provide a link to next Atom feed
+            if (link == null)
+            {
+                link = LoadRepositoryLink(repositoryId, BindingConstants.RepRelChanges);
+                if (link != null)
+                {
+                    url = new UrlBuilder(link);
+                    url.AddParameter(BindingConstants.ParamChangeLogToken, changeLogToken);
+                    url.AddParameter(BindingConstants.ParamProperties, includeProperties);
+                    url.AddParameter(BindingConstants.ParamFilter, filter);
+                    url.AddParameter(BindingConstants.ParamPolicyIds, includePolicyIds);
+                    url.AddParameter(BindingConstants.ParamAcl, includeAcl);
+                    url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+                }
+            }
+
+            if (link == null)
+            {
+                throw new CmisObjectNotFoundException("Unknown repository or content changes not supported!");
+            }
+
+            // read and parse
+            IResponse resp = Read(url);
+            AtomFeed feed = Parse<AtomFeed>(resp.Stream);
+            string lastChangeLogToken = null;
+
+            // handle top level
+            string nextLink = null;
+            foreach (AtomElement element in feed.Elements)
+            {
+                if (element.Object is AtomLink)
+                {
+                    if (IsNextLink(element))
+                    {
+                        result.HasMoreItems = true;
+                        nextLink = ((AtomLink)element.Object).Href;
+                    }
+                }
+                else if (IsInt(NameNumItems, element))
+                {
+                    result.NumItems = (BigInteger)element.Object;
+                }
+                else if (IsStr("changeLogToken", element))
+                {
+                    lastChangeLogToken = (String)element.Object;
+                }
+            }
+
+            // get the changes
+            if (feed.Entries.Count > 0)
+            {
+                result.Objects = new List<IObjectData>(feed.Entries.Count);
+
+                foreach (AtomEntry entry in feed.Entries)
+                {
+                    IObjectData hit = null;
+
+                    // walk through the entry
+                    foreach (AtomElement element in entry.Elements)
+                    {
+                        if (element.Object is IObjectData)
+                        {
+                            hit = (IObjectData)element.Object;
+                        }
+                    }
+
+                    if (hit != null)
+                    {
+                        result.Objects.Add(hit);
+                    }
+                }
+            }
+
+            changeLogToken = lastChangeLogToken;
+
+            return result;
         }
     }
 
@@ -3047,12 +3394,58 @@ namespace PortCMIS.Binding.AtomPub
 
         public void AddObjectToFolder(string repositoryId, string objectId, string folderId, bool? allVersions, IExtensionsData extension)
         {
+            if (objectId == null)
+            {
+                throw new CmisInvalidArgumentException("Object ID must be set!");
+            }
 
+            // find the link
+            string link = LoadLink(repositoryId, folderId, BindingConstants.RelDown, BindingConstants.MediaTypeChildren);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, folderId, BindingConstants.RelDown, BindingConstants.MediaTypeChildren);
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamAllVersions, allVersions);
+
+            // set up object and writer
+            AtomEntryWriter entryWriter = new AtomEntryWriter(CreateIdObject(objectId), GetCmisVersion(repositoryId));
+
+            // post addObjectToFolder request
+            PostAndConsume(url, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
+            {
+                entryWriter.Write(stream);
+            }));
         }
 
         public void RemoveObjectFromFolder(string repositoryId, string objectId, string folderId, IExtensionsData extension)
         {
+            if (objectId == null)
+            {
+                throw new CmisInvalidArgumentException("Object ID must be set!");
+            }
+
+            // find the link
+            string link = LoadCollection(repositoryId, BindingConstants.CollectionUnfiled);
+
+            if (link == null)
+            {
+                throw new CmisObjectNotFoundException("Unknown repository or unfiling not supported!");
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamRemoveFrom, folderId);
+
+            // set up object and writer
+            AtomEntryWriter entryWriter = new AtomEntryWriter(CreateIdObject(objectId), GetCmisVersion(repositoryId));
 
+            // post removeObjectFromFolder request
+            PostAndConsume(url, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
+            {
+                entryWriter.Write(stream);
+            }));
         }
     }
 
@@ -3064,10 +3457,89 @@ namespace PortCMIS.Binding.AtomPub
         }
 
         public IObjectList GetObjectRelationships(string repositoryId, string objectId, bool? includeSubRelationshipTypes,
-    RelationshipDirection? relationshipDirection, string typeId, string filter, bool? includeAllowableActions,
-    BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
+            RelationshipDirection? relationshipDirection, string typeId, string filter, bool? includeAllowableActions,
+            BigInteger? maxItems, BigInteger? skipCount, IExtensionsData extension)
         {
-            return null;
+            ObjectList result = new ObjectList();
+
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelRelationships, BindingConstants.MediaTypeFeed);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelRelationships, BindingConstants.MediaTypeFeed);
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamSubRelationshipTypes, includeSubRelationshipTypes);
+            url.AddParameter(BindingConstants.ParamRelationshipDirection, relationshipDirection);
+            url.AddParameter(BindingConstants.ParamTypeId, typeId);
+            url.AddParameter(BindingConstants.ParamFilter, filter);
+            url.AddParameter(BindingConstants.ParamAllowableActions, includeAllowableActions);
+            url.AddParameter(BindingConstants.ParamMaxItems, maxItems);
+            url.AddParameter(BindingConstants.ParamSkipCount, skipCount);
+
+            // read and parse
+            IResponse resp = Read(url);
+            AtomFeed feed = Parse<AtomFeed>(resp.Stream);
+
+            // handle top level
+            foreach (AtomElement element in feed.Elements)
+            {
+                if (element.Object is AtomLink)
+                {
+                    if (IsNextLink(element))
+                    {
+                        result.HasMoreItems = true;
+                    }
+                }
+                else if (IsInt(NameNumItems, element))
+                {
+                    result.NumItems = (BigInteger)element.Object;
+                }
+            }
+
+            // get the children
+            if (feed.Entries.Count > 0)
+            {
+                result.Objects = new List<IObjectData>(feed.Entries.Count);
+
+                foreach (AtomEntry entry in feed.Entries)
+                {
+                    IObjectData relationship = null;
+
+                    LockLinks();
+                    try
+                    {
+                        // clean up cache
+                        RemoveLinks(repositoryId, entry.Id);
+
+                        // walk through the entry
+                        foreach (AtomElement element in entry.Elements)
+                        {
+                            if (element.Object is AtomLink)
+                            {
+                                AddLink(repositoryId, entry.Id, (AtomLink)element.Object);
+                            }
+                            else if (element.Object is IObjectData)
+                            {
+                                relationship = (IObjectData)element.Object;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        UnlockLinks();
+                    }
+
+                    if (relationship != null)
+                    {
+                        result.Objects.Add(relationship);
+                    }
+                }
+            }
+
+            return result;
         }
     }
 
@@ -3080,17 +3552,135 @@ namespace PortCMIS.Binding.AtomPub
 
         public void ApplyPolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension)
         {
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelPolicies, BindingConstants.MediaTypeFeed);
 
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelPolicies, BindingConstants.MediaTypeFeed);
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+
+            // set up object and writer
+            AtomEntryWriter entryWriter = new AtomEntryWriter(CreateIdObject(policyId), GetCmisVersion(repositoryId));
+
+            // post applyPolicy request
+            PostAndConsume(url, new AtomPubHttpContent(BindingConstants.MediaTypeEntry, (stream) =>
+            {
+                entryWriter.Write(stream);
+            }));
         }
 
         public void RemovePolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension)
         {
+            // we need a policy id
+            if (policyId == null)
+            {
+                throw new CmisInvalidArgumentException("Policy id must be set!");
+            }
+
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelPolicies, BindingConstants.MediaTypeFeed);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelPolicies, BindingConstants.MediaTypeFeed);
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamFilter, PropertyIds.ObjectId);
+
+            // read and parse
+            IResponse resp = Read(url);
+            AtomFeed feed = Parse<AtomFeed>(resp.Stream);
+
+            // find the policy
+            string policyLink = null;
+            bool found = false;
 
+            if (feed.Entries.Count > 0)
+            {
+                foreach (AtomEntry entry in feed.Entries)
+                {
+                    // walk through the entry
+                    foreach (AtomElement element in entry.Elements)
+                    {
+                        if (element.Object is AtomLink)
+                        {
+                            AtomLink atomLink = (AtomLink)element.Object;
+                            if (BindingConstants.RelSelf == atomLink.Rel)
+                            {
+                                policyLink = atomLink.Href;
+                            }
+                        }
+                        else if (element.Object is IObjectData)
+                        {
+                            string id = ((IObjectData)element.Object).Id;
+                            if (policyId == id)
+                            {
+                                found = true;
+                            }
+                        }
+                    }
+
+                    if (found)
+                    {
+                        break;
+                    }
+                }
+            }
+
+            // if found, delete it
+            if (found && policyLink != null)
+            {
+                Delete(new UrlBuilder(policyLink));
+            }
         }
 
         public IList<IObjectData> GetAppliedPolicies(string repositoryId, string objectId, string filter, IExtensionsData extension)
         {
-            return null;
+            IList<IObjectData> result = new List<IObjectData>();
+
+            // find the link
+            string link = LoadLink(repositoryId, objectId, BindingConstants.RelPolicies, BindingConstants.MediaTypeFeed);
+
+            if (link == null)
+            {
+                ThrowLinkException(repositoryId, objectId, BindingConstants.RelPolicies, BindingConstants.MediaTypeFeed);
+            }
+
+            UrlBuilder url = new UrlBuilder(link);
+            url.AddParameter(BindingConstants.ParamFilter, filter);
+
+            // read and parse
+            IResponse resp = Read(url);
+            AtomFeed feed = Parse<AtomFeed>(resp.Stream);
+
+            // get the policies
+            if (feed.Entries.Count > 0)
+            {
+                foreach (AtomEntry entry in feed.Entries)
+                {
+                    IObjectData policy = null;
+
+                    // walk through the entry
+                    foreach (AtomElement element in entry.Elements)
+                    {
+                        if (element.Object is IObjectData)
+                        {
+                            policy = (IObjectData)element.Object;
+                        }
+                    }
+
+                    if (policy != null)
+                    {
+                        result.Add(policy);
+                    }
+                }
+            }
+
+            return result;
         }
     }
 
@@ -3103,13 +3693,29 @@ namespace PortCMIS.Binding.AtomPub
 
         public IAcl GetAcl(string repositoryId, string objectId, bool? onlyBasicPermissions, IExtensionsData extension)
         {
-            return null;
+            return GetAclInternal(repositoryId, objectId, onlyBasicPermissions, extension);
         }
 
         public IAcl ApplyAcl(string repositoryId, string objectId, IAcl addAces, IAcl removeAces, AclPropagation? aclPropagation,
             IExtensionsData extension)
         {
-            return null;
+            // fetch the current ACL
+            IAcl originalAces = GetAcl(repositoryId, objectId, false, null);
+
+            // if no changes required, just return the ACL
+            if (!IsAclMergeRequired(addAces, removeAces))
+            {
+                return originalAces;
+            }
+
+            // merge ACLs
+            IAcl newACL = MergeAcls(originalAces, addAces, removeAces);
+
+            // update ACL
+            AtomAcl acl = UpdateAcl(repositoryId, objectId, newACL, aclPropagation);
+            IAcl result = acl.Acl;
+
+            return result;
         }
     }
 }

Modified: chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubUtils.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubUtils.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubUtils.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/binding/atompub/AtomPubUtils.cs Thu Apr 28 11:46:18 2016
@@ -354,7 +354,7 @@ namespace PortCMIS.Binding.AtomPub
         /// </summary>
         private static AtomAllowableActions ParseAllowableActions(XmlReader parser)
         {
-            return new AtomAllowableActions() { AllowableActions = XmlConverter.convertAllowableActions(parser) };
+            return new AtomAllowableActions() { AllowableActions = XmlConverter.ConvertAllowableActions(parser) };
         }
 
         /// <summary>
@@ -362,7 +362,7 @@ namespace PortCMIS.Binding.AtomPub
         /// </summary>
         private static AtomAcl ParseACL(XmlReader parser)
         {
-            return new AtomAcl() { Acl = XmlConverter.convertAcl(parser) };
+            return new AtomAcl() { Acl = XmlConverter.ConvertAcl(parser) };
         }
 
         /// <summary>
@@ -377,7 +377,7 @@ namespace PortCMIS.Binding.AtomPub
             {
                 if (local == XmlConstants.TAG_OBJECT)
                 {
-                    return new AtomElement(uri, local, XmlConverter.convertObject(parser));
+                    return new AtomElement(uri, local, XmlConverter.ConvertObject(parser));
                 }
                 else if (local == XmlConstants.TAG_PATH_SEGMENT
                         || local == XmlConstants.TAG_RELATIVE_PATH_SEGMENT)
@@ -386,7 +386,7 @@ namespace PortCMIS.Binding.AtomPub
                 }
                 else if (local == XmlConstants.TAG_TYPE)
                 {
-                    return new AtomElement(uri, local, XmlConverter.convertTypeDefinition(parser));
+                    return new AtomElement(uri, local, XmlConverter.ConvertTypeDefinition(parser));
                 }
                 else if (local == XmlConstants.TAG_CHILDREN)
                 {
@@ -477,7 +477,7 @@ namespace PortCMIS.Binding.AtomPub
             {
                 if (local == XmlConstants.TAG_REPOSITORY_INFO)
                 {
-                    return new AtomElement(uri, local, XmlConverter.convertRepositoryInfo(parser));
+                    return new AtomElement(uri, local, XmlConverter.ConvertRepositoryInfo(parser));
                 }
                 else if (local == XmlConstants.TAG_URI_TEMPLATE)
                 {
@@ -925,7 +925,7 @@ namespace PortCMIS.Binding.AtomPub
             else if (BindingConstants.RelAlternate == rel)
             {
                 // use streamId instead of type as discriminating parameter
-                string streamId = extractStreamId(link);
+                string streamId = ExtractStreamId(link);
                 if (streamId != null)
                 {
                     linkCache.Put(new string[] { link, repositoryId, id, rel }, streamId);
@@ -937,7 +937,7 @@ namespace PortCMIS.Binding.AtomPub
         /// Tries to extract a streamId from an alternate link.
         /// this is not strictly in the spec
         /// </summary>
-        protected string extractStreamId(string link)
+        protected string ExtractStreamId(string link)
         {
             int i = link.LastIndexOf('?');
             if (i > 0)
@@ -1259,7 +1259,7 @@ namespace PortCMIS.Binding.AtomPub
         /// </summary>
         public void Write(Stream outStream)
         {
-            using (XmlWriter writer = XmlUtils.createWriter(outStream))
+            using (XmlWriter writer = XmlUtils.CreateWriter(outStream))
             {
                 XmlUtils.StartXmlDocument(writer);
 
@@ -1307,19 +1307,19 @@ namespace PortCMIS.Binding.AtomPub
                 // object
                 if (objectData != null)
                 {
-                    XmlConverter.writeObject(writer, cmisVersion, XmlConstants.NAMESPACE_RESTATOM, objectData);
+                    XmlConverter.WriteObject(writer, cmisVersion, XmlConstants.NAMESPACE_RESTATOM, objectData);
                 }
 
                 // type
                 if (typeDef != null)
                 {
-                    XmlConverter.writeTypeDefinition(writer, cmisVersion, XmlConstants.NAMESPACE_RESTATOM, typeDef);
+                    XmlConverter.WriteTypeDefinition(writer, cmisVersion, XmlConstants.NAMESPACE_RESTATOM, typeDef);
                 }
 
                 // bulk update
                 if (bulkUpdate != null)
                 {
-                    XmlConverter.writeBulkUpdate(writer, XmlConstants.NAMESPACE_RESTATOM, bulkUpdate);
+                    XmlConverter.WriteBulkUpdate(writer, XmlConstants.NAMESPACE_RESTATOM, bulkUpdate);
                 }
 
                 // end entry

Modified: chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlConverter.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlConverter.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlConverter.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlConverter.cs Thu Apr 28 11:46:18 2016
@@ -40,7 +40,7 @@ namespace PortCMIS.Binding.AtomPub
         // --- writers ---
         // ---------------
 
-        public static void writeRepositoryInfo(XmlWriter writer, CmisVersion cmisVersion, string ns, IRepositoryInfo source)
+        public static void WriteRepositoryInfo(XmlWriter writer, CmisVersion cmisVersion, string ns, IRepositoryInfo source)
         {
             if (source == null)
             {
@@ -57,8 +57,8 @@ namespace PortCMIS.Binding.AtomPub
             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);
+            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);
@@ -81,15 +81,15 @@ namespace PortCMIS.Binding.AtomPub
             {
                 foreach (ExtensionFeature feature in source.ExtensionFeatures)
                 {
-                    writeExtendedFeatures(writer, cmisVersion, feature);
+                    WriteExtendedFeatures(writer, cmisVersion, feature);
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeRepositoryCapabilities(XmlWriter writer, CmisVersion cmisVersion, IRepositoryCapabilities source)
+        public static void WriteRepositoryCapabilities(XmlWriter writer, CmisVersion cmisVersion, IRepositoryCapabilities source)
         {
             if (source == null)
             {
@@ -133,7 +133,7 @@ namespace PortCMIS.Binding.AtomPub
                         }
                     }
 
-                    writeExtensions(writer, creatablePropertyTypes);
+                    WriteExtensions(writer, creatablePropertyTypes);
                     writer.WriteEndElement();
                 }
                 if (source.NewTypeSettableAttributes != null)
@@ -174,16 +174,16 @@ namespace PortCMIS.Binding.AtomPub
                             XmlConstants.TAG_CAP_NEW_TYPE_SETTABLE_ATTRIBUTES_CONTROLABLEACL,
                             newTypeSettableAttributes.CanSetControllableAcl);
 
-                    writeExtensions(writer, newTypeSettableAttributes);
+                    WriteExtensions(writer, newTypeSettableAttributes);
                     writer.WriteEndElement();
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeAclCapabilities(XmlWriter writer, CmisVersion cmisVersion, IAclCapabilities source)
+        public static void WriteAclCapabilities(XmlWriter writer, CmisVersion cmisVersion, IAclCapabilities source)
         {
             if (source == null)
             {
@@ -203,7 +203,7 @@ namespace PortCMIS.Binding.AtomPub
                     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);
+                    WriteExtensions(writer, pd);
                     writer.WriteEndElement();
                 }
             }
@@ -222,16 +222,16 @@ namespace PortCMIS.Binding.AtomPub
                         }
                     }
 
-                    writeExtensions(writer, pm);
+                    WriteExtensions(writer, pm);
                     writer.WriteEndElement();
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeExtendedFeatures(XmlWriter writer, CmisVersion cmisVersion, ExtensionFeature source)
+        public static void WriteExtendedFeatures(XmlWriter writer, CmisVersion cmisVersion, ExtensionFeature source)
         {
             if (source == null)
             {
@@ -258,7 +258,7 @@ namespace PortCMIS.Binding.AtomPub
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
@@ -266,7 +266,7 @@ namespace PortCMIS.Binding.AtomPub
         // --- definition writers ---
         // --------------------------
 
-        public static void writeTypeDefinition(XmlWriter writer, CmisVersion cmisVersion, string ns, ITypeDefinition source)
+        public static void WriteTypeDefinition(XmlWriter writer, CmisVersion cmisVersion, string ns, ITypeDefinition source)
         {
             if (source == null)
             {
@@ -347,14 +347,14 @@ namespace PortCMIS.Binding.AtomPub
                 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);
+                WriteExtensions(writer, tm);
                 writer.WriteEndElement();
             }
             if (source.PropertyDefinitions != null)
             {
                 foreach (IPropertyDefinition pd in source.PropertyDefinitions)
                 {
-                    writePropertyDefinition(writer, cmisVersion, pd);
+                    WritePropertyDefinition(writer, cmisVersion, pd);
                 }
             }
 
@@ -390,11 +390,11 @@ namespace PortCMIS.Binding.AtomPub
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writePropertyDefinition(XmlWriter writer, CmisVersion cmisVersion, IPropertyDefinition source)
+        public static void WritePropertyDefinition(XmlWriter writer, CmisVersion cmisVersion, IPropertyDefinition source)
         {
             if (source == null)
             {
@@ -459,7 +459,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.String);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 XmlUtils.Write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MAX_LENGTH, def.MaxLength);
@@ -470,7 +470,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<string>(writer, source.PropertyType, c);
+                            WriteChoice<string>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -483,7 +483,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.Id);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 if (def.Choices != null)
@@ -492,7 +492,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<string>(writer, source.PropertyType, c);
+                            WriteChoice<string>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -505,7 +505,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.Integer);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 XmlUtils.Write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MAX_VALUE, def.MaxValue);
@@ -517,7 +517,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<BigInteger>(writer, source.PropertyType, c);
+                            WriteChoice<BigInteger>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -530,7 +530,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.Boolean);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 if (def.Choices != null)
@@ -539,7 +539,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<bool>(writer, source.PropertyType, c);
+                            WriteChoice<bool>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -552,7 +552,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.DateTime);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 XmlUtils.Write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_RESOLUTION, def.DateTimeResolution);
@@ -563,7 +563,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<DateTime>(writer, source.PropertyType, c);
+                            WriteChoice<DateTime>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -576,7 +576,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.Decimal);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 XmlUtils.Write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_PROPERTY_TYPE_MAX_VALUE, def.MaxValue);
@@ -589,7 +589,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<decimal?>(writer, source.PropertyType, c);
+                            WriteChoice<decimal?>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -602,7 +602,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.Html);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 if (def.Choices != null)
@@ -611,7 +611,7 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<string>(writer, source.PropertyType, c);
+                            WriteChoice<string>(writer, source.PropertyType, c);
                         }
                     }
                 }
@@ -624,7 +624,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     PropertyData prop = new PropertyData(PropertyType.Uri);
                     prop.AddValue(def.DefaultValue);
-                    writeProperty(writer, prop, true);
+                    WriteProperty(writer, prop, true);
                 }
 
                 if (def.Choices != null)
@@ -633,17 +633,17 @@ namespace PortCMIS.Binding.AtomPub
                     {
                         if (c != null)
                         {
-                            writeChoice<string>(writer, source.PropertyType, c);
+                            WriteChoice<string>(writer, source.PropertyType, c);
                         }
                     }
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeChoice<T>(XmlWriter writer, PropertyType propType, IChoice<T> source)
+        public static void WriteChoice<T>(XmlWriter writer, PropertyType propType, IChoice<T> source)
         {
             if (source == null)
             {
@@ -705,7 +705,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     if (c != null)
                     {
-                        writeChoice<T>(writer, propType, c);
+                        WriteChoice<T>(writer, propType, c);
                     }
                 }
             }
@@ -717,12 +717,12 @@ namespace PortCMIS.Binding.AtomPub
         // --- object writers ---
         // -----------------------
 
-        public static void writeObject(XmlWriter writer, CmisVersion cmisVersion, string ns, IObjectData source)
+        public static void WriteObject(XmlWriter writer, CmisVersion cmisVersion, string ns, IObjectData source)
         {
-            writeObject(writer, cmisVersion, false, XmlConstants.TAG_OBJECT, ns, 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)
+        public static void WriteObject(XmlWriter writer, CmisVersion cmisVersion, bool root, string name, string ns, IObjectData source)
         {
             if (source == null)
             {
@@ -757,16 +757,16 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     foreach (PropertyData property in properties.PropertyList)
                     {
-                        writeProperty(writer, property, false);
+                        WriteProperty(writer, property, false);
                     }
                 }
 
-                writeExtensions(writer, properties);
+                WriteExtensions(writer, properties);
                 writer.WriteEndElement();
             }
             if (source.AllowableActions != null)
             {
-                writeAllowableActions(writer, cmisVersion, false, source.AllowableActions);
+                WriteAllowableActions(writer, cmisVersion, false, source.AllowableActions);
             }
             if (source.Relationships != null)
             {
@@ -774,7 +774,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     if (rel != null)
                     {
-                        writeObject(writer, cmisVersion, false, XmlConstants.TAG_OBJECT_RELATIONSHIP, XmlConstants.NAMESPACE_CMIS, rel);
+                        WriteObject(writer, cmisVersion, false, XmlConstants.TAG_OBJECT_RELATIONSHIP, XmlConstants.NAMESPACE_CMIS, rel);
                     }
                 }
             }
@@ -787,12 +787,12 @@ namespace PortCMIS.Binding.AtomPub
                 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);
+                WriteExtensions(writer, info);
                 writer.WriteEndElement();
             }
             if (source.Acl != null)
             {
-                writeAcl(writer, cmisVersion, false, source.Acl);
+                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)
@@ -812,7 +812,7 @@ namespace PortCMIS.Binding.AtomPub
                     }
                 }
 
-                writeExtensions(writer, pids);
+                WriteExtensions(writer, pids);
                 writer.WriteEndElement();
             }
             if (source.Renditions != null)
@@ -832,17 +832,17 @@ namespace PortCMIS.Binding.AtomPub
                         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);
+                        WriteExtensions(writer, rend);
                         writer.WriteEndElement();
                     }
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeProperty(XmlWriter writer, IPropertyData source, bool isDefaultValue)
+        public static void WriteProperty(XmlWriter writer, IPropertyData source, bool isDefaultValue)
         {
             if (source == null)
             {
@@ -951,11 +951,11 @@ namespace PortCMIS.Binding.AtomPub
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeAllowableActions(XmlWriter writer, CmisVersion cmisVersion, bool root, IAllowableActions source)
+        public static void WriteAllowableActions(XmlWriter writer, CmisVersion cmisVersion, bool root, IAllowableActions source)
         {
             if (source == null)
             {
@@ -991,11 +991,11 @@ namespace PortCMIS.Binding.AtomPub
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
-        public static void writeAcl(XmlWriter writer, CmisVersion cmisVersion, bool root, IAcl source)
+        public static void WriteAcl(XmlWriter writer, CmisVersion cmisVersion, bool root, IAcl source)
         {
             if (source == null)
             {
@@ -1028,7 +1028,7 @@ namespace PortCMIS.Binding.AtomPub
 
                             XmlUtils.Write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACE_PRINCIPAL_ID, principal.Id);
 
-                            writeExtensions(writer, principal);
+                            WriteExtensions(writer, principal);
                             writer.WriteEndElement();
                         }
                         if (ace.Permissions != null)
@@ -1040,13 +1040,13 @@ namespace PortCMIS.Binding.AtomPub
                         }
                         XmlUtils.Write(writer, XmlConstants.PREFIX_CMIS, XmlConstants.NAMESPACE_CMIS, XmlConstants.TAG_ACE_IS_DIRECT, ace.IsDirect);
 
-                        writeExtensions(writer, ace);
+                        WriteExtensions(writer, ace);
                         writer.WriteEndElement();
                     }
                 }
             }
 
-            writeExtensions(writer, source);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
@@ -1054,7 +1054,7 @@ namespace PortCMIS.Binding.AtomPub
         // --- query ---
         // -------------
 
-        public static void writeQuery(XmlWriter writer, CmisVersion cmisVersion, QueryType source)
+        public static void WriteQuery(XmlWriter writer, CmisVersion cmisVersion, QueryType source)
         {
             if (source == null)
             {
@@ -1072,7 +1072,7 @@ namespace PortCMIS.Binding.AtomPub
             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);
+            WriteExtensions(writer, source);
             writer.WriteEndElement();
         }
 
@@ -1080,7 +1080,7 @@ namespace PortCMIS.Binding.AtomPub
         // --- bulk update ---
         // -------------------
 
-        public static void writeBulkUpdate(XmlWriter writer, String ns, BulkUpdate bulkUpdate)
+        public static void WriteBulkUpdate(XmlWriter writer, String ns, BulkUpdate bulkUpdate)
         {
             if (bulkUpdate == null || bulkUpdate.ObjectIdAndChangeToken == null)
             {
@@ -1101,7 +1101,7 @@ namespace PortCMIS.Binding.AtomPub
                 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);
+                WriteExtensions(writer, idAndToken);
                 writer.WriteEndElement();
             }
 
@@ -1114,11 +1114,11 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     foreach (PropertyData property in properties.PropertyList)
                     {
-                        writeProperty(writer, property, false);
+                        WriteProperty(writer, property, false);
                     }
                 }
 
-                writeExtensions(writer, properties);
+                WriteExtensions(writer, properties);
                 writer.WriteEndElement();
             }
 
@@ -1145,7 +1145,7 @@ namespace PortCMIS.Binding.AtomPub
         // --- extension writers ---
         // -------------------------
 
-        public static void writeExtensions(XmlWriter writer, IExtensionsData source)
+        public static void WriteExtensions(XmlWriter writer, IExtensionsData source)
         {
             if (source == null)
             {
@@ -1163,12 +1163,12 @@ namespace PortCMIS.Binding.AtomPub
                         continue;
                     }
 
-                    writeExtensionElement(writer, element, ns);
+                    WriteExtensionElement(writer, element, ns);
                 }
             }
         }
 
-        private static void writeExtensionElement(XmlWriter writer, ICmisExtensionElement source, IList<string> ns)
+        private static void WriteExtensionElement(XmlWriter writer, ICmisExtensionElement source, IList<string> ns)
         {
             if (source == null || source.Name == null)
             {
@@ -1226,7 +1226,7 @@ namespace PortCMIS.Binding.AtomPub
                 {
                     foreach (ICmisExtensionElement child in source.Children)
                     {
-                        writeExtensionElement(writer, child, ns);
+                        WriteExtensionElement(writer, child, ns);
                     }
                 }
             }
@@ -1243,37 +1243,37 @@ namespace PortCMIS.Binding.AtomPub
         // --- parsers ---
         // ---------------
 
-        public static RepositoryInfo convertRepositoryInfo(XmlReader parser)
+        public static RepositoryInfo ConvertRepositoryInfo(XmlReader parser)
         {
             return REPOSITORY_INFO_PARSER.Walk(parser);
         }
 
-        public static ITypeDefinition convertTypeDefinition(XmlReader parser)
+        public static ITypeDefinition ConvertTypeDefinition(XmlReader parser)
         {
             return TYPE_DEF_PARSER.Walk(parser);
         }
 
-        public static IObjectData convertObject(XmlReader parser)
+        public static IObjectData ConvertObject(XmlReader parser)
         {
             return OBJECT_PARSER.Walk(parser);
         }
 
-        public static QueryType convertQuery(XmlReader parser)
+        public static QueryType ConvertQuery(XmlReader parser)
         {
             return QUERY_PARSER.Walk(parser);
         }
 
-        public static IAllowableActions convertAllowableActions(XmlReader parser)
+        public static IAllowableActions ConvertAllowableActions(XmlReader parser)
         {
             return ALLOWABLE_ACTIONS_PARSER.Walk(parser);
         }
 
-        public static IAcl convertAcl(XmlReader parser)
+        public static IAcl ConvertAcl(XmlReader parser)
         {
             return ACL_PARSER.Walk(parser);
         }
 
-        public static BulkUpdate convertBulkUpdate(XmlReader parser)
+        public static BulkUpdate ConvertBulkUpdate(XmlReader parser)
         {
             return BULK_UPDATE_PARSER.Walk(parser);
         }

Modified: chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlUtils.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlUtils.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlUtils.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/binding/atompub/XmlUtils.cs Thu Apr 28 11:46:18 2016
@@ -41,7 +41,7 @@ namespace PortCMIS.Binding.AtomPub
         /// <summary>
         /// Creates a new XML writer.
         /// </summary>
-        public static XmlWriter createWriter(Stream stream)
+        public static XmlWriter CreateWriter(Stream stream)
         {
             XmlWriterSettings settings = new XmlWriterSettings();
             settings.Encoding = Encoding.UTF8;
@@ -101,7 +101,7 @@ namespace PortCMIS.Binding.AtomPub
                 return;
             }
 
-            Write(writer, prefix, ns, tag, ((BigInteger)value).ToString("#", CultureInfo.InvariantCulture));
+            Write(writer, prefix, ns, tag, ((BigInteger)value).ToString("0", CultureInfo.InvariantCulture));
         }
 
         /// <summary>

Modified: chemistry/portcmis/trunk/PortCMIS/binding/browser/BrowserBinding.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/binding/browser/BrowserBinding.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/binding/browser/BrowserBinding.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/binding/browser/BrowserBinding.cs Thu Apr 28 11:46:18 2016
@@ -1931,7 +1931,7 @@ namespace PortCMIS.Binding.Browser
             objectId = (newObj == null ? null : newObj.Id);
         }
 
-        public IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+        public IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
             string filter, bool? includeAllowableActions, IncludeRelationships? includeRelationships,
             string renditionFilter, bool? includePolicyIds, bool? includeAcl, IExtensionsData extension)
         {
@@ -1943,7 +1943,7 @@ namespace PortCMIS.Binding.Browser
             url.AddParameter(BindingConstants.ParamRenditionfilter, renditionFilter);
             url.AddParameter(BindingConstants.ParamPolicyIds, includePolicyIds);
             url.AddParameter(BindingConstants.ParamAcl, includeAcl);
-            url.AddParameter(BindingConstants.ParamReturnVersion, (!major ? ReturnVersion.Latest : ReturnVersion.LatestMajor));
+            url.AddParameter(BindingConstants.ParamReturnVersion, (major == true ? ReturnVersion.LatestMajor : ReturnVersion.Latest));
             url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
             url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
 
@@ -1957,13 +1957,13 @@ namespace PortCMIS.Binding.Browser
             return JsonConverter.ConvertObject(json, typeCache);
         }
 
-        public IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
+        public IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool? major,
             string filter, IExtensionsData extension)
         {
             // build URL
             UrlBuilder url = GetObjectUrl(repositoryId, objectId, BindingConstants.SelectorProperties);
             url.AddParameter(BindingConstants.ParamFilter, filter);
-            url.AddParameter(BindingConstants.ParamReturnVersion, (!major ? ReturnVersion.Latest : ReturnVersion.LatestMajor));
+            url.AddParameter(BindingConstants.ParamReturnVersion, (major == true ? ReturnVersion.LatestMajor : ReturnVersion.Latest));
             url.AddParameter(BindingConstants.ParamSuccinct, SuccinctParameter);
             url.AddParameter(BindingConstants.ParamDateTimeFormat, DateTimeFormatParameter);
 

Modified: chemistry/portcmis/trunk/PortCMIS/client/SessionParameter.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/client/SessionParameter.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/client/SessionParameter.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/client/SessionParameter.cs Thu Apr 28 11:46:18 2016
@@ -133,6 +133,10 @@ namespace PortCMIS.Client
 
         /// <summary>Defines if the document name should be added to the properties on check in if no properties are updated ("true" or "false")
         /// (Workaround for SharePoint 2010 and SharePoint 2013)</summary>
-        public const string OmitChangeTokens = "org.apache.chemistry.opencmis.portcmis.omitChangeTokens";
+        public const string OmitChangeTokens = "org.apache.chemistry.portcmis.workaround.omitChangeTokens";
+
+        /// <summary>Defines if the document name should be added to the properties on check in if no properties are updated
+        /// (Workaround for SharePoint 2010 and SharePoint 2013)</summary>
+        public const string AddNameOnCheckIn = "org.apache.chemistry.portcmis.workaround.addNameOnCheckIn";
     }
 }
\ No newline at end of file

Modified: chemistry/portcmis/trunk/PortCMIS/data/DataImpl.cs
URL: http://svn.apache.org/viewvc/chemistry/portcmis/trunk/PortCMIS/data/DataImpl.cs?rev=1741415&r1=1741414&r2=1741415&view=diff
==============================================================================
--- chemistry/portcmis/trunk/PortCMIS/data/DataImpl.cs (original)
+++ chemistry/portcmis/trunk/PortCMIS/data/DataImpl.cs Thu Apr 28 11:46:18 2016
@@ -914,6 +914,7 @@ namespace PortCMIS.Data
                 }
             }
         }
+
         /// <inheritdoc/>
         public object FirstValue { get { return values == null || Values.Count < 1 ? null : values[0]; } }
 



Mime
View raw message