public DecodingContext()
 {
     objectHandles = new Dictionary<int, ObjectHandlesType>();
     sessionFastTransferStreamType = new Dictionary<int, FastTransferStreamType>();
     streamType_Getbuffer = new FastTransferStreamType();
     getBuffer_InPutHandles = new Dictionary<int, int>();
     putBuffer_InPutHandles = new Dictionary<int, int>();
     copyTo_InputHandles = new Dictionary<int, int>();
     copyProperties_InputHandles = new Dictionary<int, int>();
     copyTo_OutputHandles = new Dictionary<int, int>();
     copyProperties_OutputHandles = new Dictionary<int, int>();
     copyMessage_OutputHandles = new Dictionary<int, int>();
     copyFolder_OutputHandles = new Dictionary<int, int>();
     syncGetTransferState_OutputHandles = new Dictionary<int, int>();
     syncConfigure_OutputHandles = new Dictionary<int, int>();
     destinationConfigure_OutputHandles = new Dictionary<int, int>();
     destinationConfigure_InputHandles = new Dictionary<int, int>();
     sessionObjectHandles = new Dictionary<int, Dictionary<int, ObjectHandlesType>>();
     sessionPropertyTags = new Dictionary<int, PropertyTag[]>();
     sessionLogId = new Dictionary<int, byte>();
     sessionRequestRemainSize = new Dictionary<int, List<uint>>();
     setColumnProTagMap_Handle = new Dictionary<int, Dictionary<uint, PropertyTag[]>>();
     setColumnProTagMap_Index = new Dictionary<int, Dictionary<uint, PropertyTag[]>>();
 }
        /// <summary>
        /// Define the scope and parameters of the synchronization download operation. 
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="folderHandleIndex">The server object handle index.</param>
        /// <param name="synchronizationType">The type of synchronization requested: contents or hierarchy.</param>
        /// <param name="option">Defines the parameters of a download operation.</param>
        /// <param name="synchronizationFlag">Flag structure that defines the parameters of the synchronization operation.</param>
        /// <param name="synchronizationExtraFlag">Extra flag structure that defines the parameters of the synchronization operation.</param>
        /// <param name="property">A list of properties and subobjects to exclude or include.</param>
        /// <param name="downloadcontextHandleIndex">Synchronization download context handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult SynchronizationConfigure(int serverId, int folderHandleIndex, SynchronizationTypes synchronizationType, SendOptionAlls option, SynchronizationFlag synchronizationFlag, SynchronizationExtraFlag synchronizationExtraFlag, Sequence<string> property, out int downloadcontextHandleIndex)
        {
            // Initialize ROP data.
            downloadcontextHandleIndex = -1;
            uint objHandle = this.handleContainer[folderHandleIndex];
            RopSynchronizationConfigureRequest synchronizationConfigureRequest;
            RopResult result = RopResult.InvalidParameter;
            switch (synchronizationType)
            {
                case SynchronizationTypes.Hierarchy:
                    this.streamType = FastTransferStreamType.hierarchySync;
                    break;
                case SynchronizationTypes.Contents:
                    this.streamType = FastTransferStreamType.contentsSync;
                    break;
                default:
                    break;
            }

            PropertyTag[] propertyTags = new PropertyTag[property.Count];
            for (int i = 0; i < property.Count; i++)
            {
                propertyTags[i] = this.propertyTagsDictionary[property[i]];
            }

            this.synchroniztionFlag = synchronizationFlag;
            this.propertyTagForConfigure = propertyTags[0];

            // Construct RopSynchronizationConfigure request.
            synchronizationConfigureRequest.RopId = (byte)RopId.RopSynchronizationConfigure;
            synchronizationConfigureRequest.LogonId = 0x00;
            synchronizationConfigureRequest.InputHandleIndex = 0x00;
            synchronizationConfigureRequest.OutputHandleIndex = 0x01;

            // 0x01,Indicates a contents synchronization.0x02,Indicates a hierarchy synchronization.
            synchronizationConfigureRequest.SynchronizationType = (byte)synchronizationType;
            synchronizationConfigureRequest.SendOptions = (byte)option;

            // Unicode 
            synchronizationConfigureRequest.SynchronizationFlags = (ushort)synchronizationFlag;
            if (synchronizationType == SynchronizationTypes.Contents)
            {
                // Set RestrictionDataSize to 0x0000 to avoid the complex RestrictionData.
                synchronizationConfigureRequest.RestrictionDataSize = 0x0005;

                // If PidTagMessageClass exists 
                synchronizationConfigureRequest.RestrictionData = new byte[] { 0x08, 0x1f, 0x00, 0x1a, 0x00 };
            }
            else
            {
                // Set RestrictionDataSize to 0x0000 to avoid the complex RestrictionData.
                synchronizationConfigureRequest.RestrictionDataSize = 0x0000;
                synchronizationConfigureRequest.RestrictionData = new byte[0];
            }

            synchronizationConfigureRequest.SynchronizationExtraFlags = (byte)synchronizationExtraFlag;
            synchronizationConfigureRequest.PropertyTagCount = (ushort)propertyTags.Length;
            synchronizationConfigureRequest.PropertyTags = propertyTags;

            if (this.Process(serverId, synchronizationConfigureRequest, objHandle) is RopSynchronizationConfigureResponse)
            {
                // Send request and get response.
                RopSynchronizationConfigureResponse synchronizationConfigureResponse = (RopSynchronizationConfigureResponse)this.Process(serverId, synchronizationConfigureRequest, objHandle);
                result = (RopResult)synchronizationConfigureResponse.ReturnValue;

                if (result == RopResult.Success)
                {
                    downloadcontextHandleIndex = AdapterHelper.GetHandleIndex();
                    this.handleContainer.Add(downloadcontextHandleIndex, this.responseSOHs[synchronizationConfigureResponse.OutputHandleIndex]);

                    if ((synchronizationExtraFlag & SynchronizationExtraFlag.OrderByDeliveryTime) != SynchronizationExtraFlag.OrderByDeliveryTime)
                    {
                        this.isOrderByDeliveryTimeExtraFlagNotSet = true;
                    }

                    if (this.lastChangeMadeByServer && (synchronizationExtraFlag & SynchronizationExtraFlag.CN) == SynchronizationExtraFlag.CN)
                    {
                        this.lastChangeMadeByClient = true;
                    }
                }

                // Verify ROP SynchronizationConfigure
                this.VerifyRopSynchronizationConfigure(synchronizationConfigureRequest, synchronizationConfigureResponse);
            }
            else
            {
                // If the response type is not RopSynchronizationConfigureResponse it must be that the process method throughout a FormatException when sending RPC request buffer.
                result = RopResult.RpcFormat;
            }

            return result;
        }
        /// <summary>
        /// Creates a FastTransfer download context for a snapshot of the checkpoint ICS state of the operation identified by the given synchronization download context, or synchronization upload context.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="objHandleIndex">Synchronization context index.</param>
        /// <param name="stateHandleIndex">The index of FastTransfer download context for the ICS state.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult SynchronizationGetTransferState(int serverId, int objHandleIndex, out int stateHandleIndex)
        {
            // Initialize ROP data.
            stateHandleIndex = -1;
            uint synchronizationGetTransferStateHandle = this.handleContainer[objHandleIndex];
            RopResult result = RopResult.InvalidParameter;
            this.streamType = FastTransferStreamType.state;

            // Construct ROP request.
            RopSynchronizationGetTransferStateRequest synchronizationGetTransferStateRequest;
            synchronizationGetTransferStateRequest.RopId = 0x82;
            synchronizationGetTransferStateRequest.LogonId = 0x00;
            synchronizationGetTransferStateRequest.InputHandleIndex = 0x00;
            synchronizationGetTransferStateRequest.OutputHandleIndex = 0x01;

            // Send the CreateSyncUploadContext request and verify the success response.
            RopSynchronizationGetTransferStateResponse synchronizationGetTransferStateResponse = (RopSynchronizationGetTransferStateResponse)this.Process(serverId, synchronizationGetTransferStateRequest, synchronizationGetTransferStateHandle);
            result = (RopResult)synchronizationGetTransferStateResponse.ReturnValue;

            if (result == RopResult.Success)
            {
                stateHandleIndex = AdapterHelper.GetHandleIndex();
                this.handleContainer.Add(stateHandleIndex, this.responseSOHs[synchronizationGetTransferStateResponse.OutputHandleIndex]);

                // Verify ROP SynchronizationGetTransferState
                this.VerifyRopSynchronizationGetTransferState(synchronizationGetTransferStateResponse);
            }

            return result;
        }
        /// <summary>
        /// Initializes a FastTransfer operation to download properties and descendant subobjects for a specified folder.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="sourceHandleIndex">Folder object handle index. </param>
        /// <param name="copyFlag">Defines parameters of the FastTransfer download operation.</param>
        /// <param name="option">Defines the parameters of a download operation.</param>
        /// <param name="copyFolderHandleIndex">The folder handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult FastTransferSourceCopyFolder(int serverId, int sourceHandleIndex, CopyFolderCopyFlags copyFlag, SendOptionAlls option, out int copyFolderHandleIndex)
        {
            // Initialize return value.
            copyFolderHandleIndex = -1;
            RopResult result = RopResult.InvalidParameter;
            uint targetFolderHandle = this.handleContainer[sourceHandleIndex];

            // Move flag only used in exchangeServer2007
            if (!Common.IsRequirementEnabled(526001, this.Site) && copyFlag == CopyFolderCopyFlags.Move)
            {
                return result;
            }

            this.streamType = FastTransferStreamType.TopFolder;

            // Construct ROP request.
            RopFastTransferSourceCopyFolderRequest fastTransferSourceCopyFolderRequest;
            fastTransferSourceCopyFolderRequest.RopId = 0x4C;
            fastTransferSourceCopyFolderRequest.LogonId = 0x00;
            fastTransferSourceCopyFolderRequest.InputHandleIndex = 0x00;
            fastTransferSourceCopyFolderRequest.OutputHandleIndex = 0x01;
            fastTransferSourceCopyFolderRequest.CopyFlags = (byte)copyFlag;
            fastTransferSourceCopyFolderRequest.SendOptions = (byte)option;

            this.folderCopyFlag = copyFlag;

            // Send request and get response.
            RopFastTransferSourceCopyFolderResponse response = (RopFastTransferSourceCopyFolderResponse)this.Process(serverId, fastTransferSourceCopyFolderRequest, targetFolderHandle);
            result = (RopResult)response.ReturnValue;

            if (result == RopResult.Success)
            {
                copyFolderHandleIndex = AdapterHelper.GetHandleIndex();
                this.handleContainer.Add(copyFolderHandleIndex, this.responseSOHs[response.OutputHandleIndex]);
            }

            // Verify ROP FastTransferSourceCopyFolder
            this.VerifyRopFastTransferSourceCopyFolder(fastTransferSourceCopyFolderRequest, response);

            return result;
        }
        /// <summary>
        /// Initializes a FastTransfer operation on a folder for downloading content and descendant subobjects for messages identified by a given set of IDs.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="sourceHandleIndex">Folder object handle index. </param>
        /// <param name="copyFlag">Defines parameters of the FastTransfer download operation.</param>
        /// <param name="option">Defines the parameters of a download operation.</param>
        /// <param name="messageIds">The list of MIDs the messages should copy.</param>
        /// <param name="copyMessageHandleIndex">The message handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult FastTransferSourceCopyMessages(int serverId, int sourceHandleIndex, RopFastTransferSourceCopyMessagesCopyFlags copyFlag, SendOptionAlls option, Sequence<int> messageIds, out int copyMessageHandleIndex)
        {
            // Initialize ROP data
            RopResult result = RopResult.InvalidParameter;
            copyMessageHandleIndex = -1;
            this.streamType = FastTransferStreamType.MessageList;
            RopFastTransferSourceCopyMessagesRequest req;
            uint sourceHandle = this.handleContainer[sourceHandleIndex];
            ushort idcount = (ushort)messageIds.Count;
            ulong[] messageId = new ulong[idcount];
            int index = 0;
            foreach (int mID in messageIds)
            {
                messageId[index++] = this.objectIdContainer[mID];
            }

            // Construct ROP request.
            req.RopId = 0x4B;
            req.LogonId = 0x00;
            req.InputHandleIndex = 0x00;
            req.OutputHandleIndex = 0x01;
            req.MessageIdCount = idcount;
            req.MessageIds = messageId;
            req.CopyFlags = (byte)copyFlag;
            req.SendOptions = (byte)option;

            // Stores message id and copy flag
            this.previousOperation = EnumFastTransferOperation.FastTransferSourceCopyMessage;
            this.messageIdForFastTransferSourceCopyMessages = (long)messageId[0];
            this.copyFlagForFastTransferSourceCopyMessages = copyFlag;

            // Send request and get response.
            RopFastTransferSourceCopyMessagesResponse response = (RopFastTransferSourceCopyMessagesResponse)this.Process(serverId, req, sourceHandle);
            result = (RopResult)response.ReturnValue;

            if (result == RopResult.Success)
            {
                copyMessageHandleIndex = AdapterHelper.GetHandleIndex();
                this.handleContainer.Add(copyMessageHandleIndex, this.responseSOHs[response.OutputHandleIndex]);
            }

            // Verify ROP FastTransferSourceCopyMessages
            this.VerifyRopFastTransferSourceCopyMessages(req, response);

            return result;
        }
        /// <summary>
        /// Initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="sourceHandleIndex">Folder or message object handle index. </param>
        /// <param name="handleType">Type of object handle. </param>
        /// <param name="level">Variable indicate whether copy the descendant subobjects.</param>
        /// <param name="copyFlag">Defines parameters of the FastTransfer download operation.</param>
        /// <param name="option">Defines the parameters of a download operation.</param>
        /// <param name="propertyTags">The list of properties and subobjects to exclude.</param>
        /// <param name="copyPropertiesHandleIndex">The properties handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult FastTransferSourceCopyProperties(int serverId, int sourceHandleIndex, InputHandleType handleType, bool level, CopyPropertiesCopyFlags copyFlag, SendOptionAlls option, Sequence<string> propertyTags, out int copyPropertiesHandleIndex)
        {
            // Initialize ROP data.
            RopResult result = RopResult.InvalidParameter;
            RopFastTransferSourceCopyPropertiesRequest req;
            copyPropertiesHandleIndex = -1;
            uint sourceHandle = this.handleContainer[sourceHandleIndex];

            // Get stream type.
            switch (handleType)
            {
                case InputHandleType.FolderHandle:
                    this.streamType = FastTransferStreamType.folderContent;
                    break;
                case InputHandleType.MessageHandle:
                    this.streamType = FastTransferStreamType.MessageContent;
                    break;
                case InputHandleType.AttachmentHandle:
                    this.streamType = FastTransferStreamType.attachmentContent;
                    break;
                default:
                    break;
            }

            // Initialize input propertyTags.
            ushort propertyCount = (ushort)propertyTags.Count;
            PropertyTag[] messageSamplePropertyTags = new PropertyTag[propertyCount];
            for (int i = 0; i < propertyCount; i++)
            {
                messageSamplePropertyTags[i] = this.propertyTagsDictionary[propertyTags[i]];
            }

            this.previousOperation = EnumFastTransferOperation.FastTransferSourceCopyProperties;
            this.propertyTags = messageSamplePropertyTags;
            this.copySubObjects = !level;

            // Construct ROP request.
            req.RopId = 0x69;
            req.LogonId = 0x00;
            req.InputHandleIndex = 0x00;
            req.OutputHandleIndex = 0x01;

            // This value specifies the level at which the copy is occurring, which is specified in [MS-OXCROPS].
            req.Level = (byte)(level ? 1 : 0);

            req.CopyFlags = (byte)copyFlag;
            req.SendOptions = (byte)option;
            req.PropertyTagCount = propertyCount;
            req.PropertyTags = messageSamplePropertyTags;

            // Send request and get response.
            RopFastTransferSourceCopyPropertiesResponse response = (RopFastTransferSourceCopyPropertiesResponse)this.Process(serverId, req, sourceHandle);
            result = (RopResult)response.ReturnValue;

            if (result == RopResult.Success)
            {
                copyPropertiesHandleIndex = AdapterHelper.GetHandleIndex();
                this.handleContainer.Add(copyPropertiesHandleIndex, this.responseSOHs[response.OutputHandleIndex]);
            }

            // Verify ROP FastTransferSourceCopyProperties
            this.VerifyRopFastTransferSourceCopyProperties(req, response);

            return result;
        }
        /// <summary>
        /// Initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="sourceHandleIndex">Folder or message object handle index. </param>
        /// <param name="handleType">Type of object handle </param>
        /// <param name="level">Variable indicate whether copy the descendant subobjects.</param>
        /// <param name="copyFlag">Defines parameters of the FastTransfer download operation.</param>
        /// <param name="option">Defines the parameters of a download operation.</param>
        /// <param name="propertyTags">Array of properties and subobjects to exclude.</param>
        /// <param name="copyToHandleIndex">The properties handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult FastTransferSourceCopyTo(int serverId, int sourceHandleIndex, InputHandleType handleType, bool level, CopyToCopyFlags copyFlag, SendOptionAlls option, Sequence<string> propertyTags, out int copyToHandleIndex)
        {
            // Initialize ROP returned value.
            RopResult result = RopResult.InvalidParameter;
            copyToHandleIndex = -1;
            ushort propertyCount = (ushort)propertyTags.Count;
            this.currentCopyFlag = copyFlag;

            // Get stream type.
            switch (handleType)
            {
                case InputHandleType.FolderHandle:
                    this.streamType = FastTransferStreamType.folderContent;
                    break;
                case InputHandleType.MessageHandle:
                    this.streamType = FastTransferStreamType.MessageContent;
                    break;
                case InputHandleType.AttachmentHandle:
                    this.streamType = FastTransferStreamType.attachmentContent;
                    break;
                default:
                    break;
            }

            // Initialize input propertyTags
            PropertyTag[] messagePropertyTags = new PropertyTag[propertyCount];
            for (int i = 0; i < propertyCount; i++)
            {
                messagePropertyTags[i] = this.propertyTagsDictionary[propertyTags[i]];
            }

            // Stores the values for further verification
            this.previousOperation = EnumFastTransferOperation.FastTransferSourceCopyTo;
            this.propertyTags = messagePropertyTags;

            // Construct ROP request.
            uint sourceHandle = this.handleContainer[sourceHandleIndex];
            RopFastTransferSourceCopyToRequest request;
            request.RopId = 0x4D;
            request.LogonId = 0X00;
            request.InputHandleIndex = 0x00;
            request.OutputHandleIndex = 0x01;

            // This value specifies the level at which the copy is occurring,Non-Zero: exclude all descendant subobjects from being copied
            request.Level = level ? (byte)1 : (byte)0;
            request.CopyFlags = (uint)copyFlag;
            request.SendOptions = (byte)option;
            request.PropertyTagCount = propertyCount;
            request.PropertyTags = messagePropertyTags;

            // Send request and get response.
            RopFastTransferSourceCopyToResponse response = (RopFastTransferSourceCopyToResponse)this.Process(serverId, request, sourceHandle);
            result = (RopResult)response.ReturnValue;

            if (result == RopResult.Success)
            {
                copyToHandleIndex = AdapterHelper.GetHandleIndex();
                this.handleContainer.Add(copyToHandleIndex, this.responseSOHs[response.OutputHandleIndex]);
            }

            // Verify ROP FastTransferSourceCopyTo
            this.VerifyRopFastTransferSourceCopyTo(request, response);

            return result;
        }
 public DecodingContext()
 {
     objectHandles = new Dictionary<uint, ObjectHandlesType>();
     sessionFastTransferStreamType = new Dictionary<int, FastTransferStreamType>();
     streamType_Getbuffer = new FastTransferStreamType();
     copyTo_InputHandles = new List<uint>();
     copyProperties_InputHandles = new List<uint>();
     copyTo_OutputHandles = new List<uint>();
     copyProperties_OutputHandles = new List<uint>();
     copyMessage_OutputHandles = new List<uint>();
     copyFolder_OutputHandles = new List<uint>();
     syncGetTransferState_OutputHandles = new List<uint>();
     syncConfigure_OutputHandles = new List<uint>();
     destinationConfigure_OutputHandles = new List<uint>();
     destinationConfigure_InputHandles = new List<uint>();
     getPropertiesSpec_propertyTags = new Dictionary<int, Dictionary<uint, PropertyTag[]>>();
     sessionRequestRemainSize = new Dictionary<int, List<uint>>();
     setColumnProTagMap_Handle = new Dictionary<uint, PropertyTag[]>();
     setColumnProTagMap_Index = new Dictionary<uint, PropertyTag[]>();
     propertyTagsForRowRop = new Dictionary<int, PropertyTag[]>();
     putBuffer_sourceOperation = new Dictionary<uint, SourceOperation>();
     setColumn_InputHandles_InResponse = new List<uint>();
     sessionLogonFlagsInLogonRop = new Dictionary<int, Dictionary<uint, LogonFlags>>();
     logonFlagMapLogId = new Dictionary<byte, LogonFlags>();
     sessionLogonFlagMapLogId = new Dictionary<int, Dictionary<byte, LogonFlags>>();
 }