﻿/*
 * 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 System;
using System.Collections.Generic;
using System.ServiceModel;
using DotCMIS.Binding.Impl;
using DotCMIS.Binding.Services;
using DotCMIS.CMISWebServicesReference;
using DotCMIS.Data;
using DotCMIS.Data.Extensions;
using DotCMIS.Exceptions;
using DotCMIS.Enums;

namespace DotCMIS.Binding.WebServices
{
    /// <summary>
    /// Web Services binding SPI.
    /// </summary>
    internal class CmisWebServicesSpi : ICmisSpi
    {
        private RepositoryService repositoryService;
        private NavigationService navigationService;
        private ObjectService objectService;
        private VersioningService versioningService;
        private DiscoveryService discoveryService;
        private MultiFilingService multiFilingService;
        private RelationshipService relationshipService;
        private PolicyService policyService;
        private AclService aclService;

        public void initialize(BindingSession session)
        {
            PortProvider provider = new PortProvider(session);

            repositoryService = new RepositoryService(session, provider);
            navigationService = new NavigationService(session, provider);
            objectService = new ObjectService(session, provider);
            versioningService = new VersioningService(session, provider);
            discoveryService = new DiscoveryService(session, provider);
            multiFilingService = new MultiFilingService(session, provider);
            relationshipService = new RelationshipService(session, provider);
            policyService = new PolicyService(session, provider);
            aclService = new AclService(session, provider);
        }

        public IRepositoryService GetRepositoryService()
        {
            return repositoryService;
        }

        public INavigationService GetNavigationService()
        {
            return navigationService;
        }

        public IObjectService GetObjectService()
        {
            return objectService;
        }

        public IVersioningService GetVersioningService()
        {
            return versioningService;
        }

        public IRelationshipService GetRelationshipService()
        {
            return relationshipService;
        }

        public IDiscoveryService GetDiscoveryService()
        {
            return discoveryService;
        }

        public IMultiFilingService GetMultiFilingService()
        {
            return multiFilingService;
        }

        public IAclService GetAclService()
        {
            return aclService;
        }

        public IPolicyService GetPolicyService()
        {
            return policyService;
        }

        public void ClearAllCaches()
        {
            // nothing to do
        }

        public void ClearRepositoryCache(string repositoryId)
        {
            // nothing to do
        }

        public void Close()
        {
            // nothing to do
        }
    }

    internal class PortProvider
    {
        [ThreadStatic]
        private static IDictionary<int, IDictionary<string, object>> Services;

        private BindingSession session;

        public PortProvider(BindingSession session)
        {
            this.session = session;
        }

        private static IDictionary<string, object> GetServiceDictionary(BindingSession session)
        {
            if (Services == null)
            {
                Services = new Dictionary<int, IDictionary<string, object>>();
            }

            IDictionary<string, object> serviceDict;
            if (Services.TryGetValue(session.GetHashCode(), out serviceDict))
            {
                return serviceDict;
            }

            serviceDict = new Dictionary<string, object>();
            Services[session.GetHashCode()] = serviceDict;

            return serviceDict;
        }

        public RepositoryServicePortClient GetRepositoryServicePort()
        {
            return (RepositoryServicePortClient)GetPortObject(SessionParameter.WebServicesRepositoryService);
        }

        public NavigationServicePortClient GetNavigationService()
        {
            return (NavigationServicePortClient)GetPortObject(SessionParameter.WebServicesNavigationService);
        }

        public ObjectServicePortClient GetObjectService()
        {
            return (ObjectServicePortClient)GetPortObject(SessionParameter.WebServicesObjectService);
        }

        public VersioningServicePortClient GetVersioningService()
        {
            return (VersioningServicePortClient)GetPortObject(SessionParameter.WebServicesVersioningService);
        }

        public DiscoveryServicePortClient GetDiscoveryService()
        {
            return (DiscoveryServicePortClient)GetPortObject(SessionParameter.WebServicesDiscoveryService);
        }

        public MultiFilingServicePortClient GetMultiFilingService()
        {
            return (MultiFilingServicePortClient)GetPortObject(SessionParameter.WebServicesMultifilingService);
        }

        public RelationshipServicePortClient GetRelationshipService()
        {
            return (RelationshipServicePortClient)GetPortObject(SessionParameter.WebServicesRelationshipService);
        }

        public PolicyServicePortClient GetPolicyService()
        {
            return (PolicyServicePortClient)GetPortObject(SessionParameter.WebServicesPolicyService);
        }

        public ACLServicePortClient GetAclService()
        {
            return (ACLServicePortClient)GetPortObject(SessionParameter.WebServicesAclService);
        }

        private object GetPortObject(string serviceKey)
        {
            IDictionary<string, object> servicesDict = GetServiceDictionary(session);

            object portObject;
            if (!servicesDict.TryGetValue(serviceKey, out portObject))
            {
                portObject = InitServiceObject(serviceKey);
                servicesDict[serviceKey] = portObject;
            }

            return portObject;
        }

        private object InitServiceObject(string serviceKey)
        {
            object portObject = null;

            BasicHttpBinding binding = new BasicHttpBinding();
            binding.MessageEncoding = WSMessageEncoding.Mtom;
            binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
            binding.TransferMode = TransferMode.Streamed;

            long messageSize = session.GetValue(SessionParameter.MessageSize, 4 * 1024 * 1024);
            binding.MaxReceivedMessageSize = messageSize;
            binding.MaxBufferSize = (messageSize > Int32.MaxValue ? Int32.MaxValue : (int)messageSize);

            if (serviceKey == SessionParameter.WebServicesRepositoryService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesRepositoryService) as string;
                portObject = new RepositoryServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesNavigationService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesNavigationService) as string;
                portObject = new NavigationServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesObjectService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesObjectService) as string;
                portObject = new ObjectServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesVersioningService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesVersioningService) as string;
                portObject = new VersioningServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesDiscoveryService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesDiscoveryService) as string;
                portObject = new DiscoveryServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesRelationshipService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesRelationshipService) as string;
                portObject = new RelationshipServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesMultifilingService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesMultifilingService) as string;
                portObject = new MultiFilingServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesPolicyService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesPolicyService) as string;
                portObject = new PolicyServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }
            else if (serviceKey == SessionParameter.WebServicesAclService)
            {
                string wsdlUrl = session.GetValue(SessionParameter.WebServicesAclService) as string;
                portObject = new ACLServicePortClient(binding, new EndpointAddress(wsdlUrl));
            }

            AbstractAuthenticationProvider authenticationProvider = session.GetAuthenticationProvider();
            if (authenticationProvider != null)
            {
                authenticationProvider.Authenticate(portObject);
            }

            return portObject;
        }
    }

    /// <summary>
    /// Common service methods.
    /// </summary>
    internal abstract class AbstractWebServicesService
    {
        protected BindingSession Session { get; set; }

        protected PortProvider Provider { get; set; }

        protected CmisBaseException ConvertException(FaultException<cmisFaultType> fault)
        {
            if ((fault == null) || (fault.Detail == null))
            {
                return new CmisRuntimeException("CmisException has no fault!");
            }

            String msg = fault.Detail.message;
            long? code = null;

            try
            {
                code = Int64.Parse(fault.Detail.code);
            }
            catch (Exception)
            {
                // ignore
            }

            switch (fault.Detail.type)
            {
                case enumServiceException.constraint:
                    return new CmisConstraintException(msg, code);
                case enumServiceException.contentAlreadyExists:
                    return new CmisContentAlreadyExistsException(msg, code);
                case enumServiceException.filterNotValid:
                    return new CmisFilterNotValidException(msg, code);
                case enumServiceException.invalidArgument:
                    return new CmisInvalidArgumentException(msg, code);
                case enumServiceException.nameConstraintViolation:
                    return new CmisNameConstraintViolationException(msg, code);
                case enumServiceException.notSupported:
                    return new CmisNotSupportedException(msg, code);
                case enumServiceException.objectNotFound:
                    return new CmisObjectNotFoundException(msg, code);
                case enumServiceException.permissionDenied:
                    return new CmisPermissionDeniedException(msg, code);
                case enumServiceException.runtime:
                    return new CmisRuntimeException(msg, code);
                case enumServiceException.storage:
                    return new CmisStorageException(msg, code);
                case enumServiceException.streamNotSupported:
                    return new CmisStreamNotSupportedException(msg, code);
                case enumServiceException.updateConflict:
                    return new CmisUpdateConflictException(msg, code);
                case enumServiceException.versioning:
                    return new CmisVersioningException(msg, code);
            }

            return new CmisRuntimeException("Unknown exception[" + fault.Detail.type + "]: " + msg);
        }
    }

    internal class RepositoryService : AbstractWebServicesService, IRepositoryService
    {
        public RepositoryService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public IList<IRepositoryInfo> GetRepositoryInfos(IExtensionsData extension)
        {
            RepositoryServicePortClient port = Provider.GetRepositoryServicePort();

            try
            {
                cmisRepositoryEntryType[] entries = port.getRepositories(Converter.ConvertExtension(extension));

                if (entries == null)
                {
                    return null;
                }

                IList<IRepositoryInfo> result = new List<IRepositoryInfo>();
                foreach (cmisRepositoryEntryType entry in entries)
                {
                    cmisRepositoryInfoType info = port.getRepositoryInfo(entry.repositoryId, null);
                    result.Add(Converter.Convert(info));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IRepositoryInfo GetRepositoryInfo(string repositoryId, IExtensionsData extension)
        {
            RepositoryServicePortClient port = Provider.GetRepositoryServicePort();

            try
            {
                return Converter.Convert(port.getRepositoryInfo(repositoryId, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public ITypeDefinitionList GetTypeChildren(string repositoryId, string typeId, bool? includePropertyDefinitions,
                long? maxItems, long? skipCount, IExtensionsData extension)
        {
            RepositoryServicePortClient port = Provider.GetRepositoryServicePort();

            try
            {
                return Converter.Convert(port.getTypeChildren(repositoryId, typeId, includePropertyDefinitions,
                    maxItems.ToString(), skipCount.ToString(), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<ITypeDefinitionContainer> GetTypeDescendants(string repositoryId, string typeId, long? depth,
                bool? includePropertyDefinitions, IExtensionsData extension)
        {
            RepositoryServicePortClient port = Provider.GetRepositoryServicePort();

            try
            {
                cmisTypeContainer[] descendants = port.getTypeDescendants(
                    repositoryId, typeId, depth.ToString(), includePropertyDefinitions, Converter.ConvertExtension(extension));

                if (descendants == null)
                {
                    return null;
                }

                List<ITypeDefinitionContainer> result = new List<ITypeDefinitionContainer>();
                foreach (cmisTypeContainer container in descendants)
                {
                    result.Add(Converter.Convert(container));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public ITypeDefinition GetTypeDefinition(string repositoryId, string typeId, IExtensionsData extension)
        {
            RepositoryServicePortClient port = Provider.GetRepositoryServicePort();

            try
            {
                return Converter.Convert(port.getTypeDefinition(repositoryId, typeId, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class NavigationService : AbstractWebServicesService, INavigationService
    {
        public NavigationService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public IObjectInFolderList GetChildren(string repositoryId, string folderId, string filter, string orderBy,
            bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
            bool? includePathSegment, long? maxItems, long? skipCount, IExtensionsData extension)
        {
            NavigationServicePortClient port = Provider.GetNavigationService();

            try
            {
                return Converter.Convert(port.getChildren(repositoryId, folderId, filter, orderBy, includeAllowableActions,
                    (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships), renditionFilter,
                    includePathSegment, maxItems.ToString(), skipCount.ToString(), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<IObjectInFolderContainer> GetDescendants(string repositoryId, string folderId, long? depth, string filter,
            bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
            bool? includePathSegment, IExtensionsData extension)
        {
            NavigationServicePortClient port = Provider.GetNavigationService();

            try
            {
                cmisObjectInFolderContainerType[] descendants = port.getDescendants(repositoryId, folderId, filter, depth.ToString(),
                    includeAllowableActions, (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships),
                    renditionFilter, includePathSegment, Converter.ConvertExtension(extension));

                if (descendants == null)
                {
                    return null;
                }

                List<IObjectInFolderContainer> result = new List<IObjectInFolderContainer>();
                foreach (cmisObjectInFolderContainerType container in descendants)
                {
                    result.Add(Converter.Convert(container));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<IObjectInFolderContainer> GetFolderTree(string repositoryId, string folderId, long? depth, string filter,
            bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
            bool? includePathSegment, IExtensionsData extension)
        {
            NavigationServicePortClient port = Provider.GetNavigationService();

            try
            {
                cmisObjectInFolderContainerType[] descendants = port.getFolderTree(repositoryId, folderId, filter, depth.ToString(),
                    includeAllowableActions, (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships),
                    renditionFilter, includePathSegment, Converter.ConvertExtension(extension));

                if (descendants == null)
                {
                    return null;
                }

                List<IObjectInFolderContainer> result = new List<IObjectInFolderContainer>();
                foreach (cmisObjectInFolderContainerType container in descendants)
                {
                    result.Add(Converter.Convert(container));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<IObjectParentData> GetObjectParents(string repositoryId, string objectId, string filter,
            bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
            bool? includeRelativePathSegment, IExtensionsData extension)
        {
            NavigationServicePortClient port = Provider.GetNavigationService();

            try
            {
                cmisObjectParentsType[] parents = port.getObjectParents(repositoryId, objectId, filter,
                    includeAllowableActions, (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships),
                    renditionFilter, includeRelativePathSegment, Converter.ConvertExtension(extension));

                if (parents == null)
                {
                    return null;
                }

                List<IObjectParentData> result = new List<IObjectParentData>();
                foreach (cmisObjectParentsType parent in parents)
                {
                    result.Add(Converter.Convert(parent));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IObjectData GetFolderParent(string repositoryId, string folderId, string filter, ExtensionsData extension)
        {
            NavigationServicePortClient port = Provider.GetNavigationService();

            try
            {
                return Converter.Convert(port.getFolderParent(repositoryId, folderId, filter, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IObjectList GetCheckedOutDocs(string repositoryId, string folderId, string filter, string orderBy,
            bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
            long? maxItems, long? skipCount, IExtensionsData extension)
        {
            NavigationServicePortClient port = Provider.GetNavigationService();

            try
            {
                return Converter.Convert(port.getCheckedOutDocs(repositoryId, folderId, filter, orderBy, includeAllowableActions,
                    (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships), renditionFilter,
                    maxItems.ToString(), skipCount.ToString(), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class ObjectService : AbstractWebServicesService, IObjectService
    {
        public ObjectService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public string CreateDocument(string repositoryId, IProperties properties, string folderId, IContentStream contentStream,
            VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                string objectId = port.createDocument(repositoryId, Converter.Convert(properties), folderId, Converter.Convert(contentStream),
                    (enumVersioningState?)CmisValue.CmisToSerializerEnum(versioningState), Converter.ConvertList(policies),
                    Converter.Convert(addAces), Converter.Convert(removeAces), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);

                return objectId;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public string CreateDocumentFromSource(string repositoryId, string sourceId, IProperties properties, string folderId,
            VersioningState? versioningState, IList<string> policies, IAcl addAces, IAcl removeAces, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                string objectId = port.createDocumentFromSource(repositoryId, sourceId, Converter.Convert(properties), folderId,
                    (enumVersioningState?)CmisValue.CmisToSerializerEnum(versioningState), Converter.ConvertList(policies),
                    Converter.Convert(addAces), Converter.Convert(removeAces), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);

                return objectId;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public string CreateFolder(string repositoryId, IProperties properties, string folderId, IList<string> policies,
            IAcl addAces, IAcl removeAces, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                string objectId = port.createFolder(repositoryId, Converter.Convert(properties), folderId,
                    Converter.ConvertList(policies), Converter.Convert(addAces), Converter.Convert(removeAces), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);

                return objectId;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public string CreateRelationship(string repositoryId, IProperties properties, IList<string> policies, IAcl addAces,
            IAcl removeAces, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                string objectId = port.createRelationship(repositoryId, Converter.Convert(properties), Converter.ConvertList(policies),
                    Converter.Convert(addAces), Converter.Convert(removeAces), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);

                return objectId;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }

        }

        public string CreatePolicy(string repositoryId, IProperties properties, string folderId, IList<string> policies,
            IAcl addAces, IAcl removeAces, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                string objectId = port.createPolicy(repositoryId, Converter.Convert(properties), folderId,
                    Converter.ConvertList(policies), Converter.Convert(addAces), Converter.Convert(removeAces), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);

                return objectId;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IAllowableActions GetAllowableActions(string repositoryId, string objectId, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                return Converter.Convert(port.getAllowableActions(repositoryId, objectId, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IProperties GetProperties(string repositoryId, string objectId, string filter, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                return Converter.Convert(port.getProperties(repositoryId, objectId, filter, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<IRenditionData> GetRenditions(string repositoryId, string objectId, string renditionFilter,
            long? maxItems, long? skipCount, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisRenditionType[] renditions = port.getRenditions(repositoryId, objectId, renditionFilter,
                    maxItems.ToString(), skipCount.ToString(), Converter.ConvertExtension(extension));

                if (renditions == null)
                {
                    return null;
                }

                IList<IRenditionData> result = new List<IRenditionData>();
                foreach (cmisRenditionType rendition in renditions)
                {
                    result.Add(Converter.Convert(rendition));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IObjectData GetObject(string repositoryId, string objectId, string filter, bool? includeAllowableActions,
            IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds,
            bool? includeAcl, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                return Converter.Convert(port.getObject(repositoryId, objectId, filter, includeAllowableActions,
                    (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships), renditionFilter,
                    includePolicyIds, includeAcl, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IObjectData GetObjectByPath(string repositoryId, string path, string filter, bool? includeAllowableActions,
            IncludeRelationships? includeRelationships, string renditionFilter, bool? includePolicyIds, bool? includeAcl,
            IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                return Converter.Convert(port.getObjectByPath(repositoryId, path, filter, includeAllowableActions,
                    (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships), renditionFilter,
                    includePolicyIds, includeAcl, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IContentStream GetContentStream(string repositoryId, string objectId, string streamId, long? offset, long? length,
            IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                return Converter.Convert(port.getContentStream(
                    repositoryId, objectId, streamId, offset.ToString(), length.ToString(), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void UpdateProperties(string repositoryId, ref string objectId, ref string changeToken, IProperties properties,
            IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.updateProperties(repositoryId, ref objectId, ref changeToken, Converter.Convert(properties), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void MoveObject(string repositoryId, ref string objectId, string targetFolderId, string sourceFolderId,
            IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.moveObject(repositoryId, ref objectId, targetFolderId, sourceFolderId, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void DeleteObject(string repositoryId, string objectId, bool? allVersions, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.deleteObject(repositoryId, objectId, allVersions, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IFailedToDeleteData DeleteTree(string repositoryId, string folderId, bool? allVersions, UnfileObject? unfileObjects,
            bool? continueOnFailure, ExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                return Converter.Convert(port.deleteTree(repositoryId, folderId, allVersions,
                    (enumUnfileObject?)CmisValue.CmisToSerializerEnum(unfileObjects), continueOnFailure,
                    Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void SetContentStream(string repositoryId, ref string objectId, bool? overwriteFlag, ref string changeToken,
            IContentStream contentStream, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.setContentStream(repositoryId, ref objectId, overwriteFlag, ref changeToken,
                    Converter.Convert(contentStream), ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void DeleteContentStream(string repositoryId, ref string objectId, ref string changeToken, IExtensionsData extension)
        {
            ObjectServicePortClient port = Provider.GetObjectService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.deleteContentStream(repositoryId, ref objectId, ref changeToken, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class VersioningService : AbstractWebServicesService, IVersioningService
    {
        public VersioningService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public void CheckOut(string repositoryId, ref string objectId, IExtensionsData extension, out bool? contentCopied)
        {
            VersioningServicePortClient port = Provider.GetVersioningService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                contentCopied = port.checkOut(repositoryId, ref objectId, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void CancelCheckOut(string repositoryId, string objectId, IExtensionsData extension)
        {
            VersioningServicePortClient port = Provider.GetVersioningService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.cancelCheckOut(repositoryId, objectId, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
            IContentStream contentStream, string checkinComment, List<string> policies, IAcl addAces, IAcl removeAces,
            IExtensionsData extension)
        {
            VersioningServicePortClient port = Provider.GetVersioningService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.checkIn(repositoryId, ref objectId, major, Converter.Convert(properties), Converter.Convert(contentStream),
                    checkinComment, Converter.ConvertList(policies), Converter.Convert(addAces), Converter.Convert(removeAces),
                    ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        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)
        {
            VersioningServicePortClient port = Provider.GetVersioningService();

            try
            {
                return Converter.Convert(port.getObjectOfLatestVersion(repositoryId, versionSeriesId, major, filter,
                    includeAllowableActions, (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships),
                    renditionFilter, includePolicyIds, includeAcl, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IProperties GetPropertiesOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
            string filter, IExtensionsData extension)
        {
            VersioningServicePortClient port = Provider.GetVersioningService();

            try
            {
                return Converter.Convert(port.getPropertiesOfLatestVersion(repositoryId, versionSeriesId, major, filter,
                    Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<IObjectData> GetAllVersions(string repositoryId, string objectId, string versionSeriesId, string filter,
            bool? includeAllowableActions, IExtensionsData extension)
        {
            VersioningServicePortClient port = Provider.GetVersioningService();

            try
            {
                cmisObjectType[] versions = port.getAllVersions(repositoryId, versionSeriesId, filter, includeAllowableActions,
                    Converter.ConvertExtension(extension));

                if (versions == null)
                {
                    return null;
                }

                IList<IObjectData> result = new List<IObjectData>();
                foreach (cmisObjectType version in versions)
                {
                    result.Add(Converter.Convert(version));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class RelationshipService : AbstractWebServicesService, IRelationshipService
    {
        public RelationshipService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public IObjectList GetObjectRelationships(string repositoryId, string objectId, bool? includeSubRelationshipTypes,
            RelationshipDirection? relationshipDirection, string typeId, string filter, bool? includeAllowableActions,
            long? maxItems, long? skipCount, IExtensionsData extension)
        {
            RelationshipServicePortClient port = Provider.GetRelationshipService();

            try
            {
                return Converter.Convert(port.getObjectRelationships(repositoryId, objectId,
                    includeSubRelationshipTypes == null ? true : (bool)includeSubRelationshipTypes,
                    (enumRelationshipDirection?)CmisValue.CmisToSerializerEnum(relationshipDirection), typeId, filter, includeAllowableActions,
                    maxItems.ToString(), skipCount.ToString(), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class DiscoveryService : AbstractWebServicesService, IDiscoveryService
    {
        public DiscoveryService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public IObjectList Query(string repositoryId, string statement, bool? searchAllVersions,
            bool? includeAllowableActions, IncludeRelationships? includeRelationships, string renditionFilter,
            long? maxItems, long? skipCount, IExtensionsData extension)
        {
            DiscoveryServicePortClient port = Provider.GetDiscoveryService();

            try
            {
                return Converter.Convert(port.query(repositoryId, statement, searchAllVersions, includeAllowableActions,
                    (enumIncludeRelationships?)CmisValue.CmisToSerializerEnum(includeRelationships), renditionFilter,
                    maxItems.ToString(), skipCount.ToString(), Converter.ConvertExtension(extension), null));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IObjectList GetContentChanges(string repositoryId, ref string changeLogToken, bool? includeProperties,
           string filter, bool? includePolicyIds, bool? includeAcl, long? maxItems, IExtensionsData extension)
        {
            DiscoveryServicePortClient port = Provider.GetDiscoveryService();

            try
            {
                return Converter.Convert(port.getContentChanges(repositoryId, ref changeLogToken, includeProperties, filter,
                    includePolicyIds, includeAcl, maxItems.ToString(), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class MultiFilingService : AbstractWebServicesService, IMultiFilingService
    {
        public MultiFilingService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public void AddObjectToFolder(string repositoryId, string objectId, string folderId, bool? allVersions, IExtensionsData extension)
        {
            MultiFilingServicePortClient port = Provider.GetMultiFilingService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.addObjectToFolder(repositoryId, objectId, folderId, allVersions == null ? true : (bool)allVersions, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void RemoveObjectFromFolder(string repositoryId, string objectId, string folderId, IExtensionsData extension)
        {
            MultiFilingServicePortClient port = Provider.GetMultiFilingService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.removeObjectFromFolder(repositoryId, objectId, folderId, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class AclService : AbstractWebServicesService, IAclService
    {
        public AclService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public IAcl GetAcl(string repositoryId, string objectId, bool? onlyBasicPermissions, IExtensionsData extension)
        {
            ACLServicePortClient port = Provider.GetAclService();

            try
            {
                return Converter.Convert(port.getACL(repositoryId, objectId, onlyBasicPermissions, Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IAcl ApplyAcl(string repositoryId, string objectId, IAcl addAces, IAcl removeAces, AclPropagation? aclPropagation,
            IExtensionsData extension)
        {
            ACLServicePortClient port = Provider.GetAclService();

            try
            {
                return Converter.Convert(port.applyACL(repositoryId, objectId, Converter.Convert(addAces), Converter.Convert(removeAces),
                    (enumACLPropagation?)CmisValue.CmisToSerializerEnum(aclPropagation), Converter.ConvertExtension(extension)));
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }

    internal class PolicyService : AbstractWebServicesService, IPolicyService
    {
        public PolicyService(BindingSession session, PortProvider provider)
        {
            Session = session;
            Provider = provider;
        }

        public void ApplyPolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension)
        {
            PolicyServicePortClient port = Provider.GetPolicyService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.applyPolicy(repositoryId, policyId, objectId, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public void RemovePolicy(string repositoryId, string policyId, string objectId, IExtensionsData extension)
        {
            PolicyServicePortClient port = Provider.GetPolicyService();

            try
            {
                cmisExtensionType cmisExtension = Converter.ConvertExtension(extension);

                port.removePolicy(repositoryId, policyId, objectId, ref cmisExtension);

                Converter.ConvertExtension(cmisExtension, extension);
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }

        public IList<IObjectData> GetAppliedPolicies(string repositoryId, string objectId, string filter, IExtensionsData extension)
        {
            PolicyServicePortClient port = Provider.GetPolicyService();

            try
            {
                cmisObjectType[] policies = port.getAppliedPolicies(repositoryId, objectId, filter, Converter.ConvertExtension(extension));

                if (policies == null)
                {
                    return null;
                }

                List<IObjectData> result = new List<IObjectData>();
                foreach (cmisObjectType policy in policies)
                {
                    result.Add(Converter.Convert(policy));
                }

                return result;
            }
            catch (FaultException<cmisFaultType> fe)
            {
                throw ConvertException(fe);
            }
            catch (Exception e)
            {
                throw new CmisRuntimeException("Error: " + e.Message, e);
            }
        }
    }
}
