/// <summary>
        /// Get the corresponding AbstractFastTransferStream.
        /// </summary>
        /// <returns>The corresponding AbstractFastTransferStream.</returns>
        public AbstractFastTransferStream GetAbstractFastTransferStream()
        {
            AbstractFastTransferStream abstractFastTransferStream = new AbstractFastTransferStream
            {
                StreamType = FastTransferStreamType.MessageList
            };
            AbstractMessageList abstractMessageList = new AbstractMessageList
            {
                IsPidTagEcWarningOut = this.ErrorCodeList.Count != 0
            };

            // If ErrorCodeList contains values, it means PidTagEcWaring is out in model level.
            // Since ErrorCodeList contains PidTagEcWaring values, each value is after a PidTagEcWaring.

            // Beside checking permission, each MessageList contains at least 1 message.
            abstractMessageList.AbsMessage.AbsMessageContent.IsNoPermissionMessageNotOut = !(this.Messages != null && this.Messages.Count > 0);
            abstractFastTransferStream.AbstractMessageList = abstractMessageList;
            return abstractFastTransferStream;
        }
Esempio n. 2
0
        /// <summary>
        /// Get the corresponding AbstractFastTransferStream.
        /// </summary>
        /// <returns>The corresponding AbstractFastTransferStream.</returns>
        public AbstractFastTransferStream GetAbstractFastTransferStream()
        {
            AbstractFastTransferStream abstractFastTransferStream = new AbstractFastTransferStream
            {
                StreamType = FastTransferStreamType.MessageList
            };
            AbstractMessageList abstractMessageList = new AbstractMessageList
            {
                IsPidTagEcWarningOut = this.ErrorCodeList.Count != 0
            };

            // If ErrorCodeList contains values, it means PidTagEcWaring is out in model level.
            // Since ErrorCodeList contains PidTagEcWaring values, each value is after a PidTagEcWaring.

            // Beside checking permission, each MessageList contains at least 1 message.
            abstractMessageList.AbsMessage.AbsMessageContent.IsNoPermissionMessageNotOut = !(this.Messages != null && this.Messages.Count > 0);
            abstractFastTransferStream.AbstractMessageList = abstractMessageList;
            return(abstractFastTransferStream);
        }
        /// <summary>
        /// Get the corresponding AbstractFastTransferStream.
        /// </summary>
        /// <returns>The corresponding AbstractFastTransferStream.</returns>
        public AbstractFastTransferStream GetAbstractFastTransferStream()
        {
            AbstractFastTransferStream afts = default(AbstractFastTransferStream);

            afts.StreamType = FastTransferStreamType.folderContent;

            afts.AbstractFolderContent.IsNoPermissionObjNotOut = !(this.SubFolders != null && this.SubFolders.Count > 0);
            afts.AbstractFolderContent.IsPidTagEcWarningOut    = this.WarningCode != null;

            // The stack uses the structure defined in Open Specification 2.2.4.2 and the order to deserialize the payload. If the deserialization succeeds, the condition that IsFolderMessagesPrecededByPidTagFXDelProp is met.
            if (this.FolderMessages != null && this.folderMessages.FXDelPropList != null)
            {
                for (int i = 0; i < this.folderMessages.FXDelPropList.Count; i++)
                {
                    if ((this.folderMessages.FXDelPropList[i] == 0x3610000d) || (this.folderMessages.FXDelPropList[i] == 0x360F000d))
                    {
                        afts.AbstractFolderContent.AbsFolderMessage.IsFolderMessagesPrecededByPidTagFXDelProp = true;
                        break;
                    }
                }
            }

            if (this.SubFolders != null && this.SubFolders.Count > 0)
            {
                // afts.AbstractTopFolder.subFolderInScope = true;
                // The stack uses the structure defined in Open Specification 2.2.4.2 and the order to deserialize the payload. If the deserialization succeeds, the condition that IsFolderMessagesPrecededByPidTagFXDelProp is met.
                for (int i = 0; i < this.FXDelPropList.Count; i++)
                {
                    if (this.FXDelPropList[i] == 0x360E000d)
                    {
                        afts.AbstractFolderContent.IsSubFolderPrecededByPidTagFXDelProp = true;
                        break;
                    }
                }
            }

            // afts.AbstractFolderContent.AbsFolderMessage.MessageList.AbsMessage.AbsMessageContent.IsNoPermissionMessageNotOut = ((this.SubFolders == null) || (this.SubFolders != null && this.SubFolders.Count == 0));
            return(afts);
        }
        /// <summary>
        /// Generate fast transfer stream data.
        /// </summary>
        /// <param name="serverId">server id.</param>
        /// <param name="buffer">Input buffer data.</param>
        /// <returns>AbstractFastTransferStream object.</returns>
        private AbstractFastTransferStream GenerateAbstractFastTransferStream(
            int serverId,
            byte[] buffer)
        {
            using (FastTransferStream fs = new FastTransferStream(buffer, false))
            {
                AbstractFastTransferStream afts;

                // Record all property list generated while deserializing.
                SyntacticalBase.AllPropList = new List<PropList>();
                int icsStateIndex = -1;
                switch (this.streamType)
                {
                    case FastTransferStreamType.state:
                        State s = new State(fs);
                        this.VerifyMarkers(s);

                        // Insert state to the ICSStateContainer
                        icsStateIndex = this.InsertStateDict(s);
                        afts = new AbstractFastTransferStream();

                        // Get the AbstractState corresponding to the state from the fast transfer stream.
                        AbstractState astate = this.GetAbstractState(serverId, icsStateIndex, s);

                        // Set the AbstractState of the AbstractFastTransferStream.
                        afts.AbstractState = new AbstractState
                        {
                            AbstractICSStateIndex = icsStateIndex,
                            IdSetGiven = astate.IdSetGiven
                        };

                        //// Other fields of the AbstractState of the AbstractFastTransferStream do not need.

                        afts.StreamType = FastTransferStreamType.state;
                        return afts;
                    case FastTransferStreamType.attachmentContent:
                        AttachmentContent att = new AttachmentContent(fs);
                        this.VerifyMarkers(att);
                        return att.GetAbstractFastTransferStream();
                    case FastTransferStreamType.contentsSync:
                        ContentsSync cs = new ContentsSync(fs);
                        this.VerifyMarkers(cs);

                        // Insert the state of the contentsSync to the ICSStateContainer
                        icsStateIndex = this.InsertStateDict(cs.State);
                        afts = this.GetAbstractContentSync(
                            serverId, icsStateIndex, cs);
                        return afts;
                    case FastTransferStreamType.folderContent:
                        FolderContent fc = new FolderContent(fs);
                        this.VerifyMarkers(fc);
                        this.VerifyFolderReplicaInfoStructure(fc);

                        afts = fc.GetAbstractFastTransferStream();

                        if (!this.existNoPermissionFolder)
                        {
                            afts.AbstractFolderContent.IsNoPermissionObjNotOut = false;
                        }

                        this.VerifyMetaProperty(afts);
                        return afts;
                    case FastTransferStreamType.hierarchySync:
                        HierarchySync hs = new HierarchySync(fs);
                        this.VerifyMarkers(hs);
                        if (hs.FolderChangeList.Count > 0)
                        {
                            PropValue property = hs.FolderChangeList[hs.FolderChangeList.Count - 1].PropList.PropValues.Find(p => p.PropInfo.PropID == 0x65e3);
                            if (property != null)
                            {
                                this.lastConflictInfo.PCLXFromServer = ((VarPropTypePropValue)property).ValueArray;
                                this.VerifyPidTagPredecessorChangeList();
                            }
                        }

                        // Insert state to the ICSStateContainer
                        icsStateIndex = this.InsertStateDict(hs.State);
                        afts = this.GetAbstractHierachySync(serverId, hs, icsStateIndex);
                        return afts;
                    case FastTransferStreamType.MessageContent:
                        MessageContent mc = new MessageContent(fs);
                        for (int i = 0; i < mc.PropList.PropValues.Count; i++)
                        {
                            PropValue propValue = mc.PropList.PropValues[i];

                            if (propValue.PropType == 0x84b0)
                            {
                                CodePage codePage = new CodePage();
                                codePage.Deserialize(propValue.PropType);

                                this.VerifyCodePageProperty(codePage);
                            }
                        }

                        this.VerifyMarkers(mc);
                        afts = mc.GetAbstractFastTransferStream();
                        this.VerifyMetaProperty(afts);
                        return afts;
                    case FastTransferStreamType.MessageList:
                        MessageList ml = new MessageList(fs);
                        afts = ml.GetAbstractFastTransferStream();
                        this.VerifyMetaProperty(afts);
                        this.VerifyMarkers(ml);
                        return afts;
                    case FastTransferStreamType.TopFolder:
                        TopFolder tf = new TopFolder(fs);
                        this.VerifyMarkers(tf);
                        afts = tf.GetAbstractFastTransferStream();
                        this.VerifyMetaProperty(afts);
                        return afts;
                    default:
                        AdapterHelper.Site.Assert.Fail("The stream type is invalid, its value is:{0}.", this.streamType);
                        return new AbstractFastTransferStream();
                }
            }
        }
        /// <summary>
        /// Get HierachySync data.
        /// </summary>
        /// <param name="serverId">server id.</param>
        /// <param name="hsync">Content sync object</param>
        /// <param name="stateIndex">Start index.</param>
        /// <returns>The AbstractFastTransferStream</returns>
        private AbstractFastTransferStream GetAbstractHierachySync(
            int serverId,
            HierarchySync hsync,
            int stateIndex)
        {
            AbstractFastTransferStream afts = new AbstractFastTransferStream();
            AbstractHierarchySync ahsync = new AbstractHierarchySync();
            afts.StreamType = FastTransferStreamType.hierarchySync;

            ahsync.FinalICSState = this.GetAbstractState(serverId, stateIndex, hsync.State);
            ahsync.AbstractDeletion = this.GetAbstractDeletion(hsync.Deletions);
            AbstractFolderChange fc = new AbstractFolderChange();

            // Get the FolderchangeInfo, FolderCount and IsParentFolderBeforeChild
            // of the AbstractHierarchySync.
            if (hsync.FolderChangeList != null && hsync.FolderChangeList.Count > 0)
            {
                AbstractFolderChange tmp = new AbstractFolderChange();

                // fields:IsPidTagFolderIdExist,IsPidTagParentFolderIdExist
                // IsPidTagParentSourceKeyValueZero,IsPidTagSourceKeyValueZero
                // need all folderChange's corresponding flag is true.
                fc = hsync.FolderChangeList[0].GetAbstractFolderChange();
                for (int i = 1; i < hsync.FolderChangeList.Count; i++)
                {
                    tmp = hsync.FolderChangeList[i].GetAbstractFolderChange();
                    fc.IsPidTagFolderIdExist =
                        fc.IsPidTagFolderIdExist && tmp.IsPidTagFolderIdExist;
                    fc.IsPidTagParentFolderIdExist =
                        fc.IsPidTagParentFolderIdExist && tmp.IsPidTagParentFolderIdExist;
                    fc.IsPidTagParentSourceKeyValueZero =
                        fc.IsPidTagParentSourceKeyValueZero && tmp.IsPidTagParentSourceKeyValueZero;
                    fc.IsPidTagSourceKeyValueZero =
                        fc.IsPidTagSourceKeyValueZero && tmp.IsPidTagSourceKeyValueZero;
                }

                ahsync.FolderchangeInfo = fc;

                // The count of folderChange.
                ahsync.FolderCount = hsync.FolderChangeList.Count;

                // If parents are before their children,
                // for a specific folder change, its ParentSourceKey
                // must be zero if its parent is the sync folder
                // or can be found before the position of the folder change.
                ahsync.IsParentFolderBeforeChild = hsync.IsParentBeforeChildren;
            }

            afts.AbstractHierarchySync = ahsync;
            return afts;
        }
        /// <summary>
        /// Get content sync data.
        /// </summary>
        /// <param name="serverID">server id.</param>
        /// <param name="stateIndex">Start index.</param>
        /// <param name="cs">Content sync object</param>
        /// <returns>The AbstractFastTransferStream</returns>
        public AbstractFastTransferStream GetAbstractContentSync(
            int serverID,
            int stateIndex,
            ContentsSync cs)
        {
            AbstractFastTransferStream afts = new AbstractFastTransferStream();
            AbstractContentsSync acs = new AbstractContentsSync
            {
                AbstractDeletion = new AbstractDeletion
                {
                    IdSetDeleted = new Modeling.Set<int>()
                }
            };

            // If the deletion is not null change the AbstractDeletion's field,
            // else do not change the Deletions field of the AbstractContentsSync
            if (cs.Deletions != null)
            {
                // If the deletion is not null the deletion is present.
                acs.AbstractDeletion = new AbstractDeletion
                {
                    IsDeletionPresent = true,
                    IsPidTagIdsetExpiredExist = cs.Deletions.PropList.HasPidTagIdsetExpired,

                    // Check pidtags in the deletions property list.
                    IsPidTagIdsetNoLongerInScopeExist = cs.Deletions.PropList.HasPidTagIdsetNoLongerInScope,
                    IdSetDeleted = new Modeling.Set<int>()
                };

                // Check Idset in the deletion.
                // If the Idset that can be got from PidTagIdsetDeleted value 
                // in the PropList of the deletions is contained in the objectIdContainer
                // add it to the IdsetDeleted field in the AbstractDeletion
                List<ulong> ids = cs.Deletions.IdsetDeleted;
                foreach (int key in this.objectIdContainer.Keys)
                {
                    if (ids.Contains(this.objectIdContainer[key]))
                    {
                        acs.AbstractDeletion.IdSetDeleted =
                             acs.AbstractDeletion.IdSetDeleted.Add(key);
                    }
                }

                this.VerifyMetaTagIdsetDeletedProperty(this.hasExecuteSynchronizationImportDeletes, this.importDelFlag, ids, this.delObjId);
                this.hasExecuteSynchronizationImportDeletes = false;
            }

            // Whether ProgressTotal is present.
            acs.IsprogessTotalPresent = cs.ProgressTotal != null;

            // Whether ReadStateChanges is present.
            acs.IsReadStateChangesExist = cs.ReadStateChanges != null;

            acs.MessageInfo = new Modeling.Set<AbstractMessageChangeInfo>();
            if (cs.MessageChangeTuples != null)
            {
                for (int i = 0; i < cs.MessageChangeTuples.Count; i++)
                {
                    AbstractMessageChangeInfo info = new AbstractMessageChangeInfo();
                    Tuple<ProgressPerMessage, MessageChange> msg = cs.MessageChangeTuples[i];
                    info.IsMessageChangeFull = msg.Item2 is MessageChangeFull;

                    // Whether ProgressPerMessagePresent is present.
                    info.IsProgressPerMessagePresent = msg.Item1 != null;
                    if (msg.Item1 != null)
                    {
                        // If ProgressPerMessagePresent is present,
                        // whether the message followed is a FAI message.
                        info.FollowedFAIMessage = msg.Item1.IsFollowedFAIMessage;
                    }

                    info.IsPidTagChangeNumberExist = msg.Item2.HasPidTagChangeNumber;
                    info.IsPidTagMessageSizeExist = msg.Item2.HasPidTagMessageSize;
                    info.IsPidTagMidExist = msg.Item2.HasPidTagMid;

                    // convert the SourceKey in the messageChangeHeader of the messageChange
                    // to a GID  structure, then use this GID to build a LongTermId,
                    // get the id corresponding to the LongTermId,if the id is maintained in the 
                    // objectIdContainer,find its index, else set the messageIdIndex of the 
                    // AbstractMessageChangeInfo to -1.
                    byte[] buffer = msg.Item2.SourceKey;
                    GID gid = StructureSerializer.Deserialize<GID>(buffer);
                    LongTermId lid = new LongTermId
                    {
                        DatabaseGuid = gid.DatabaseGuid.ToByteArray(),
                        GlobalCounter = gid.GlobalCounter
                    };
                    ulong id = this.GetIdFromLongTerm(serverID, lid);
                    info.MessageIdIndex = -1;
                    foreach (int k in this.objectIdContainer.Keys)
                    {
                        if (this.objectIdContainer[k] == id)
                        {
                            info.MessageIdIndex = k;
                            break;
                        }
                    }

                    // If messageChangeFull, whether its PropList contains PidTagRtfCompressed. 
                    if (msg.Item2 is MessageChangeFull)
                    {
                        info.IsRTFformat = (msg.Item2 as MessageChangeFull).IsRTFFormat;
                    }

                    // Add the AbstractMessageChangeInfo to the MessageInfo of the AbstractContentsSync
                    acs.MessageInfo = acs.MessageInfo.Add(info);
                }

                // if there is  more than 1 messageChange presents.
                // whether their order is in descending order.
                if (cs.MessageChangeTuples.Count > 1)
                {
                    acs.IsSortByLastModificationTime = true;
                    acs.IsSortByMessageDeliveryTime = true;
                    DateTime prev = cs.MessageChangeTuples[0].Item2.LastModificationTime;
                    for (int i = 1; i < cs.MessageChangeTuples.Count; i++)
                    {
                        DateTime curr = cs.MessageChangeTuples[i].Item2.LastModificationTime;

                        // If one is not in descending order.
                        // set flags to false.
                        if (prev < curr)
                        {
                            acs.IsSortByLastModificationTime = false;
                            acs.IsSortByMessageDeliveryTime = false;
                            break;
                        }
                    }

                    // If the OrderByDeliveryTime flag of the SynchronizationExtraFlag field is not set, there is no requirement on the server to return items in a specific order.
                    if (this.isOrderByDeliveryTimeExtraFlagNotSet)
                    {
                        acs.IsSortByLastModificationTime = false;
                        acs.IsSortByMessageDeliveryTime = false;
                    }
                }
            }

            // Get FinalICSState.
            acs.FinalICSState = this.GetAbstractState(serverID, stateIndex, cs.State);
            afts.AbstractContentsSync = acs;
            afts.StreamType = FastTransferStreamType.contentsSync;
            afts.AbstractState = new AbstractState();
            return afts;
        }
        /// <summary>
        /// Downloads the next portion of a FastTransfer stream.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="downloadHandleIndex">A fast transfer stream object handle index. </param>
        /// <param name="bufferSize">Specifies the maximum amount of data to be output in the TransferBuffer.</param>
        /// <param name="transferBufferIndex">The index of data get from the fast transfer stream.</param>
        /// <param name="abstractFastTransferStream">Fast transfer stream.</param>
        /// <param name="transferDataSmallOrEqualToBufferSize">Variable to not if the transferData is small or equal to bufferSize</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult FastTransferSourceGetBuffer(int serverId, int downloadHandleIndex, BufferSize bufferSize, out int transferBufferIndex, out AbstractFastTransferStream abstractFastTransferStream, out bool transferDataSmallOrEqualToBufferSize)
        {
            // Initialize ROP data.
            SyntacticalBase.AllPropList = null;
            RopResult returnValue = RopResult.InvalidParameter;
            this.totalTransferBufferList.Clear();
            transferBufferIndex = -1;
            abstractFastTransferStream = new AbstractFastTransferStream();
            transferDataSmallOrEqualToBufferSize = false;
            if (downloadHandleIndex < 0)
            {
                return returnValue;
            }

            if (bufferSize == BufferSize.Greater && !Common.IsRequirementEnabled(2625, this.Site))
            {
                returnValue = RopResult.BufferTooSmall;
                return returnValue;
            }

            RopFastTransferSourceGetBufferResponse response = new RopFastTransferSourceGetBufferResponse();
            uint sourceHandle = this.handleContainer[downloadHandleIndex];
            uint downloadContextHandle = sourceHandle;

            // Construct ROP request.
            RopFastTransferSourceGetBufferRequest fastTransferSourceGetBufferRequest;
            fastTransferSourceGetBufferRequest.RopId = 0x4e;
            fastTransferSourceGetBufferRequest.LogonId = 0x00;
            fastTransferSourceGetBufferRequest.InputHandleIndex = 0x00;
            fastTransferSourceGetBufferRequest.BufferSize = (ushort)bufferSize;
            if (bufferSize != BufferSize.Normal)
            {
                fastTransferSourceGetBufferRequest.MaximumBufferSize = null;
            }
            else
            {
                fastTransferSourceGetBufferRequest.MaximumBufferSize = (ushort)bufferSize;
            }

            bool isRunIntoPartial = false;
            bool isRunIntoNoRoom = false;
            do
            {
                IDeserializable tempRopResponse = null;
                if ((tempRopResponse = this.Process(serverId, fastTransferSourceGetBufferRequest, downloadContextHandle)) != null)
                {    // Send request and get response.
                    response = (RopFastTransferSourceGetBufferResponse)tempRopResponse;

                    byte[] transferBuffer = new byte[(int)response.TransferBufferSize];
                    if (response.ReturnValue == 0)
                    {
                        if (bufferSize != BufferSize.Normal)
                        {
                            transferDataSmallOrEqualToBufferSize = transferBuffer.Length <= (int)bufferSize;
                        }

                        for (int i = 0; i < (int)response.TransferBufferSize; i++)
                        {
                            transferBuffer[i] = response.TransferBuffer[i];
                        }

                        this.totalTransferBufferList.Add(transferBuffer);

                        if (response.TransferStatus == (ushort)TransferStatus.Partial)
                        {
                            isRunIntoPartial = true;
                        }

                        if (response.TransferStatus == (ushort)TransferStatus.NoRoom)
                        {
                            isRunIntoNoRoom = true;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            while (response.TransferStatus != (ushort)TransferStatus.Done && (RopResult)response.ReturnValue == RopResult.Success);

            if (response.TransferBuffer == null)
            {
                returnValue = (RopResult)this.ropResult;
            }
            else
            {
                returnValue = (RopResult)response.ReturnValue;
            }

            bool isReachedBufferTooSmall = (bufferSize == BufferSize.Greater) && (returnValue == RopResult.BufferTooSmall);

            this.VerifyTransferStatus(isRunIntoPartial, isRunIntoNoRoom, isReachedBufferTooSmall);

            if (isReachedBufferTooSmall)
            {
                this.previousGetBufferResult = RopResult.BufferTooSmall;
            }

            if (response.TransferStatus == (ushort)TransferStatus.Done)
            {
                returnValue = RopResult.Success;

                int bufferlength = 0;
                foreach (byte[] blengt in this.totalTransferBufferList)
                {
                    bufferlength += blengt.Length;
                }

                byte[] totalTransferBuffer = new byte[bufferlength];
                int index = 0;
                foreach (byte[] buffer in this.totalTransferBufferList)
                {
                    Array.Copy(buffer, 0, totalTransferBuffer, index, buffer.Length);
                    index += buffer.Length;
                }

                byte[] requiredTransferBuffer = this.ProcessFXSourceGetBuffer(totalTransferBuffer);

                using (FastTransferStream fs = new FastTransferStream(requiredTransferBuffer, true))
                {
                    // Verify FastTransfer Stream
                    this.VerifyFastTransferStream(fs, this.streamType);
                }

                abstractFastTransferStream = this.GenerateAbstractFastTransferStream(serverId, requiredTransferBuffer);
                if (bufferSize == BufferSize.Greater)
                {
                    transferBufferIndex = -1;
                }
                else
                {
                    transferBufferIndex = AdapterHelper.GetStreamBufferIndex();
                }

                int k = this.streamBufferContainer.Count;
                foreach (byte[] subBuffer in this.totalTransferBufferList)
                {
                    this.streamBufferContainer.Add(++k, subBuffer);
                }
            }

            if (response.RopId != 0x00)
            {
                // Verify ROP FastTransferSourceGetBuffer
                this.VerifyRopFastTransferSourceGetBuffer(response);
            }

            return returnValue;
        }
Esempio n. 8
0
        public static RopResult FastTransferSourceGetBuffer(int serverId, int downloadHandleIndex, BufferSize bufferSize, out int transferBufferIndex, out AbstractFastTransferStream abstractFastTransferStream, out bool transferDataSmallOrEqualToBufferSize)
        {
            // The contractions conditions.
            Condition.IsTrue(connections.Count > 0);
            Condition.IsTrue(connections.Keys.Contains(serverId));

            // Initialize the return value.
            RopResult result = RopResult.InvalidParameter;
            transferBufferIndex = -1;
            abstractFastTransferStream = new AbstractFastTransferStream();
            transferDataSmallOrEqualToBufferSize = false;

            if (bufferSize == BufferSize.Greater)
            {
                result = RopResult.BufferTooSmall;
                return result;
            }

            // Get current ConnectionData value.
            ConnectionData currentConnection = connections[serverId];

            // Create a new currentDownloadContext.
            AbstractDownloadInfo currentDownloadContext = new AbstractDownloadInfo();

            // Identify whether the Download context is existent or not.
            bool isDownloadHandleExist = false;

            // Find the current Download Context
            foreach (AbstractDownloadInfo tempDownloadContext in currentConnection.DownloadContextContainer)
            {
                if (tempDownloadContext.DownloadHandleIndex == downloadHandleIndex)
                {
                    // Set the value to the related variable when the download context is existent.
                    isDownloadHandleExist = true;
                    result = RopResult.Success;
                    currentDownloadContext = tempDownloadContext;
                    int infoIndex = currentConnection.DownloadContextContainer.IndexOf(tempDownloadContext);

                    // Get the Data buffer index
                    transferBufferIndex = AdapterHelper.GetStreamBufferIndex();
                    currentDownloadContext.DownloadStreamIndex = transferBufferIndex;
                    abstractFastTransferStream.StreamType = currentDownloadContext.AbstractFastTransferStreamType;
                    currentConnection.DownloadContextContainer = currentConnection.DownloadContextContainer.Update(infoIndex, currentDownloadContext);
                }
            }

            // Create new variable relate to current folder.
            AbstractFolder currentFolder = new AbstractFolder();
            int currentFolderIndex = 0;

            // Identify current whether DownloadHandle is existent or not.
            if (isDownloadHandleExist)
            {
                // If bufferSize is set to a value other than 0xBABE
                if (bufferSize != BufferSize.Normal)
                {
                    transferDataSmallOrEqualToBufferSize = true;

                    ModelHelper.CaptureRequirement(
                        2142,
                        @"[In Receiving a RopFastTransferSourceGetBuffer Request]If the value of BufferSize in the ROP request is set to a value other than 0xBABE, the following semantics apply:The server MUST output, at most, the number of bytes specified by the BufferSize field in the 
                        TransferBuffer field even if more data is available.");
                    ModelHelper.CaptureRequirement(
                        2143,
                        @"[In Receiving a RopFastTransferSourceGetBuffer Request]If the value of BufferSize in the ROP request is set to a value other than 
                        0xBABE, the following semantics apply:The server returns less bytes than the value specified by the BufferSize field, or the server 
                        returns the number of bytes specified by the BufferSize field in the TransferBuffer field.");
                }

                #region Requirements about RopOperation Response

                // FolderHandleIndex is the Index of the FastTransfer download context
                if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                {
                    ModelHelper.CaptureRequirement(384, "[In RopFastTransferSourceCopyTo ROP Response Buffer] OutputServerObject: The value of this field MUST be the FastTransfer download context.");
                }
                else if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyProperties)
                {
                    ModelHelper.CaptureRequirement(455, "[In RopFastTransferSourceCopyProperties ROP Response Buffer] OutputServerObject: The value of this field MUST be the FastTransfer download context. ");
                }
                else if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyMessage)
                {
                    ModelHelper.CaptureRequirement(487, @"[In RopFastTransferSourceCopyMessages ROP Response Buffer]OutputServerObject: The value of this field MUST be the FastTransfer download context.");
                }
                else if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyFolder)
                {
                    ModelHelper.CaptureRequirement(511, @"[In RopFastTransferSourceCopyFolder ROP Response Buffer]OutputServerObject: The value of this field MUST be the FastTransfer download context.");
                }
                #endregion

                // Get the related folder for the download handle in the folder container.
                foreach (AbstractFolder tempfolder in currentConnection.FolderContainer)
                {
                    if (tempfolder.FolderHandleIndex == currentDownloadContext.RelatedObjectHandleIndex)
                    {
                        currentFolder = tempfolder;
                        currentFolderIndex = currentConnection.FolderContainer.IndexOf(tempfolder);
                        break;
                    }
                }

                // Identify the abstractFastTransferStream type
                switch (currentDownloadContext.AbstractFastTransferStreamType)
                {
                    // The hierarchySync element contains the result of the hierarchy synchronization download operation
                    case FastTransferStreamType.hierarchySync:
                        {
                            if (currentDownloadContext.SynchronizationType == SynchronizationTypes.Hierarchy && priorDownloadOperation == PriorDownloadOperation.RopSynchronizationConfigure)
                            {
                                // Because if the synchronizationType in synchronization configure and the stream type return are Hierarchy indicate this requirement verified.
                                ModelHelper.CaptureRequirement(
                                    3322,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopSynchronizationConfigure, ROP request buffer field conditions is The SynchronizationType field is set to Hierarchy (0x02), Root element in the produced FastTransfer stream is hierarchySync.");
                            }

                            // Create a new HierarchySync.
                            abstractFastTransferStream.AbstractHierarchySync = new AbstractHierarchySync
                            {
                                FolderchangeInfo = new AbstractFolderChange(),
                                AbstractDeletion =
                                {
                                    IdSetDeleted = new Set<int>()
                                },
                                FinalICSState =
                                    new AbstractState
                                    {
                                        AbstractICSStateIndex = AdapterHelper.GetICSStateIndex(),
                                        IsNewCnsetSeenFAIPropertyChangeNumber = false
                                    }
                            };

                            // Assigned a new final ICS State for HierarchySync.

                            // This isn't New ChangeNumber for CnsetSeenFAIProperty in Initialize.

                            // Because of the SynchronizationType must optioned "Hierarchy" value in RopSynchronizationConfigure operation  if FastTransferStreamType is hierarchySync.
                            ModelHelper.CaptureRequirement(1209, "[In state Element] [MetaTagCnsetSeenFAI, Conditional] MetaTagCnsetSeenFAI MUST NOT be present if the SynchronizationType field is set to Hierarchy (0x02), as specified in section 2.2.3.2.1.1.1.");

                            // This isn't New ChangeNumber for CnsetReadProperty in Initialize.
                            abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IsNewCnsetReadPropertyChangeNumber = false;
                            ModelHelper.CaptureRequirement(1211, "[In state Element] [MetaTagCnsetRead,Conditional] MetaTagCnsetRead MUST NOT be present if the SynchronizationType field is set to Hierarchy (0x02).");

                            // In case of SynchronizationExtraFlag is EID in current DownloadContext.
                            if (((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.Eid) == SynchronizationExtraFlag.Eid) && (currentFolder.SubFolderIds.Count > 0))
                            {
                                // Because the SynchronizationExtraFlag is EID and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                ModelHelper.CaptureRequirement(2730, "[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] Reply is the same whether unknown flags [0x00000010] is set or not.");

                                // In case of SynchronizationExtraFlag is EID in current DownloadContext.
                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.Eid) == SynchronizationExtraFlag.Eid)
                                {
                                    // The PidTagFolderId must be exist  in folder change of HierarchySync.
                                    abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagFolderIdExist = true;

                                    // Because the SynchronizationExtraFlag is EID and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                    ModelHelper.CaptureRequirement(1095, "[In folderChange Element] [PidTagFolderId, Conditional] PidTagFolderId MUST be present if and only if the Eid flag of the SynchronizationExtraFlags field is set.");
                                    ModelHelper.CaptureRequirement(
                                                        2191,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagFolderId property (section 2.2.1.2.2) in a folder change header if and only if the Eid flag of the SynchronizationExtraFlags field flag is set.");
                                    ModelHelper.CaptureRequirement(
                                                      2761,
                                                      @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMid property (section 2.2.1.2.1) in a message change header if and only if the Eid flag of the SynchronizationExtraFlags field is set.");

                                    if (currentDownloadContext.SynchronizationType == SynchronizationTypes.Hierarchy)
                                    {
                                        ModelHelper.CaptureRequirement(
                                                       3500,
                                                       @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagFolderId property in the folder change header if the SynchronizationType field is set to Hierarchy (0x02), as specified in section 2.2.3.2.1.1.1.");
                                    }
                                }
                                else
                                {
                                    // The PidTagFolderId must be not exist  in folder change of HierarchySync.
                                    abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagFolderIdExist = false;
                                    ModelHelper.CaptureRequirement(
                                                   716001,
                                                   @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is Eid, the value is 0x00000001] The server does not include the PidTagFolderId (section 2.2.1.2.2) property in the folder change header when the Eid flag of the SynchronizationExtraFlag field is not set.");
                                }
                            }
                            else
                            {
                                // The PidTagFolderId must be not exist  in folder change of HierarchySync.
                                abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagFolderIdExist = false;
                                ModelHelper.CaptureRequirement(
                                                   716001,
                                                   @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is Eid, the value is 0x00000001] The server does not include the PidTagFolderId (section 2.2.1.2.2) property in the folder change header when the Eid flag of the SynchronizationExtraFlag field is not set.");
                            }

                            // In case of SynchronizationExtraFlag is NoForeignIdentifiers in current DownloadContext.
                            if (((currentDownloadContext.Synchronizationflag & SynchronizationFlag.NoForeignIdentifiers) == SynchronizationFlag.NoForeignIdentifiers) && (currentFolder.SubFolderIds.Count > 0))
                            {
                                // The PidTagParentFolderId must be exist  in folder change of HierarchySync.
                                abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagParentFolderIdExist = true;
                                ModelHelper.CaptureRequirement(1097, "[In folderChange Element] [PidTagParentFolderId, Conditional] PidTagParentFolderId MUST be present if the NoForeignIdentifiers flag of the SynchronizationFlags field is set.");

                                // The PidTagParentSourceKey and PidTagSourceKey  must be exist  in folder change of HierarchySync.
                                abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagParentSourceKeyValueZero = false;
                                abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagSourceKeyValueZero = false;

                                ModelHelper.CaptureRequirement(
                                    2178001,
                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoForeignIdentifiers flag of the SynchronizationFlags field is set, server will return null values for the PidTagSourceKey property (section 2.2.1.2.5) and PidTagParentSourceKey (section 2.2.1.2.6) properties when producing the FastTransfer stream for folder and message changes.");
                                ModelHelper.CaptureRequirement(2077, "[In Generating the PidTagSourceKey Value] When requested by the client, the server MUST output the PidTagSourceKey property (section 2.2.1.2.5) value if it is persisted.");
                                ModelHelper.CaptureRequirement(
                                    2179001,
                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoForeignIdentifiers flag of the SynchronizationFlags field is not set, server will return not null values for the PidTagSourceKey and PidTagParentSourceKey properties when producing the FastTransfer stream for folder and message changes.");
                            }
                            else
                            {
                                // The PidTagFolderId must be not exist  in folder change of HierarchySync.
                                abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagParentFolderIdExist = false;
                            }

                            // Sub folder count.
                            int subFolderCount = 0;

                            // Record all descendant folders.
                            Set<int> allDescendantFolders = new Set<int>();
                            if (currentFolder.SubFolderIds.Count > 0)
                            {
                                // Search the current folder in FolderContainer.
                                foreach (AbstractFolder tempFolder in currentConnection.FolderContainer)
                                {
                                    if (currentFolder.FolderIdIndex == tempFolder.ParentFolderIdIndex)
                                    {
                                        // Set the value to the related variable when the current folder is existent.
                                        if (!currentDownloadContext.UpdatedState.IdsetGiven.Contains(tempFolder.FolderIdIndex))
                                        {
                                            // Because of identify that It is a folder by (CurrentFolder.FolderIdIndex == tempFolder.ParentFolderIdIndex) and identify that change number is not in PidTagCnsetSeen by (!currentDownloadContext.UpdatedState.CnsetSeen.Contains(tempFolder.changeNumberIndex)). so can cover requirement here.
                                            ModelHelper.CaptureRequirement(
                                                2042,
                                                @"[In Determining What Differences To Download] For every object in the synchronization scope, servers MUST do the following: 	Include the following syntactical elements in the FastTransfer stream of the OutputServerObject field of the FastTransfer download ROPs, as specified in section 2.2.3.1.1, if one of the following applies:
	Include the folderChange element, as specified in section 2.2.4.3.5, if the object specified by the InputServerObject field of the FastTransfer download ROP request is a Folder object
	And the change number is not included in the value of the MetaTagCnsetSeen property (section 2.2.1.1.2).");

                                            // Add current folder id to IdsetGiven of DownloadContext when the IdsetGiven of updatedState contains the current folder id.
                                            currentDownloadContext.UpdatedState.IdsetGiven = currentDownloadContext.UpdatedState.IdsetGiven.Add(tempFolder.FolderIdIndex);

                                            // Assign a new change number for CnsetSeenProperty.
                                            abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = true;

                                            if (priorUploadOperation == PriorOperation.RopSynchronizationImportHierarchyChange)
                                            {
                                                ModelHelper.CaptureRequirement(
                                                    2235,
                                                    @"[In Receiving a RopSynchronizationImportHierarchyChange Request] Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated to include a new change number in the MetaTagCnsetSeen property (section 2.2.1.1.2).");
                                            }

                                            subFolderCount++;
                                        }
                                        else
                                        {
                                            if (!currentDownloadContext.UpdatedState.CnsetSeen.Contains(tempFolder.ChangeNumberIndex))
                                            {
                                                // Add current folder id to updatedState.IdsetGiven when the IdsetGiven of updatedState contains the current folder id.
                                                currentDownloadContext.UpdatedState.CnsetSeen = currentDownloadContext.UpdatedState.CnsetSeen.Add(tempFolder.ChangeNumberIndex);
                                                abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = true;

                                                // Because of identify that It is a folder by (CurrentFolder.FolderIdIndex == tempFolder.ParentFolderIdIndex) and identify that change number is not in PidTagCnsetSeen by (!currentDownloadContext.UpdatedState.CnsetSeen.Contains(tempFolder.changeNumberIndex)). so can cover requirement here.
                                                ModelHelper.CaptureRequirement(
                                                    2042,
                                                    @"[In Determining What Differences To Download] For every object in the synchronization scope, servers MUST do the following: 	Include the following syntactical elements in the FastTransfer stream of the OutputServerObject field of the FastTransfer download ROPs, as specified in section 2.2.3.1.1, if one of the following applies:
	Include the folderChange element, as specified in section 2.2.4.3.5, if the object specified by the InputServerObject field of the FastTransfer download ROP request is a Folder object
	And the change number is not included in the value of the MetaTagCnsetSeen property (section 2.2.1.1.2).");

                                                if (priorUploadOperation == PriorOperation.RopSynchronizationImportHierarchyChange)
                                                {
                                                    ModelHelper.CaptureRequirement(
                                                        2235,
                                                        @"[In Receiving a RopSynchronizationImportHierarchyChange Request] Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated to include a new change number in the MetaTagCnsetSeen property (section 2.2.1.1.2).");
                                                }

                                                subFolderCount++;
                                            }
                                        }

                                        // In case of current folder's subFolder count greater the 0.
                                        if (tempFolder.SubFolderIds.Count > 0)
                                        {
                                            // Find the second Folder in FolderContainer which was created under current folder.
                                            foreach (AbstractFolder secondFolder in currentConnection.FolderContainer)
                                            {
                                                if (secondFolder.ParentFolderIdIndex == tempFolder.FolderIdIndex)
                                                {
                                                    if (!currentDownloadContext.UpdatedState.IdsetGiven.Contains(secondFolder.FolderIdIndex))
                                                    {
                                                        // Add current folder id to updatedState.IdsetGiven when the IdsetGiven of updatedState contains the current folder id.
                                                        currentDownloadContext.UpdatedState.IdsetGiven = currentDownloadContext.UpdatedState.IdsetGiven.Add(secondFolder.FolderIdIndex);

                                                        // Assign a new change number for CnsetSeenPropery.
                                                        abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = true;

                                                        if (priorUploadOperation == PriorOperation.RopSynchronizationImportHierarchyChange)
                                                        {
                                                            ModelHelper.CaptureRequirement(
                                                                2235,
                                                                @"[In Receiving a RopSynchronizationImportHierarchyChange Request] Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated to include a new change number in the MetaTagCnsetSeen property (section 2.2.1.1.2).");
                                                        }

                                                        subFolderCount++;
                                                    }
                                                    else
                                                    {
                                                        if (!currentDownloadContext.UpdatedState.CnsetSeen.Contains(secondFolder.ChangeNumberIndex))
                                                        {
                                                            // Add current folder id to updatedState.CnsetSeen when the CnsetSeen of updatedState contains the current folder id.
                                                            currentDownloadContext.UpdatedState.CnsetSeen = currentDownloadContext.UpdatedState.CnsetSeen.Add(secondFolder.ChangeNumberIndex);

                                                            // Assign a new change number for CnsetSeenProperty.
                                                            abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = true;

                                                            if (priorUploadOperation == PriorOperation.RopSynchronizationImportHierarchyChange)
                                                            {
                                                                ModelHelper.CaptureRequirement(
                                                                    2235,
                                                                    @"[In Receiving a RopSynchronizationImportHierarchyChange Request] Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated to include a new change number in the MetaTagCnsetSeen property (section 2.2.1.1.2).");
                                                            }

                                                            subFolderCount++;
                                                        }
                                                    }
                                                }

                                                // Add second Folder to descendant folder.
                                                allDescendantFolders = allDescendantFolders.Add(secondFolder.FolderIdIndex);
                                            }
                                        }

                                        // Add second Folder to descendant folder.
                                        allDescendantFolders = allDescendantFolders.Add(tempFolder.FolderIdIndex);
                                    }
                                }
                            }

                            // Search the Descendant folderId in IdsetGiven.
                            foreach (int folderId in currentDownloadContext.UpdatedState.IdsetGiven)
                            {
                                // Identify whether the last Updated Id is or not in Descendant Folder.
                                if (!allDescendantFolders.Contains(folderId))
                                {
                                    if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.NoDeletions) == SynchronizationFlag.NoDeletions)
                                    {
                                        if (requirementContainer.ContainsKey(1062) && requirementContainer[1062])
                                        {
                                            // Deletions isn't present in deletions.
                                            abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IsDeletionPresent = false;
                                            ModelHelper.CaptureRequirement(
                                                1062,
                                                @"[In deletions Element] Implementation does not present deletions element if the NoDeletions flag of the SynchronizationFlag field, as specified in section 2.2.3.2.1.1.1, was set when the synchronization download operation was configured. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                        }

                                        // Deletions isn't present in deletions.
                                        abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IsDeletionPresent = false;
                                        ModelHelper.CaptureRequirement(
                                            2165,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoDeletions flag of the SynchronizationFlags field is set, the server MUST NOT download information about item deletions, as specified in section 2.2.4.3.3");
                                    }
                                    else
                                    {
                                        // Deletions is present in deletions.
                                        abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IsDeletionPresent = true;

                                        // PidTagIdsetNoLongerInScope be present in deletions
                                        abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IsPidTagIdsetNoLongerInScopeExist = false;
                                        ModelHelper.CaptureRequirement(
                                                    1333,
                                                    @"[In deletions Element] [The following restrictions exist on the contained propList element, as specified in section 2.2.4.3.20:] MUST adhere to the following restrictions: MetaTagIdsetNoLongerInScope MUST NOT be present if the Hierarchy value of the SynchronizationType field is set, as specified in section 2.2.3.2.1.1.1.");

                                        // Are folders that have never been reported as deleted
                                        abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IsPidTagIdsetExpiredExist = false;
                                        ModelHelper.CaptureRequirement(
                                                    2046,
                                                    @"[In Determining What Differences To Download] [For every object in the synchronization scope, servers MUST do the following:] If the NoDeletions flag of the SynchronizationFlags field is not set, include the deletions element, as specified in section 2.2.4.3.3, for objects that either: 
Have their internal identifiers present in the value of the MetaTagIdsetGiven property (section 2.2.1.1.1) and are missing from the server replica.Are folders that have never been reported as deleted folders.
Are folders that have never been reported as deleted folders.");

                                        ModelHelper.CaptureRequirement(
                                            1337002,
                                            @"[In deletions Element] [The following restrictions exist on the contained propList element, as specified in section 2.2.4.3.20:] MUST adhere to the following restrictions: ] MetaTagIdsetExpired (section 2.2.1.3.3) MUST NOT be present if the Hierarchy value of the SynchronizationType field is set. ");

                                        // Because isPidTagIdsetExpiredExist value is false so have their internal identifiers present in PidTagIdsetGiven and isDeletionPresent is true to those are missing from the server replica. So cover requirement here.
                                        ModelHelper.CaptureRequirement(
                                            2045,
                                            @"[In Determining What Differences To Download] [For every object in the synchronization scope, servers MUST do the following:] If the NoDeletions flag of the SynchronizationFlag field is not set, include the deletions element, as specified in section 2.2.4.3.3, for objects that either:
	                                         Have their internal identifiers present in the value of the MetaTagIdsetGiven property (section 2.2.1.1.1) and are missing from the server replica.Are folders that have never been reported as deleted folders.
                                            Are folders that have never been reported as deleted folders.");

                                        // Identify the current ExchangeServer Version.
                                        if (requirementContainer.ContainsKey(2652) && requirementContainer[2652])
                                        {
                                            // Add folderId to IdSetDeleted of abstractDeletion
                                            abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IdSetDeleted = abstractFastTransferStream.AbstractHierarchySync.AbstractDeletion.IdSetDeleted.Add(folderId);

                                            // Because of execute RopSynchronizationImportHierarchyChange or RopSynchronizationImportMessageChange operation before execute RopSynchronizationImportDeletes operation, record deletions and  prevent it restoring them back finished in MS_OXCFXICSAdapter. So cover this requirement here.
                                            ModelHelper.CaptureRequirement(
                                                2652,
                                                @"[In Receiving a RopSynchronizationImportDeletes Request] Implementation does record deletions of objects that never existed in the server replica, in order to prevent the RopSynchronizationImportHierarchyChange (section 2.2.3.2.4.3) or RopSynchronizationImportMessageChange (section 2.2.3.2.4.2) ROPs from restoring them back. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                        }

                                        // Delete folder id from DownloadContext.
                                        currentDownloadContext.UpdatedState.IdsetGiven = currentDownloadContext.UpdatedState.IdsetGiven.Remove(folderId);

                                        // If NoDeletions flag is not set and the operation can be executed successfully, the element isDeletionPresent as true will be returned, which means the deletion elements is downloaded, so this requirement can be verified.
                                        ModelHelper.CaptureRequirement(
                                            2167,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoDeletions flag of the SynchronizationFlags field is not set, the server MUST download information about item deletions, as specified in section 2.2.4.3.3.");
                                    }

                                    // This is a new changeNumber
                                    abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = true;
                                    if (priorUploadOperation == PriorOperation.RopSynchronizationImportHierarchyChange)
                                    {
                                        ModelHelper.CaptureRequirement(
                                            2235,
                                            @"[In Receiving a RopSynchronizationImportHierarchyChange Request] Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated to include a new change number in the MetaTagCnsetSeen property (section 2.2.1.1.2).");
                                    }
                                }
                            }

                            // The lDescendantFolder is existent.
                            if (currentFolder.SubFolderIds == allDescendantFolders)
                            {
                                if (allDescendantFolders.Count > 0)
                                {
                                    // Parent folder is existent and PidTagParentSourceKey is not in folder change
                                    abstractFastTransferStream.AbstractHierarchySync.FolderchangeInfo.IsPidTagParentSourceKeyValueZero = true;
                                }
                            }
                            else
                            {
                                ModelHelper.CaptureRequirement(1129, "[In hierarchySync Element]The folderChange elements for the parent folders MUST be output before any of their child folders.");
                                abstractFastTransferStream.AbstractHierarchySync.IsParentFolderBeforeChild = true;
                            }

                            // Set value for finalICSState.
                            abstractFastTransferStream.AbstractHierarchySync.FinalICSState.IdSetGiven = currentDownloadContext.UpdatedState.IdsetGiven;
                            abstractFastTransferStream.AbstractHierarchySync.FolderCount = subFolderCount;
                            currentFolder.ICSStateContainer.Add(abstractFastTransferStream.AbstractHierarchySync.FinalICSState.AbstractICSStateIndex, currentDownloadContext.UpdatedState);

                            // Because of the "foreach" Search the Descendant folderId in IdsetGive  and the end of "foreach" search. So cover this requirement here.
                            ModelHelper.CaptureRequirement(1128, "[In hierarchySync Element]There MUST be exactly one folderChange element for each descendant folder of the root of the synchronization operation (that is the folder that was passed to the RopSynchronizationConfigure ROP, as specified in section 2.2.3.2.1.1) that is new or has been changed since the last synchronization.");

                            // Update the FolderContainer.
                            currentConnection.FolderContainer = currentConnection.FolderContainer.Update(currentFolderIndex, currentFolder);
                            connections[serverId] = currentConnection;

                            break;
                        }

                    // The state element contains the final ICS state of the synchronization download operation.
                    case FastTransferStreamType.state:
                        {
                            if (priorDownloadOperation == PriorDownloadOperation.RopSynchronizationGetTransferState)
                            {
                                // Because if the isRopSynchronizationGetTransferState called the steam type return by RopFastTransferSourceGetBuffer should be State
                                ModelHelper.CaptureRequirement(
                                    3323,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopSynchronizationGetTransferState, ROP request buffer field conditions is always, Root element in the produced FastTransfer stream is state.");
                            }

                            // Create a new abstractState.
                            abstractFastTransferStream.AbstractState = new AbstractState
                            {
                                AbstractICSStateIndex = AdapterHelper.GetICSStateIndex()
                            };

                            // Assign a new ICS State Index.

                            // The new IdSetGiven of State value equal to IdsetGiven of current download context.
                            if (requirementContainer.ContainsKey(350400101) && requirementContainer[350400101] && (priorOperation == PriorOperation.RopSynchronizationOpenCollector))
                            {
                                abstractFastTransferStream.AbstractState.IdSetGiven = new Set<int>();
                                ModelHelper.CaptureRequirement(
                                    350400101,
                                    @"[In Appendix A: Product Behavior] Implementation does use this behavior. <40> Section 3.2.5.9.3.1: In Exchange 2007, the RopSynchronizationGetTransferState ROP (section 2.2.3.2.3.1) returns a checkpoint ICS state that is reflective of the current status.");
                            }
                            else
                            {
                                abstractFastTransferStream.AbstractState.IdSetGiven = currentDownloadContext.UpdatedState.IdsetGiven;
                            }

                            // Add the new stat to ICSStateContainer.
                            currentFolder.ICSStateContainer.Add(abstractFastTransferStream.AbstractState.AbstractICSStateIndex, currentDownloadContext.UpdatedState);
                            currentConnection.FolderContainer = currentConnection.FolderContainer.Update(currentFolderIndex, currentFolder);
                            connections[serverId] = currentConnection;
                            break;
                        }

                    // The messageContent element represents the content of a message.
                    case FastTransferStreamType.contentsSync:
                        {
                            if (currentDownloadContext.SynchronizationType == SynchronizationTypes.Contents && priorDownloadOperation == PriorDownloadOperation.RopSynchronizationConfigure)
                            {
                                // Because if the synchronizationType in synchronization configure and the stream type return are contents indicate this requirement verified.
                                ModelHelper.CaptureRequirement(
                                    3321,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopSynchronizationConfigure, ROP request buffer field conditions is The SynchronizationType field is set to Contents (0x01), Root element in the produced FastTransfer stream is contentsSync.");
                            }

                            // Create a new abstractContentsSync.
                            abstractFastTransferStream.AbstractContentsSync = new AbstractContentsSync
                            {
                                MessageInfo = new Set<AbstractMessageChangeInfo>(),
                                AbstractDeletion =
                                {
                                    IdSetDeleted = new Set<int>()
                                },
                                FinalICSState = new AbstractState
                                {
                                    // Assign abstractICSStateIndex.
                                    AbstractICSStateIndex = AdapterHelper.GetICSStateIndex()
                                }
                            };

                            // Create a new finalICSState.
                            if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Progress) == SynchronizationFlag.Progress)
                            {
                                // The current ContentsSync is include progressTotal.
                                abstractFastTransferStream.AbstractContentsSync.IsprogessTotalPresent = true;
                                ModelHelper.CaptureRequirement(1179, "[In progressTotal Element]This element MUST be present if the Progress flag of the SynchronizationFlags field, as specified in section 2.2.3.2.1.1.1, was set when configuring the synchronization download operation and a server supports progress reporting.");

                                if (requirementContainer.ContainsKey(2675) && requirementContainer[2675])
                                {
                                    // The current ContentsSync is include progressTotal.
                                    abstractFastTransferStream.AbstractContentsSync.IsprogessTotalPresent = true;

                                    // The current server is exchange.
                                    ModelHelper.CaptureRequirement(
                                        2675,
                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] Implementation does inject the progressTotal element, as specified in section 2.2.4.3.19, into the FastTransfer stream, if the Progress flag of the SynchronizationFlag field is set. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                }
                            }
                            else
                            {
                                // The current ContentsSync is not include progressTotal.
                                abstractFastTransferStream.AbstractContentsSync.IsprogessTotalPresent = false;
                                ModelHelper.CaptureRequirement(
                                    2188,
                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the Progress flag of the SynchronizationFlags field is not set, the server MUST not inject the progressTotal element into the FastTransfer stream.");
                                ModelHelper.CaptureRequirement(1180, "[In progressTotal Element]This element MUST NOT be present if the Progress flag of the SynchronizationFlags field was not set when configuring the synchronization download operation.");
                            }

                            // Search the message ids in IdsetGiven.
                            foreach (int messageId in currentDownloadContext.UpdatedState.IdsetGiven)
                            {
                                if (!currentFolder.MessageIds.Contains(messageId))
                                {
                                    // Assign a new change number for CnsetRead Property.
                                    if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.NoDeletions) == SynchronizationFlag.NoDeletions)
                                    {
                                        // The server MUST NOT download information about item deletions.
                                        abstractFastTransferStream.AbstractContentsSync.AbstractDeletion.IsDeletionPresent = false;
                                        ModelHelper.CaptureRequirement(
                                            2165,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoDeletions flag of the SynchronizationFlags field is set, the server MUST NOT download information about item deletions, as specified in section 2.2.4.3.3");
                                        ModelHelper.CaptureRequirement(
                                            2166,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoDeletions flag of the SynchronizationFlags field is set, the server MUST respond as if the IgnoreNoLongerInScope flag was set.");
                                    }
                                    else if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.IgnoreNoLongerInScope) != SynchronizationFlag.IgnoreNoLongerInScope)
                                    {
                                        // The server MUST  download information about item deletions.
                                        abstractFastTransferStream.AbstractContentsSync.AbstractDeletion.IsDeletionPresent = true;
                                        ModelHelper.CaptureRequirement(
                                            2167,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the NoDeletions flag of the SynchronizationFlags field is not set, the server MUST download information about item deletions, as specified in section 2.2.4.3.3.");

                                        // Identify the current ExchangeServer Version.
                                        if (requirementContainer.ContainsKey(2652) && requirementContainer[2652])
                                        {
                                            // Add messageId to abstractDeletion of abstractDeletion.
                                            abstractFastTransferStream.AbstractContentsSync.AbstractDeletion.IdSetDeleted = abstractFastTransferStream.AbstractContentsSync.AbstractDeletion.IdSetDeleted.Add(messageId);

                                            // Because of execute RopSynchronizationImportHierarchyChange or RopSynchronizationImportMessageChange operation before execute RopSynchronizationImportDeletes operation, record deletions and  prevent it restoring them back finished in MS_OXCFXICSAdapter. So cover this requirement here.
                                            ModelHelper.CaptureRequirement(
                                                2652,
                                                @"[In Receiving a RopSynchronizationImportDeletes Request] Implementation does record deletions of objects that never existed in the server replica, in order to prevent the RopSynchronizationImportHierarchyChange (section 2.2.3.2.4.3) or RopSynchronizationImportMessageChange (section 2.2.3.2.4.2) ROPs from restoring them back. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                        }

                                        currentDownloadContext.UpdatedState.IdsetGiven = currentDownloadContext.UpdatedState.IdsetGiven.Remove(messageId);
                                        ModelHelper.CaptureRequirement(
                                            2169,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the IgnoreNoLongerInScope flag of the SynchronizationFlags field is not set, the server MUST download information about messages that went out of scope as deletions, as specified in section 2.2.4.3.3.");
                                    }

                                    if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.IgnoreNoLongerInScope) == SynchronizationFlag.IgnoreNoLongerInScope)
                                    {
                                        // PidTagIdsetNoLongerInScope MUST NOT be present.
                                        abstractFastTransferStream.AbstractContentsSync.AbstractDeletion.IsPidTagIdsetNoLongerInScopeExist = false;
                                        ModelHelper.CaptureRequirement(1334, @"[In deletions Element] [The following restrictions exist on the contained propList element, as specified in section 2.2.4.3.20:] MUST adhere to the following restrictions: MetaTagIdsetNoLongerInScope MUST NOT be present if the IgnoreNoLongerInScope flag of the SynchronizationFlags field is set.");
                                        ModelHelper.CaptureRequirement(
                                            2168,
                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the IgnoreNoLongerInScope flag of the SynchronizationFlags field is set, the server MUST NOT download information about messages that went out of scope as deletions, as specified in section 2.2.4.3.3.");
                                    }
                                }
                            }
                            #region Set message change contents

                            // Search the current message which match search condition in MessageContainer
                            foreach (AbstractMessage tempMessage in currentConnection.MessageContainer)
                            {
                                if (tempMessage.FolderIdIndex == currentFolder.FolderIdIndex)
                                {
                                    // The found message is FAI message.
                                    if (tempMessage.IsFAImessage)
                                    {
                                        if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.FAI) == SynchronizationFlag.FAI)
                                        {
                                            if (!currentDownloadContext.UpdatedState.IdsetGiven.Contains(tempMessage.MessageIdIndex))
                                            {
                                                // Create a new messageChange of contentSync.
                                                AbstractMessageChangeInfo newMessageChange = new AbstractMessageChangeInfo
                                                {
                                                    MessageIdIndex = tempMessage.MessageIdIndex,
                                                    IsMessageChangeFull = true
                                                };

                                                // Set the value for new messageChange.

                                                // This MessageChangeFull is in  new message change.
                                                if ((currentDownloadContext.Sendoptions & SendOptionAlls.PartialItem) != SendOptionAlls.PartialItem)
                                                {
                                                    ModelHelper.CaptureRequirement(
                                                        1135,
                                                        @"[In messageChange Element] A server MUST use the messageChangeFull element, instead of the messageChangePartial element, if any of the following are true: 	The PartialItem flag of the SendOptions field was not set, as specified in section 2.2.3.2.1.1.");
                                                }

                                                // Because SynchronizationFlag is set FAI and isMessageChangeFull is true  so can cover requirement here.
                                                ModelHelper.CaptureRequirement(1137, @"[In messageChange Element] [A server MUST use the messageChangeFull element, instead of the messageChangePartial element, if any of the following are true:] The message is an FAI message.");
                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.CN) == SynchronizationExtraFlag.CN)
                                                {
                                                    // PidTagChangeNumber must be present .
                                                    newMessageChange.IsPidTagChangeNumberExist = true;

                                                    // Because the SynchronizationExtraFlag is CN and the SynchronizationExtraFlag only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(1367, "[In messageChangeHeader Element, PidTagChangeNumber,Conditional]PidTagChangeNumber MUST be present if and only if the CN flag of the SynchronizationExtraFlags field is set.");

                                                    // Because the SynchronizationExtraFlag is CN and the SynchronizationExtraFlag only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2196,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagChangeNumber property (section 2.2.1.2.3) in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    // PidTagChangeNumber must not present .
                                                    newMessageChange.IsPidTagChangeNumberExist = false;

                                                    // Because the SynchronizationExtraFlag is not CN and the SynchronizationExtraFlag only don't set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2197,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST NOT include the PidTagChangeNumber property in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.Eid) == SynchronizationExtraFlag.Eid)
                                                {
                                                    // The server MUST include the PidTagMid property in the messageChange.
                                                    newMessageChange.IsPidTagMidExist = true;

                                                    // Because the SynchronizationExtraFlag is EID and the SynchronizationExtraFlag only set EID. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(1363, "[In messageChangeHeader Element] [PidTagMid,Conditional] PidTagMid MUST be present if and only if the Eid flag of the SynchronizationExtraFlags field is set, as specified in section 2.2.3.2.1.1.1.");
                                                }
                                                else
                                                {
                                                    // The server don't include the PidTagFolderId property in the messageChange. 
                                                    newMessageChange.IsPidTagMidExist = false;
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.MessageSize) == SynchronizationExtraFlag.MessageSize)
                                                {
                                                    // The server include the PidTagMessageSize property in the messageChange. 
                                                    newMessageChange.IsPidTagMessageSizeExist = true;

                                                    // Because the SynchronizationExtraFlag is MessageSize and the SynchronizationExtraFlag only set MessageSize. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2195,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMessageSize property (section 2.2.1.6) in the message change header if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");
                                                    ModelHelper.CaptureRequirement(
                                                        1365,
                                                        @"[In messageChangeHeader Element] [PidTagMessageSize,Conditional] PidTagMessageSize MUST be present if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");
                                                }

                                                if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Progress) == SynchronizationFlag.Progress)
                                                {
                                                    // The server must include the ProgressPerMessage in the messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = true;

                                                    // Message object that follows is FAI
                                                    newMessageChange.FollowedFAIMessage = true;

                                                    // Because the SynchronizationExtraFlag is Progress and the SynchronizationExtraFlag only set Progress. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        1171,
                                                        @"[In progressPerMessage Element]MUST be present if and only if the progessTotal element, as specified in
                                                        section 2.2.4.3.18, was output within the same ancestor contentsSync element, as specified in section
                                                        2.2.4.3.2.");
                                                    ModelHelper.CaptureRequirement(
                                                        1382,
                                                        @"[In progressPerMessage Element] [[PtypBoolean] 0x0000000B] [The server returns] TRUE (0x01 or any non-zero value) if the Message object that follows is FAI.");
                                                }
                                                else
                                                {
                                                    // The server don't include the ProgressPerMessage in the messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = false;
                                                    ModelHelper.CaptureRequirement(
                                                        1172,
                                                        @"[In progressPerMessage Element] [ProgressPerMessage Element] MUST NOT be present if the Progress flag of the SynchronizationFlags field was not set when configuring the synchronization download operation.");
                                                }

                                                if (tempMessage.MessageProperties.Contains("PidTagBody"))
                                                {
                                                    if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.BestBody) != SynchronizationFlag.BestBody)
                                                    {
                                                        // Implementation does only support the message body (2) which is always in the original format
                                                        if (requirementContainer.ContainsKey(3118002) && requirementContainer[3118002])
                                                        {
                                                            newMessageChange.IsRTFformat = false;
                                                            ModelHelper.CaptureRequirement(
                                                                3118002,
                                                                @"[In Appendix A: Product Behavior] Implementation does only support the message body which is always in the original format. <3> Section 2.2.3.1.1.1.1: In Exchange 2013 and Exchange 2016, the message body is always in the original format.");
                                                        }

                                                        if (requirementContainer.ContainsKey(2117002) && requirementContainer[2117002])
                                                        {
                                                            // Identify whether message bodies in the compressed RTF format is or not.
                                                            newMessageChange.IsRTFformat = true;

                                                            // Because the BestBody flag of the CopyFlags field is not set before and the prior ROP is RopFastTransferSourceCopyMessages, so this requirement can be captured.
                                                            ModelHelper.CaptureRequirement(
                                                                2117002,
                                                                @"[In Appendix A: Product Behavior] <33> Section 3.2.5.8.1.3: Implementation does support the BestBody flag. If the BestBody flag of the CopyFlags field is not set, implementation does output message bodies in the compressed RTF (Microsoft Exchange Server 2007 and Exchange Server 2010 follow this behavior.)");
                                                        }

                                                        if (requirementContainer.ContainsKey(3118003) && requirementContainer[3118003])
                                                        {
                                                            // Identify whether message bodies in the compressed RTF format is or not.
                                                            newMessageChange.IsRTFformat = true;

                                                            // Because the BestBody flag of the CopyFlags field is not set before and the prior ROP is RopFastTransferSourceCopyMessages, so this requirement can be captured.
                                                            ModelHelper.CaptureRequirement(
                                                                3118003,
                                                                @"[In Appendix A: Product Behavior] Implementation does support this flag [BestBody flag] [in RopFastTransferSourceCopyTo ROP]. (<3> Section 2.2.3.1.1.1.1: Microsoft Exchange Server 2007 and 2010 follow this behavior.)");
                                                        }

                                                        if (requirementContainer.ContainsKey(499001) && requirementContainer[499001])
                                                        {
                                                            // Identify whether message bodies in the compressed RTF format is or not.
                                                            newMessageChange.IsRTFformat = false;

                                                            // Because the BestBody flag of the CopyFlags field is set before and the prior ROP is RopFastTransferSourceCopyMessages, so this requirement can be captured.
                                                            ModelHelper.CaptureRequirement(
                                                                   499001,
                                                                   @"[In Appendix A: Product Behavior] Implementation does only support the message body which is always in the original format. <5> Section 2.2.3.1.1.3.1: In Exchange 2013 and Exchange 2016, the message body is always in the original format.");
                                                        }

                                                        if (requirementContainer.ContainsKey(2182002) && requirementContainer[2182002])
                                                        {
                                                            // Identify whether message bodies in the compressed RTF format is or not.
                                                            newMessageChange.IsRTFformat = true;

                                                            // Because the BestBody flag of the CopyFlags field is set before and the prior ROP is RopFastTransferSourceCopyMessages, so this requirement can be captured.
                                                            ModelHelper.CaptureRequirement(
                                                                   2182002,
                                                                   @"[In Appendix A: Product Behavior] Implementation does support BestBody flag [in RopSynchronizationConfigure ROP]. (<38> Section 3.2.5.9.1.1: Microsoft Exchange Server 2007 and Exchange Server 2010 follow this behavior.)");
                                                        }
                                                    }
                                                }

                                                // Add new messagChange to ContentsSync.
                                                abstractFastTransferStream.AbstractContentsSync.MessageInfo = abstractFastTransferStream.AbstractContentsSync.MessageInfo.Add(newMessageChange);

                                                // Add message id to IdsetGiven of current download context.
                                                currentDownloadContext.UpdatedState.IdsetGiven = currentDownloadContext.UpdatedState.IdsetGiven.Add(tempMessage.MessageIdIndex);
                                                ModelHelper.CaptureRequirement(
                                                    2172,
                                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the FAI flag of the SynchronizationFlags field is set, the server MUST download information about changes to FAI messages, as specified by the folderContents element in section 2.2.4.3.7.");
                                            }
                                            else if (!currentDownloadContext.UpdatedState.CnsetSeenFAI.Contains(tempMessage.ChangeNumberIndex))
                                            {
                                                // The message change number is not in CnsetSeenFAI property.
                                                // Create a new  message change.
                                                AbstractMessageChangeInfo newMessageChange = new AbstractMessageChangeInfo
                                                {
                                                    MessageIdIndex = tempMessage.MessageIdIndex,
                                                    IsMessageChangeFull = true
                                                };

                                                // Set message id for new messageChange

                                                // The server don't include messagchangeFull in messageChange.
                                                ModelHelper.CaptureRequirement(
                                                    1137,
                                                    @"[In messageChange Element] [A server MUST use the messageChangeFull element, instead of the messageChangePartial element, if any of the following are true:] The message is an FAI message.");
                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.CN) == SynchronizationExtraFlag.CN)
                                                {
                                                    // The server MUST include the PidTagChangeNumber property in the message change
                                                    newMessageChange.IsPidTagChangeNumberExist = true;

                                                    // Because the SynchronizationExtraFlag is CN and the SynchronizationExtraFlag only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2196,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagChangeNumber property (section 2.2.1.2.3) in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    // The server don't include the PidTagChangeNumber property in the message change
                                                    newMessageChange.IsPidTagChangeNumberExist = false;

                                                    // Because the SynchronizationExtraFlag is not CN and the SynchronizationExtraFlag  not only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2197,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST NOT include the PidTagChangeNumber property in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.Eid) == SynchronizationExtraFlag.Eid)
                                                {
                                                    // The server MUST include the PidTagFolderId property in the messageChange.
                                                    newMessageChange.IsPidTagMidExist = true;

                                                    // Because the SynchronizationExtraFlag is EID and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2191,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagFolderId property (section 2.2.1.2.2) in a folder change header if and only if the Eid flag of the SynchronizationExtraFlags field flag is set.");

                                                    ModelHelper.CaptureRequirement(
                                                        2761,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMid property (section 2.2.1.2.1) in a message change header if and only if the Eid flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    // The server MUST NOT include the PidTagMid property in the messageChange.
                                                    newMessageChange.IsPidTagMidExist = false;

                                                    // Because the SynchronizationExtraFlag is Eid and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        716002,
                                                        @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is Eid, the value is 0x00000001] The server does not include the PidTagMid (section 2.2.1.2.1) property in the message change header when the Eid flag of the SynchronizationExtraFlag field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.MessageSize) == SynchronizationExtraFlag.MessageSize)
                                                {
                                                    ModelHelper.CaptureRequirement(
                                                        2195,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMessageSize property (section 2.2.1.6) in the message change header if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");

                                                    // The server MUST include the PidTagMessageSize property in the message change.
                                                    newMessageChange.IsPidTagMessageSizeExist = true;

                                                    // Because the SynchronizationExtraFlag is MessageSize and the SynchronizationExtraFlag only set MessageSize. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        1365,
                                                        @"[In messageChangeHeader Element] [PidTagMessageSize,Conditional] PidTagMessageSize MUST be present if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    newMessageChange.IsPidTagMessageSizeExist = false;

                                                    // When the MessageSize flag of the SynchronizationExtraFlag field is not set and the server does not include the PidTagMessageSize property (section 2.2.1.6) in the message change header this requirement captured.
                                                    ModelHelper.CaptureRequirement(
                                                        718001,
                                                        @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is MessageSize, the value is 0x00000002] The server does not include the PidTagMessageSize property (section 2.2.1.6) in the message change header if the MessageSize flag of the SynchronizationExtraFlag field is not set.");
                                                }

                                                if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Progress) == SynchronizationFlag.Progress)
                                                {
                                                    // The server include ProgressPerMessag in messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = true;

                                                    // The message is a FAl Message.
                                                    newMessageChange.FollowedFAIMessage = true;

                                                    // Because the SynchronizationExtraFlag is Progress and the SynchronizationExtraFlag only set Progress. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        1171,
                                                        @"[In progressPerMessage Element]MUST be present if and only if the progessTotal element, as specified in
                                                        section 2.2.4.3.18, was output within the same ancestor contentsSync element, as specified in section
                                                        2.2.4.3.2.");
                                                    ModelHelper.CaptureRequirement(1382, "[In progressPerMessage Element] [[PtypBoolean] 0x0000000B] [The server returns] TRUE (0x01 or any non-zero value) if the Message object that follows is FAI.");
                                                }
                                                else
                                                {
                                                    // The server don't include ProgressPerMessag in messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = false;
                                                    ModelHelper.CaptureRequirement(
                                                        1172,
                                                        @"[In progressPerMessage Element] [ProgressPerMessage Element] MUST NOT be present if the Progress flag of the SynchronizationFlags field was not set when configuring the synchronization download operation.");
                                                }

                                                if (!messagechangePartail && (requirementContainer.ContainsKey(2172) && !requirementContainer[2172]))
                                                {
                                                    abstractFastTransferStream.AbstractContentsSync.MessageInfo = new Set<AbstractMessageChangeInfo>();
                                                }
                                                else
                                                {
                                                    // Add new messagChange to ContentsSync.
                                                    abstractFastTransferStream.AbstractContentsSync.MessageInfo = abstractFastTransferStream.AbstractContentsSync.MessageInfo.Add(newMessageChange);
                                                    ModelHelper.CaptureRequirement(
                                                    2172,
                                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the FAI flag of the SynchronizationFlags field is set, the server MUST download information about changes to FAI messages, as specified by the folderContents element in section 2.2.4.3.7.");
                                                }
                                            }
                                        }
                                        else
                                        {
                                            // Because SynchronizationFlag FAI flag is not set and no have download context add to abstractFastTransferStream. So can cover this requirement here.
                                            ModelHelper.CaptureRequirement(
                                                2173,
                                                @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the FAI flag of the SynchronizationFlags field is not set, the server MUST NOT download information about changes to FAI messages, as specified by the folderContents element in section 2.2.4.3.7.");
                                        }
                                    }
                                    else
                                    {
                                        // The found message is Normal message.
                                        // SynchronizationFlag is Normal in download context.
                                        if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Normal) == SynchronizationFlag.Normal)
                                        {
                                            // The message id not in IdsetGiven of download context.
                                            if (!currentDownloadContext.UpdatedState.IdsetGiven.Contains(tempMessage.MessageIdIndex))
                                            {
                                                // Create a newMessageChange.
                                                AbstractMessageChangeInfo newMessageChange = new AbstractMessageChangeInfo
                                                {
                                                    MessageIdIndex = tempMessage.MessageIdIndex,
                                                    IsMessageChangeFull = true
                                                };

                                                // Set message id for newMessageChange.

                                                // This messagechangeFull is in newMessageChange.

                                                // Because the  message object include MId  and it is initial ICS state through set sequence.
                                                ModelHelper.CaptureRequirement(1136, "[In messageChange Element] [A server MUST use the messageChangeFull element, instead of the messageChangePartial element, if any of the following are true:] The MID structure ([MS-OXCDATA] section 2.2.1.2) of the message to be output is not in the MetaTagIdsetGiven property (section 2.2.1.1.1) from the initial ICS state.");
                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.CN) == SynchronizationExtraFlag.CN)
                                                {
                                                    // The server MUST include the PidTagChangeNumber property in the messageChange.
                                                    newMessageChange.IsPidTagChangeNumberExist = true;

                                                    // Because the SynchronizationExtraFlag is CN and the SynchronizationExtraFlag only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2196,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagChangeNumber property (section 2.2.1.2.3) in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    // The server don't include the PidTagChangeNumber property in the messageChange.
                                                    newMessageChange.IsPidTagChangeNumberExist = false;

                                                    // Because the SynchronizationExtraFlag is not CN and the SynchronizationExtraFlag not only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2197,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST NOT include the PidTagChangeNumber property in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.Eid) == SynchronizationExtraFlag.Eid)
                                                {
                                                    // The server MUST include the PidTagFolderId property in the messageChange.
                                                    newMessageChange.IsPidTagMidExist = true;

                                                    // Because the SynchronizationExtraFlag is EID and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2191,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagFolderId property (section 2.2.1.2.2) in a folder change header if and only if the Eid flag of the SynchronizationExtraFlags field flag is set.");

                                                    ModelHelper.CaptureRequirement(
                                                      2761,
                                                      @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMid property (section 2.2.1.2.1) in a message change header if and only if the Eid flag of the SynchronizationExtraFlags field is set.");

                                                    if (currentDownloadContext.SynchronizationType == SynchronizationTypes.Contents)
                                                    {
                                                        ModelHelper.CaptureRequirement(
                                                            3501,
                                                            @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMid property in the message change header if the SynchronizationType field is set Contents (0x01), as specified in section 2.2.3.2.1.1.1.");
                                                    }
                                                }
                                                else
                                                {
                                                    // The server don't include the PidTagFolderId property in the messageChange.
                                                    newMessageChange.IsPidTagMidExist = false;

                                                    // Because the SynchronizationExtraFlag is Eid and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        716002,
                                                        @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is Eid, the value is 0x00000001] The server does not include the PidTagMid (section 2.2.1.2.1) property in the message change header when the Eid flag of the SynchronizationExtraFlag field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.MessageSize) == SynchronizationExtraFlag.MessageSize)
                                                {
                                                    ModelHelper.CaptureRequirement(
                                                        2195,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMessageSize property (section 2.2.1.6) in the message change header if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");

                                                    // The server MUST include the PidTagMessageSize property in the messageChange.
                                                    newMessageChange.IsPidTagMessageSizeExist = true;

                                                    // Because the SynchronizationExtraFlag is MessageSize and the SynchronizationExtraFlag only set MessageSize. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        1365,
                                                        @"[In messageChangeHeader Element] [PidTagMessageSize,Conditional] PidTagMessageSize MUST be present if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    newMessageChange.IsPidTagMessageSizeExist = false;
                                                    ModelHelper.CaptureRequirement(
                                                        718001,
                                                        @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is MessageSize, the value is 0x00000002] The server does not include the PidTagMessageSize property (section 2.2.1.6) in the message change header if the MessageSize flag of the SynchronizationExtraFlag field is not set.");
                                                }

                                                if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Progress) == SynchronizationFlag.Progress)
                                                {
                                                    // The server include the progessTotal in the messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = true;

                                                    // The message object is normal message.
                                                    newMessageChange.FollowedFAIMessage = false;

                                                    // Because the SynchronizationExtraFlag is Progress and the SynchronizationExtraFlag only set Progress. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        1171,
                                                        @"[In progressPerMessage Element]MUST be present if and only if the progessTotal element, as specified in
                                                        section 2.2.4.3.18, was output within the same ancestor contentsSync element, as specified in section
                                                        2.2.4.3.2.");
                                                    ModelHelper.CaptureRequirement(
                                                        1383,
                                                        @"[In progressPerMessage Element] [[PtypBoolean] 0x0000000B] otherwise[if the Message object that follows is not FAI] ,[the server returns] FALSE (0x00).");
                                                }
                                                else
                                                {
                                                    // The server don't include the progessTotal in the messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = false;
                                                    ModelHelper.CaptureRequirement(
                                                        1172,
                                                        @"[In progressPerMessage Element] [ProgressPerMessage Element] MUST NOT be present if the Progress flag of the SynchronizationFlags field was not set when configuring the synchronization download operation.");
                                                }

                                                // Add new messageChange to ContentsSync.
                                                abstractFastTransferStream.AbstractContentsSync.MessageInfo = abstractFastTransferStream.AbstractContentsSync.MessageInfo.Add(newMessageChange);

                                                // Add messageId to IdsetGiven of download context.
                                                currentDownloadContext.UpdatedState.IdsetGiven = currentDownloadContext.UpdatedState.IdsetGiven.Add(tempMessage.MessageIdIndex);

                                                // Because SynchronizationFlag is Normal
                                                ModelHelper.CaptureRequirement(
                                                    2174,
                                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the Normal flag of the SynchronizationFlags flag is set, the server MUST download information about changes to normal messages, as specified in section 2.2.4.3.11.");
                                            }
                                            else if (!currentDownloadContext.UpdatedState.CnsetSeen.Contains(tempMessage.ChangeNumberIndex))
                                            {
                                                // The message change number is not in CnsetSeenFAI property.
                                                // Create a newMessageChange.
                                                AbstractMessageChangeInfo newMessageChange = new AbstractMessageChangeInfo
                                                {
                                                    // Set messageId for newMessageChange.
                                                    MessageIdIndex = tempMessage.MessageIdIndex
                                                };

                                                if ((currentDownloadContext.Sendoptions & SendOptionAlls.PartialItem) != SendOptionAlls.PartialItem)
                                                {
                                                    // The server include MessageChangeFull in messageChange.
                                                    newMessageChange.IsMessageChangeFull = true;
                                                    ModelHelper.CaptureRequirement(
                                                        1135,
                                                        @"[In messageChange Element]A server MUST use the messageChangeFull element, instead of the
                                                        messageChangePartial element, if any of the following are true:The PartialItem flag of the SendOptions
                                                        field was not set, as specified in section 2.2.3.2.1.1.");
                                                }
                                                else
                                                {
                                                    messagechangePartail = false;

                                                    // The server include MessageChangePartial in messageChange.
                                                    newMessageChange.IsMessageChangeFull = false;
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.CN) == SynchronizationExtraFlag.CN)
                                                {
                                                    // The server include the PidTagChangeNumber property in the messageChange.
                                                    newMessageChange.IsPidTagChangeNumberExist = true;

                                                    // Because the SynchronizationExtraFlag is CN and the SynchronizationExtraFlag only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2196,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagChangeNumber property (section 2.2.1.2.3) in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    // The server don't include the PidTagChangeNumber property in the messageChange.
                                                    newMessageChange.IsPidTagChangeNumberExist = false;

                                                    // Because the SynchronizationExtraFlag is not  CN and the SynchronizationExtraFlag not only set CN. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2197,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST NOT include the PidTagChangeNumber property in the message change header if and only if the CN flag of the SynchronizationExtraFlags field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.Eid) == SynchronizationExtraFlag.Eid)
                                                {
                                                    // The server include the PidTagMid property in messageChange.
                                                    newMessageChange.IsPidTagMidExist = true;

                                                    // Because the SynchronizationExtraFlag is EID and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2191,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagFolderId property (section 2.2.1.2.2) in a folder change header if and only if the Eid flag of the SynchronizationExtraFlags field flag is set.");

                                                    ModelHelper.CaptureRequirement(
                                                      2761,
                                                      @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMid property (section 2.2.1.2.1) in a message change header if and only if the Eid flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    // The server don't include the PidTagMid property in messageChange.
                                                    newMessageChange.IsPidTagMidExist = false;

                                                    // Because the SynchronizationExtraFlag is Eid and the SynchronizationExtraFlag only set Eid. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        716002,
                                                        @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is Eid, the value is 0x00000001] The server does not include the PidTagMid (section 2.2.1.2.1) property in the message change header when the Eid flag of the SynchronizationExtraFlag field is not set.");
                                                }

                                                if ((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.MessageSize) == SynchronizationExtraFlag.MessageSize)
                                                {
                                                    // Because the SynchronizationExtraFlag is MessageSize and the SynchronizationExtraFlag only set MessageSize. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        2195,
                                                        @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] The server MUST include the PidTagMessageSize property (section 2.2.1.6) in the message change header if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");

                                                    // The server include the PidTagMessageSize property in messageChange.
                                                    newMessageChange.IsPidTagMessageSizeExist = true;
                                                    ModelHelper.CaptureRequirement(
                                                        1365,
                                                        @"[In messageChangeHeader Element] [PidTagMessageSize,Conditional] PidTagMessageSize MUST be present if and only if the MessageSize flag of the SynchronizationExtraFlags field is set.");
                                                }
                                                else
                                                {
                                                    newMessageChange.IsPidTagMessageSizeExist = false;
                                                    ModelHelper.CaptureRequirement(
                                                       718001,
                                                       @"[In RopSynchronizationConfigure ROP Request Buffer] [SynchronizationExtraFlags, When the flag name is MessageSize, the value is 0x00000002] The server does not include the PidTagMessageSize property (section 2.2.1.6) in the message change header if the MessageSize flag of the SynchronizationExtraFlag field is not set.");
                                                }

                                                if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Progress) == SynchronizationFlag.Progress)
                                                {
                                                    // The server include ProgressPerMessage in messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = true;

                                                    // The message object is a normal message.
                                                    newMessageChange.FollowedFAIMessage = false;

                                                    // Because the SynchronizationExtraFlag is MessageSize and the SynchronizationExtraFlag only set MessageSize. So can cover requirement here.
                                                    ModelHelper.CaptureRequirement(
                                                        1171,
                                                        @"[In progressPerMessage Element]MUST be present if and only if the progessTotal element, as specified in
                                                        section 2.2.4.3.18, was output within the same ancestor contentsSync element, as specified in section
                                                        2.2.4.3.2.");
                                                    ModelHelper.CaptureRequirement(
                                                        1383,
                                                        @"[In progressPerMessage Element] [[PtypBoolean] 0x0000000B] otherwise[if the Message object that follows is not FAI] ,[the server returns] FALSE (0x00).");
                                                }
                                                else
                                                {
                                                    // The server don't include ProgressPerMessage in messageChange.
                                                    newMessageChange.IsProgressPerMessagePresent = false;
                                                    ModelHelper.CaptureRequirement(
                                                        1172,
                                                        @"[In progressPerMessage Element] [ProgressPerMessage Element] MUST NOT be present if the Progress flag of the SynchronizationFlags field was not set when configuring the synchronization download operation.");
                                                }

                                                // Add new messageChange to ContentsSync.
                                                abstractFastTransferStream.AbstractContentsSync.MessageInfo = abstractFastTransferStream.AbstractContentsSync.MessageInfo.Add(newMessageChange);

                                                // Because the MessageChange.followedFAIMessage default expect value is false and it is a normal messages.
                                                ModelHelper.CaptureRequirement(
                                                    2174,
                                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the Normal flag of the SynchronizationFlags flag is set, the server MUST download information about changes to normal messages, as specified in section 2.2.4.3.11.");
                                            }
                                        }
                                        else
                                        {
                                            // Because the MessageChange.followedFAIMessage default expect value is false and it is a normal messages.
                                            ModelHelper.CaptureRequirement(
                                                2175,
                                                @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the Normal flag of the SynchronizationFlags field is not set, the server MUST NOT download information about changes to normal messages, as specified in section 2.2.4.3.11.");
                                        }
                                    }
                                }
                            }
                            #endregion
                            if (((currentDownloadContext.SynchronizationExtraflag & SynchronizationExtraFlag.OrderByDeliveryTime) == SynchronizationExtraFlag.OrderByDeliveryTime) && abstractFastTransferStream.AbstractContentsSync.MessageInfo.Count >= 2)
                            {
                                // The server MUST sort messages by the value of their PidTagMessageDeliveryTime property when generating a sequence of messageChange.
                                abstractFastTransferStream.AbstractContentsSync.IsSortByMessageDeliveryTime = true;
                                ModelHelper.CaptureRequirement(
                                    2198,
                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] If the OrderByDeliveryTime flag of the SynchronizationExtraFlags field is set, the server MUST sort messages by the value of their PidTagMessageDeliveryTime property ([MS-OXOMSG] section 2.2.3.9) when generating a sequence of messageChange elements for the FastTransfer stream, as specified in section 2.2.4.2.");

                                // The server MUST sort messages by the value of their PidTagLastModificationTime property when generating a sequence of messageChange.
                                abstractFastTransferStream.AbstractContentsSync.IsSortByLastModificationTime = true;
                                ModelHelper.CaptureRequirement(
                                    2199,
                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationExtraFlags Constraints] If the OrderByDeliveryTime flag of the SynchronizationExtraFlags field is set, the server MUST sort messages by the PidTagLastModificationTime property ([MS-OXPROPS] section 2.753) if the former[PidTagMessageDeliveryTime] is missing, when generating a sequence of messageChange elements for the FastTransfer stream, as specified in section 2.2.4.2.");
                            }

                            // Search the message in MessageContainer.
                            foreach (AbstractMessage tempMessage in currentConnection.MessageContainer)
                            {
                                if (tempMessage.FolderIdIndex == currentFolder.FolderIdIndex)
                                {
                                    // Identify whether the readStateChange is or not included in messageContent.
                                    if (!currentDownloadContext.UpdatedState.CnsetRead.Contains(tempMessage.ReadStateChangeNumberIndex))
                                    {
                                        if (tempMessage.ReadStateChangeNumberIndex != 0)
                                        {
                                            if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.ReadState) != SynchronizationFlag.ReadState)
                                            {
                                                // Download information about changes to the read state of messages.
                                                abstractFastTransferStream.AbstractContentsSync.IsReadStateChangesExist = false;
                                                ModelHelper.CaptureRequirement(
                                                    2171,
                                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the ReadState flag of the SynchronizationFlags field is not set, the server MUST NOT download information about changes to the read state of messages, as specified in section 2.2.4.3.22.");

                                                // Download information about changes to the read state of messages.
                                                if (requirementContainer.ContainsKey(1193) && requirementContainer[1193])
                                                {
                                                    abstractFastTransferStream.AbstractContentsSync.IsReadStateChangesExist = false;
                                                    ModelHelper.CaptureRequirement(
                                                        1193,
    @"[In readStateChanges Element] Implementation does not present this element if the ReadState flag of the SynchronizationFlag field was not set when configuring the synchronization download operation. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                                }
                                            }

                                            if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.ReadState) == SynchronizationFlag.ReadState)
                                            {
                                                if (requirementContainer.Keys.Contains(2665) && requirementContainer[2665])
                                                {
                                                    // Assign a new changeNumber for CnsetReadProperty.
                                                    abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetReadPropertyChangeNumber = true;

                                                    // Because identify the read state of a message changes by(currentMessage.IsRead != IReadstatus) and get new change number. So can cover this requirement here. 
                                                    ModelHelper.CaptureRequirement(2665, "[In Tracking Read State Changes] Implementation does assign a new value to the separate change number(the read state change number) on the message, whenever the read state of a message changes on the server. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                                }

                                                abstractFastTransferStream.AbstractContentsSync.IsReadStateChangesExist = true;

                                                // Assign a new changeNumber for CnsetReadProperty.
                                                abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetReadPropertyChangeNumber = true;

                                                ModelHelper.CaptureRequirement(
                                                    2087,
                                                    "[In Tracking Read State Changes] An IDSET structure of change numbers associated with message read state transitions, either from read to unread, or unread to read (as determined by the PidTagMessageFlags property in [MS-OXCMSG] section 2.2.1.6) are included in the MetaTagCnsetRead property (section 2.2.1.1.4), which is part of the ICS state and is never directly set on any objects.");

                                                ModelHelper.CaptureRequirement(
                                                    3315,
                                                    "[In readStateChanges Element] This element MUST be present if there are changes to the read state of messages.");
                                            }
                                        }

                                        if (tempMessage.ReadStateChangeNumberIndex == 0)
                                        {
                                            if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.ReadState) == SynchronizationFlag.ReadState)
                                            {
                                                // Download information about changes to the read state of messages.
                                                abstractFastTransferStream.AbstractContentsSync.IsReadStateChangesExist = false;

                                                // Assign a new changeNumber for CnsetReadProperty.
                                                abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetReadPropertyChangeNumber = true;
                                                ModelHelper.CaptureRequirement(
                                                    2170,
                                                    @"[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] If the ReadState flag of the SynchronizationFlags field is set, the server MUST also download information about changes to the read state of messages, as specified in section 2.2.4.3.22.");

                                                ModelHelper.CaptureRequirement(
                                                    2048,
                                                    @"[In Determining What Differences To Download] [For every object in the synchronization scope, servers MUST do the following:] If the ReadState flag of the SynchronizationFlags field is set, include the readStateChanges element, as specified in section 2.2.4.3.22, for messages that: 
	Do not have their change numbers for read and unread state in the MetaTagCnsetRead property (section 2.2.1.1.4)
	And are not FAI messages and have not had change information downloaded for them in this session.");
                                            }
                                        }
                                    }

                                    // The message change number is not in CnsetSeenFAI property.
                                    if (!currentDownloadContext.UpdatedState.CnsetSeenFAI.Contains(tempMessage.ChangeNumberIndex))
                                    {
                                        // The message is FAI message.
                                        if (tempMessage.IsFAImessage)
                                        {
                                            if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.FAI) == SynchronizationFlag.FAI)
                                            {
                                                ModelHelper.CaptureRequirement(
                                                    2044,
                                                        @"[In Determining What Differences To Download] [For every object in the synchronization scope, servers MUST do the following:] [Include the following syntactical elements in the FastTransfer stream of the OutputServerObject field of the FastTransfer download ROPs, as specified in section 2.2.3.1.1, if one of the following applies:] 
	                                                Include the messageChangeFull element, as specified in section 2.2.4.3.13, if the object specified by the InputServerObject field is an FAI message, meaning the PidTagAssociated property (section 2.2.1.5) is set to TRUE
                                                    And the FAI flag of the SynchronizationFlag field was set
                                                    And the change number is not included in the value of the MetaTagCnsetSeenFAI property (section 2.2.1.1.3).");

                                                // Add message changeNumber to CnsetSeenFAI of current download context.
                                                currentDownloadContext.UpdatedState.CnsetSeenFAI = currentDownloadContext.UpdatedState.CnsetSeenFAI.Add(tempMessage.ChangeNumberIndex);

                                                if (priorUploadOperation == MS_OXCFXICS.PriorOperation.RopSynchronizationImportMessageMove)
                                                {
                                                    // Assign a new changeNumber.
                                                    abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetSeenFAIPropertyChangeNumber = true;
                                                    ModelHelper.CaptureRequirement(
                                                        2247,
                                                        @"[In Receiving a RopSynchronizationImportMessageMove Request] Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated to include change numbers of messages in the destination folder in or MetaTagCnsetSeenFAI (section 2.2.1.1.3) property, when the message is an FAI message.");
                                                }

                                                // Assign a new changeNumber.
                                                abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetSeenFAIPropertyChangeNumber = true;

                                                if (requirementContainer.ContainsKey(218300301) && requirementContainer[218300301])
                                                {
                                                    abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetSeenFAIPropertyChangeNumber = false;
                                                }

                                                // Because this ROP is called after successful import of a new or changed object using ICS upload and the server represent the imported version in the MetaTagCnsetSeen property for FAI message, this requirement is captured.
                                                ModelHelper.CaptureRequirement(
                                                    190701,
                                                    @"[In Identifying Objects and Maintaining Change Numbers] Upon successful import of a new or changed object using ICS upload, the server MUST do the following when receiving RopSaveChangesMessage ROP: This is necessary because the server MUST be able to represent the imported version in the MetaTagCnsetSeenFAI (section 2.2.1.1.3) property for FAI message.");
                                            }
                                        }
                                        else
                                        {
                                            // SynchronizationFlag  is Normal of current Download Context.
                                            if ((currentDownloadContext.Synchronizationflag & SynchronizationFlag.Normal) == SynchronizationFlag.Normal)
                                            {
                                                if (!currentDownloadContext.UpdatedState.CnsetSeen.Contains(tempMessage.ChangeNumberIndex))
                                                {
                                                    // Add  Message changeNumber to CnsetSeen.
                                                    currentDownloadContext.UpdatedState.CnsetSeen = currentDownloadContext.UpdatedState.CnsetSeen.Add(tempMessage.ChangeNumberIndex);
                                                    ModelHelper.CaptureRequirement(
                                                        2043,
                                                            @"[In Determining What Differences To Download] [For every object in the synchronization scope, servers MUST do the following:] [Include the following syntactical elements in the FastTransfer stream of the OutputServerObject field of the FastTransfer download ROPs, as specified in section 2.2.3.1.1, if one of the following applies:] 
	Include the messageChange element, as specified in section 2.2.4.3.11, if the object specified by the InputServerObject field is a normal message
	And the Normal flag of the SynchronizationFlags field was set, as specified in section 2.2.3.2.1.1.1; 	And the change number is not included in the value of the MetaTagCnsetSeen property.");
                                                }
                                                else if (abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetReadPropertyChangeNumber)
                                                {
                                                    if (requirementContainer.ContainsKey(2666) && requirementContainer[2666])
                                                    {
                                                        abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = false;
                                                        ModelHelper.CaptureRequirement(
                                                            2666,
                                                            @"[In Tracking Read State Changes] Implementation does not modify the change number of the message unless other changes to a message were made at the same time. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                                    }
                                                }

                                                // Assign a new changeNumber.
                                                abstractFastTransferStream.AbstractContentsSync.FinalICSState.IsNewCnsetSeenPropertyChangeNumber = true;
                                                ModelHelper.CaptureRequirement(
                                                    2246,
                                                    @"[In Receiving a RopSynchronizationImportMessageMove Request]Upon successful completion of this ROP, the ICS 
                                                    state on the synchronization context MUST be updated to include change numbers of messages in the destination 
                                                    folder in the MetaTagCnsetSeen (section 2.2.1.1.2)  when the message is a normal message.");

                                                // Because this ROP is called after successful import of a new or changed object using ICS upload and the server represent the imported version in the MetaTagCnsetSeen property for normal message, this requirement is captured.
                                                ModelHelper.CaptureRequirement(
                                                    1907,
                                                    @"[In Identifying Objects and Maintaining Change Numbers] Upon successful import of a new or changed object using ICS upload, the server MUST do the following when receiving RopSaveChangesMessage ROP: This is necessary because the server MUST be able to represent the imported version in the MetaTagCnsetSeen (section 2.2.1.1.2) property for normal message.");
                                            }
                                        }
                                    }
                                }
                            }

                            // Set ContentsSync IdSetGiven value with IdsetGiven value of current download context.
                            abstractFastTransferStream.AbstractContentsSync.FinalICSState.IdSetGiven = currentDownloadContext.UpdatedState.IdsetGiven;

                            // Add ICS State to ICSStateContainer.
                            currentFolder.ICSStateContainer.Add(abstractFastTransferStream.AbstractContentsSync.FinalICSState.AbstractICSStateIndex, currentDownloadContext.UpdatedState);

                            // Update the FolderContainer.
                            currentConnection.FolderContainer = currentConnection.FolderContainer.Update(currentFolderIndex, currentFolder);
                            connections[serverId] = currentConnection;

                            break;
                        }

                    // In case of the FastTransferStreamType of download context include folderContent.
                    case FastTransferStreamType.folderContent:
                        {
                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyTo
                                && currentDownloadContext.ObjectType == ObjectType.Folder)
                            {
                                ModelHelper.CaptureRequirement(
                                    3324,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyTo, ROP request buffer field conditions is The InputServerObject field is a Folder object<22>, Root element in the produced FastTransfer stream is folderContent.");
                            }

                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyProperties && currentDownloadContext.ObjectType == ObjectType.Folder)
                            {
                                ModelHelper.CaptureRequirement(
                                    3325,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyProperties, ROP request buffer field conditions is The InputServerObject field is a Folder object<22>, Root element in the produced FastTransfer stream is folderContent.");
                            }

                            if (priorOperation == PriorOperation.RopFastTransferDestinationConfigure && currentDownloadContext.ObjectType == ObjectType.Folder && sourOperation == SourceOperation.CopyProperties)
                            {
                                ModelHelper.CaptureRequirement(
                                    598,
                                    @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyProperties, if the value of InputServerObject field is a Folder Object, Root element in FastTransfer stream is folderContent element.");
                            }

                            if (priorOperation == PriorOperation.RopFastTransferDestinationConfigure && currentDownloadContext.ObjectType == ObjectType.Folder && sourOperation == SourceOperation.CopyTo)
                            {
                                ModelHelper.CaptureRequirement(
                                    595,
                                    @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyTo, if the value of the InputServerObject field is a Folder Object, Root element in FastTransfer stream is folderContent element.");
                            }

                            // Initialize the entity variable
                            abstractFastTransferStream.AbstractFolderContent = new AbstractFolderContent
                            {
                                AbsFolderMessage = new AbstractFolderMessage()
                            };

                            bool isSubFolderExist = false;
                            AbstractFolder subFolder = new AbstractFolder();

                            // Search the folder container to find if the download folder contains subFolder
                            foreach (AbstractFolder tempSubFolder in currentConnection.FolderContainer)
                            {
                                if (currentFolder.SubFolderIds.Contains(tempSubFolder.FolderIdIndex))
                                {
                                    isSubFolderExist = true;
                                    subFolder = tempSubFolder;
                                    break;
                                }
                            }

                            // The downLaod folder's subFolder exist
                            if (isSubFolderExist)
                            {
                                if (subFolder.FolderPermission == PermissionLevels.None && (currentDownloadContext.CopyToCopyFlag == CopyToCopyFlags.Move || currentDownloadContext.CopyPropertiesCopyFlag == CopyPropertiesCopyFlags.Move))
                                {
                                    abstractFastTransferStream.AbstractFolderContent.IsNoPermissionObjNotOut = true;
                                    if (requirementContainer.ContainsKey(2667) && requirementContainer[2667])
                                    {
                                        ModelHelper.CaptureRequirement(2667, @"[In Receiving a RopFastTransferSourceCopyTo ROP Request] Implementation does not output any objects in a FastTransfer stream that the client does not have permissions to delete, if the Move flag of the CopyFlags field is set. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                    }

                                    if (requirementContainer.ContainsKey(2669) && requirementContainer[2669])
                                    {
                                        ModelHelper.CaptureRequirement(
                                            2669,
                                            @"[In Receiving a RopFastTransferSourceCopyProperties Request] Implementation does not output any objects in a FastTransfer stream that the client does not have permissions to delete, if the Move flag of the CopyFlags field is specified for a download operation. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                    }
                                }
                            }
                            else if (subFolder.FolderPermission == PermissionLevels.FolderVisible && currentDownloadContext.CopyToCopyFlag == CopyToCopyFlags.Move)
                            {
                                if (requirementContainer.ContainsKey(118201) && requirementContainer[118201])
                                {
                                    abstractFastTransferStream.AbstractFolderContent.IsPidTagEcWarningOut = true;
                                } 

abstractFastTransferStream.AbstractFolderContent.AbsFolderMessage.MessageList.AbsMessage.AbsMessageContent.IsNoPermissionMessageNotOut = true;
                            }

                            // Search the currentDownloadContext.property to find if the specific property is required download
                            foreach (string propStr in currentDownloadContext.Property)
                            {
                                if (isSubFolderExist && subFolder.FolderPermission != PermissionLevels.None)
                                {
                                    // PidTagContainerHierarchy property is required to download
                                    if (propStr == "PidTagContainerHierarchy")
                                    {
                                        // CopyFolder operation will copy subFolder IFF CopySubfolders copyFlag is set
                                        if (((currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyFolder
                                            && currentDownloadContext.CopyFolderCopyFlag == CopyFolderCopyFlags.CopySubfolders) ||
                                            currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyProperties)
                                            && currentConnection.LogonFolderType != LogonFlags.Ghosted)
                                        {
                                            if (currentConnection.LogonFolderType != LogonFlags.Ghosted || (requirementContainer.ContainsKey(1113) && requirementContainer[1113] && currentConnection.LogonFolderType == LogonFlags.Ghosted))
                                            {
                                                abstractFastTransferStream.AbstractFolderContent.IsSubFolderPrecededByPidTagFXDelProp = true;
                                                ModelHelper.CaptureRequirement(
                                                    1113,
                                                    @"[In folderContent Element] Under conditions specified in section 3.2.5.10, the PidTagContainerHierarchy property ([MS-OXPROPS] section 2.636) included in a subFolder element MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1).");
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                                        {
                                            if (currentConnection.LogonFolderType != LogonFlags.Ghosted || (requirementContainer.ContainsKey(1113) && requirementContainer[1113] && currentConnection.LogonFolderType == LogonFlags.Ghosted))
                                            {
                                                // The FastTransferOperation is FastTransferSourceCopyTo and the properties that not required in the propertyTag is download
                                                abstractFastTransferStream.AbstractFolderContent.IsSubFolderPrecededByPidTagFXDelProp = true;
                                                ModelHelper.CaptureRequirement(
                                                    1113,
                                                     @"[In folderContent Element] Under conditions specified in section 3.2.5.10, the PidTagContainerHierarchy property ([MS-OXPROPS] section 2.636) included in a subFolder element MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1).");
                                            }
                                        }
                                    }
                                }

                                if (currentConnection.LogonFolderType != LogonFlags.Ghosted)
                                {
                                    // PidTagFolderAssociatedContents property is required to download
                                    if (propStr == "PidTagFolderAssociatedContents")
                                    {
                                        if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyProperties)
                                        {
                                            // The FastTransferOperation is FastTransferSourceCopyProperties and the properties that required in the propertyTag is download
                                            abstractFastTransferStream.AbstractFolderContent.AbsFolderMessage.IsFolderMessagesPrecededByPidTagFXDelProp = true;
                                            ModelHelper.CaptureRequirement(
                                                2620,
                                                @"[In folderMessages Element] Under conditions specified in section 3.2.5.10, when included in the folderMessages element, the PidTagFolderAssociatedContents ([MS-OXPROPS] section 2.690) and PidTagContainerContents ([MS-OXPROPS] section 2.634) properties MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1).");
                                        }
                                    }
                                    else
                                    {
                                        if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                                        {
                                            // The FastTransferOperation is FastTransferSourceCopyTo and the properties that not required in the propertyTag is download
                                            abstractFastTransferStream.AbstractFolderContent.AbsFolderMessage.IsFolderMessagesPrecededByPidTagFXDelProp = true;
                                            ModelHelper.CaptureRequirement(
                                                2620,
                                                @"[In folderMessages Element] Under conditions specified in section 3.2.5.10, when included in the folderMessages element, the PidTagFolderAssociatedContents ([MS-OXPROPS] section 2.690) and PidTagContainerContents ([MS-OXPROPS] section 2.634) properties MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1).");
                                        }
                                    }

                                    // PidTagContainerContents property is required to download
                                    if (propStr == "PidTagContainerContents")
                                    {
                                        if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyProperties)
                                        {
                                            // The FastTransferOperation is FastTransferSourceCopyProperties and the properties that required in the propertyTag is download
                                            abstractFastTransferStream.AbstractFolderContent.AbsFolderMessage.IsFolderMessagesPrecededByPidTagFXDelProp = true;
                                        }
                                    }
                                    else
                                    {
                                        if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                                        {
                                            // The FastTransferOperation is FastTransferSourceCopyTo and the properties that not required in the propertyTag is download
                                            abstractFastTransferStream.AbstractFolderContent.AbsFolderMessage.IsFolderMessagesPrecededByPidTagFXDelProp = true;
                                        }
                                    }
                                }
                            }

                            break;
                        }

                    // In case of the FastTransferStreamType of download context include messageContent.
                    case FastTransferStreamType.MessageContent:
                        {
                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyTo && currentDownloadContext.ObjectType == ObjectType.Message)
                            {
                                ModelHelper.CaptureRequirement(
                                    3326,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyTo, ROP request buffer field conditions is The InputServerObject field is a Message object, Root element in the produced FastTransfer stream is messageContent.");
                            }

                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyProperties && currentDownloadContext.ObjectType == ObjectType.Message)
                            {
                                ModelHelper.CaptureRequirement(
                                    3327,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyProperties, ROP request buffer field conditions is The InputServerObject field is a Message object, Root element in the produced FastTransfer stream is messageContent.");
                            }

                            if (priorOperation == PriorOperation.RopFastTransferDestinationConfigure && currentDownloadContext.ObjectType == ObjectType.Message && sourOperation == SourceOperation.CopyProperties)
                            {
                                ModelHelper.CaptureRequirement(
                                    596,
                                    @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyProperties, if the value of the InputServerObject field is a Message object, Root element in FastTransfer stream is messageContent element.");
                            }

                            if (priorOperation == PriorOperation.RopFastTransferDestinationConfigure && currentDownloadContext.ObjectType == ObjectType.Message && sourOperation == SourceOperation.CopyTo)
                            {
                                ModelHelper.CaptureRequirement(
                                    599,
                                    @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyTo, if the value of the InputServerObject field is a Message object, Root element in FastTransfer stream is messageContent element.");
                            }

                            // Initialize the entity variable
                            abstractFastTransferStream.AbstractMessageContent = new AbstractMessageContent
                            {
                                AbsMessageChildren = new AbstractMessageChildren()
                            };

                            AbstractFolder messageParentFolder = new AbstractFolder();

                            // Search the MessagecCntianer to find the downLaodMessage
                            foreach (AbstractMessage cumessage in currentConnection.MessageContainer)
                            {
                                if (cumessage.MessageHandleIndex == currentDownloadContext.RelatedObjectHandleIndex)
                                {
                                    foreach (AbstractFolder cufolder in currentConnection.FolderContainer)
                                    {
                                        if (cufolder.FolderHandleIndex == cumessage.FolderHandleIndex)
                                        {
                                            messageParentFolder = cufolder;
                                            break;
                                        }
                                    }

                                    break;
                                }
                            }

                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyTo)
                            {
                                if ((currentDownloadContext.CopyToCopyFlag & CopyToCopyFlags.BestBody) == CopyToCopyFlags.BestBody)
                                {
                                    if (requirementContainer.ContainsKey(211501) && requirementContainer[211501])
                                    {
                                        abstractFastTransferStream.AbstractMessageContent.IsRTFFormat = false;
                                        ModelHelper.CaptureRequirement(211501, @"[In Receiving a RopFastTransferSourceCopyTo ROP Request] Implementation does output the message body, and the body of the Embedded Message object, in their original format, if the BestBody flag of the CopyFlags field is set. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                    }

                                    if (requirementContainer.ContainsKey(3118003) && requirementContainer[3118003])
                                    {
                                        abstractFastTransferStream.AbstractMessageContent.IsRTFFormat = false;
                                        ModelHelper.CaptureRequirement(3118003, @"[In Appendix A: Product Behavior] Implementation does support this flag [BestBody flag] [in RopFastTransferSourceCopyTo ROP]. (<3> Section 2.2.3.1.1.1.1: Microsoft Exchange Server 2007 and 2010 follow this behavior.)");
                                    }
                                }
                            }

                            #region Verify Requirements about Sendoptions
                            if ((currentDownloadContext.Sendoptions & SendOptionAlls.UseCpid) == SendOptionAlls.UseCpid && connections.Count > 1)
                            {
                                if (currentDownloadContext.Sendoptions == SendOptionAlls.UseCpid)
                                {
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicodeCodePage = true;
                                    ModelHelper.CaptureRequirement(
                                             3453,
                                             @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When UseCpid only, if the properties are stored in Unicode on the server, the server MUST return the properties using the Unicode code page (code page property type 0x84B0).");

                                    if (currentDownloadContext.RelatedFastTransferOperation != EnumFastTransferOperation.FastTransferSourceCopyProperties)
                                    {
                                        if (requirementContainer.ContainsKey(3454) && requirementContainer[3454])
                                        {
                                            abstractFastTransferStream.AbstractMessageContent.StringPropertiesInOtherCodePage = true;
                                            ModelHelper.CaptureRequirement(
                                                   3454,
                                                   @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When UseCpid only, otherwise[the properties are not stored in Unicode on the server] the server MUST send the string using the code page property type of the code page in which the property is stored on the server.");
                                        }
                                    }

                                    ModelHelper.CaptureRequirement(
                                            3452,
                                            @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When UseCpid only, String properties MUST be output using code page property types, as specified in section 2.2.4.1.1.1.");
                                }
                                else if (currentDownloadContext.Sendoptions == (SendOptionAlls.Unicode | SendOptionAlls.UseCpid))
                                {
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicodeCodePage = true;
                                    ModelHelper.CaptureRequirement(
                                             3457,
                                             @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When UseCpid and Unicode, If string properties are stored in Unicode on the server, the server MUST return the properties using the Unicode code page (code page property type 0x84B0).");

                                    if (currentDownloadContext.RelatedFastTransferOperation != EnumFastTransferOperation.FastTransferSourceCopyProperties)
                                    {
                                        if (requirementContainer.ContainsKey(3454) && requirementContainer[3454])
                                        {
                                            abstractFastTransferStream.AbstractMessageContent.StringPropertiesInOtherCodePage = true;
                                            ModelHelper.CaptureRequirement(
                                                      3780,
                                                      @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] UseCpid and Unicode: If string properties are not stored in Unicode on the server, the server MUST send the string using the code page property type of the code page in which the property is stored on the server.");
                                        }
                                    }

                                    ModelHelper.CaptureRequirement(
                                              3456,
                                              @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When UseCpid and Unicode, String properties MUST be output using code page property types, as specified in section 2.2.4.1.1.1. ");
                                }
                                else if (currentDownloadContext.Sendoptions == (SendOptionAlls.UseCpid | SendOptionAlls.ForceUnicode))
                                {
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicodeCodePage = true;
                                    ModelHelper.CaptureRequirement(
                                                3782,
                                                @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] UseCpid and ForceUnicode: String properties MUST be output using the Unicode code page (code page property type 0x84B0).");
                                }
                                else if (currentDownloadContext.Sendoptions == (SendOptionAlls.UseCpid | SendOptionAlls.ForceUnicode | SendOptionAlls.Unicode))
                                {
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicodeCodePage = true;
                                    ModelHelper.CaptureRequirement(
                                                 3459,
                                                 @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] WhenUseCpid, Unicode, and ForceUnicode, The combination of the UseCpid and Unicode flags is the ForUpload flag.
                                                String properties MUST be output using the Unicode code page (code page property type 0x84B0).");
                                }
                            }
                            else
                            {
                                if (currentDownloadContext.Sendoptions == SendOptionAlls.ForceUnicode)
                                {
                                    // The String properties is saved in the server using unicode format in this test environment ,so the string properties must out in Unicode format
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicode = true;
                                    ModelHelper.CaptureRequirement(
                                                3451,
                                                @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When ForceUnicode only, String properties MUST be output in Unicode with a property type of PtypUnicode.");
                                }
                                else if (((currentDownloadContext.Sendoptions & SendOptionAlls.Unicode) != SendOptionAlls.Unicode) && (currentDownloadContext.Sendoptions != (SendOptionAlls.ForceUnicode | SendOptionAlls.Unicode)))
                                {
                                    // String properties MUST be output in code page
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicode = false;

                                    ModelHelper.CaptureRequirement(
                                        3447,
                                        @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When none of the three flags[Unicode, ForceUnicode, and UseCpid] are set, String properties MUST be output in the code page set on the current connection with a property type of PtypString8 ([MS-OXCDATA] section 2.11.1). ");
                                }
                                else if (currentDownloadContext.Sendoptions == (SendOptionAlls.ForceUnicode | SendOptionAlls.Unicode))
                                {
                                    // String properties MUST be output in Unicode
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicode = true;

                                    ModelHelper.CaptureRequirement(
                                        3455,
                                        @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When Unicode and ForceUnicode, String properties MUST be output in Unicode with a property type of PtypUnicode.");
                                }
                                else if (currentDownloadContext.Sendoptions == SendOptionAlls.Unicode)
                                {
                                    // The string properties is saved in the server using Unicode format in this test environment ,so the string properties must out in Unicode format
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicode = true;

                                    ModelHelper.CaptureRequirement(
                                       3448,
                                       @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When Unicode only, String properties MUST be output either in Unicode with a property type of PtypUnicode ([MS-OXCDATA] section 2.11.1), or in the code page set on the current connection with a property type of PtypString8. ");

                                    ModelHelper.CaptureRequirement(
                                        3449,
                                        @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When Unicode only, if the properties are stored in Unicode on the server, the server MUST return the properties in Unicode. ");

                                    ModelHelper.CaptureRequirement(
                                        3450,
                                        @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When Unicode only, if the properties are not stored in Unicode on the server, the server MUST return the properties in the code page set on the current connection.");
                                }
                                else if (currentDownloadContext.Sendoptions == SendOptionAlls.ForceUnicode)
                                {
                                    // The string properties is saved in the server using unicode format in this test environment ,so the string properties must out in Unicode format
                                    abstractFastTransferStream.AbstractMessageContent.StringPropertiesInUnicode = true;
                                    ModelHelper.CaptureRequirement(
                                                3451,
                                                @"[In Receiving a RopFastTransferSourceCopyTo Request] [valid combinations of the Unicode, ForceUnicode, and UseCpid flags of the SendOptions field] When ForceUnicode only, String properties MUST be output in Unicode with a property type of PtypUnicode.");
                                }
                            }
                            #endregion

                            if (!currentDownloadContext.IsLevelTrue)
                            {
                                bool isPidTagMessageAttachmentsExist = false;
                                bool isPidTagMessageRecipientsExist = false;

                                // Search the currentDownloadContext.property to find if the specific property is required to download
                                foreach (string propStr in currentDownloadContext.Property)
                                {
                                    if (propStr == "PidTagMessageAttachments")
                                    {
                                        isPidTagMessageAttachmentsExist = true;
                                    }

                                    if (propStr == "PidTagMessageRecipients")
                                    {
                                        isPidTagMessageRecipientsExist = true;
                                    }

                                    // CopyTo operation's propertyTags specific the properties not to download
                                    if (currentDownloadContext.RelatedFastTransferOperation != EnumFastTransferOperation.FastTransferSourceCopyTo)
                                    {
                                        // The PidTagMessageRecipients property is required to download
                                        if (propStr == "PidTagMessageAttachments")
                                        {
                                            // The PidTagMessageAttachments property is required to download
                                            abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.AttachmentPrecededByPidTagFXDelProp = true;
                                            ModelHelper.CaptureRequirement(
                                                3304,
                                                @"[In messageChildren Element] Under the conditions specified in section 3.2.5.10 [Effect of Property and Subobject Filters on Download] , the PidTagMessageRecipients ([MS-OXPROPS] section 2.784) property included in a recipient element and the PidTagMessageAttachments ([MS-OXPROPS] section 2.774) property included in an attachment element MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1)and .");

                                            // The AttachmentPrecededByPidTagFXDelProp true means server outputs the MetaTagFXDelProp property before outputting subobjects, such as attachment.
                                            ModelHelper.CaptureRequirement(
                                                2276,
                                                @"[In Effect of Property and Subobject Filters on Download] Whenever subobject filters have an effect, servers MUST output a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1) immediately before outputting subobjects of a particular type, to differentiate between the cases where a set of subobjects (such as attachments or recipients) was filtered in, but was empty, and where it was filtered out.");

                                            ModelHelper.CaptureRequirement(
                                                3464,
                                                @"[In Receiving a RopFastTransferSourceCopyProperties Request] If the Level field is set to 0x00, the server MUST copy descendant subobjects by using the property list specified by the PropertyTags field. ");

                                            ModelHelper.CaptureRequirement(
                                                3783,
                                                @"[In Receiving a RopFastTransferSourceCopyProperties Request] Subobjects are not copied unless listed in the value of the PropertyTags field.");
                                        }

                                        if (propStr == "PidTagMessageRecipients")
                                        {
                                            // The PidTagMessageRecipients property is required to download
                                            abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.RecipientPrecededByPidTagFXDelProp = true;
                                            ModelHelper.CaptureRequirement(
                                                3304,
                                                @"[In messageChildren Element] Under the conditions specified in section 3.2.5.10 [Effect of Property and Subobject Filters on Download] , the PidTagMessageRecipients ([MS-OXPROPS] section 2.784) property included in a recipient element and the PidTagMessageAttachments ([MS-OXPROPS] section 2.774) property included in an attachment element MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1)and .");

                                            // The RecipientPrecededByPidTagFXDelProp true means server outputs the MetaTagFXDelProp property before outputting subobjects, such as recipients.
                                            ModelHelper.CaptureRequirement(
                                                2276,
                                                @"[In Effect of Property and Subobject Filters on Download] Whenever subobject filters have an effect, servers MUST output a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1) immediately before outputting subobjects of a particular type, to differentiate between the cases where a set of subobjects (such as attachments or recipients) was filtered in, but was empty, and where it was filtered out.");
                                        }
                                    }
                                    else if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                                    {
                                        if (propStr == "PidTagMessageAttachments")
                                        {
                                            // The PidTagMessageAttachments property is not required to download
                                            abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.AttachmentPrecededByPidTagFXDelProp = false;

                                            ModelHelper.CaptureRequirement(
                                                3439,
                                                @"[In Receiving a RopFastTransferSourceCopyTo ROP Request] If the Level field is set to 0x00, the server MUST copy descendant subobjects by using the property list specified by the PropertyTags field. ");

                                            ModelHelper.CaptureRequirement(
                                                3440,
                                                @"[In Receiving a RopFastTransferSourceCopyTo ROP Request] Subobjects are only copied when they are not listed in the value of the PropertyTags field. ");
                                        }

                                        if (propStr == "PidTagMessageRecipients")
                                        {
                                            // The PidTagMessageRecipients property is not required to download
                                            abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.RecipientPrecededByPidTagFXDelProp = false;
                                        }
                                    }
                                }

                                if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo && currentConnection.AttachmentContainer.Count > 0)
                                {
                                    if (!isPidTagMessageAttachmentsExist)
                                    {
                                        abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.AttachmentPrecededByPidTagFXDelProp = true;

                                        ModelHelper.CaptureRequirement(
                                            3304,
                                            @"[In messageChildren Element] Under the conditions specified in section 3.2.5.10 [Effect of Property and Subobject Filters on Download] , the PidTagMessageRecipients ([MS-OXPROPS] section 2.784) property included in a recipient element and the PidTagMessageAttachments ([MS-OXPROPS] section 2.774) property included in an attachment element MUST be preceded by a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1)and .");
                                    }
                                }

                                if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                                {
                                    if (!isPidTagMessageRecipientsExist)
                                    {
                                        abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.RecipientPrecededByPidTagFXDelProp = true;

                                        // The RecipientPrecededByPidTagFXDelProp true means server outputs the MetaTagFXDelProp property before outputting subobjects, such as recipients.
                                        ModelHelper.CaptureRequirement(
                                            2276,
                                            @"[In Effect of Property and Subobject Filters on Download] Whenever subobject filters have an effect, servers MUST output a MetaTagFXDelProp meta-property (section 2.2.4.1.5.1) immediately before outputting subobjects of a particular type, to differentiate between the cases where a set of subobjects (such as attachments or recipients) was filtered in, but was empty, and where it was filtered out.");
                                    }
                                }
                            }
                            else
                            {
                                abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.AttachmentPrecededByPidTagFXDelProp = false;
                                abstractFastTransferStream.AbstractMessageContent.AbsMessageChildren.RecipientPrecededByPidTagFXDelProp = false;

                                if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyTo)
                                {
                                    ModelHelper.CaptureRequirement(
                                        3441,
                                        @"[In Receiving a RopFastTransferSourceCopyTo ROP Request] If the Level field is set to a nonzero value, the server MUST exclude all descendant subobjects from being copied.");
                                }

                                if (currentDownloadContext.RelatedFastTransferOperation == EnumFastTransferOperation.FastTransferSourceCopyProperties)
                                {
                                    ModelHelper.CaptureRequirement(
                                        3465,
                                        @"[In Receiving a RopFastTransferSourceCopyProperties Request] If the Level field is set to a nonzero value, the server MUST exclude all descendant subobjects from being copied.");
                                }
                            }

                            break;
                        }

                    // In case of the FastTransferStreamType of download context include messageList.
                    case FastTransferStreamType.MessageList:
                        {
                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyMessage)
                            {
                                ModelHelper.CaptureRequirement(
                                    3330,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyMessages, ROP request buffer field conditions is always, Root element in the produced FastTransfer stream is messageList.");
                            }

                            if (priorOperation == MS_OXCFXICS.PriorOperation.RopFastTransferDestinationConfigure && sourOperation == SourceOperation.CopyMessages)
                            {
                                ModelHelper.CaptureRequirement(
                                           601,
                                           @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyMessages, Root element in FastTransfer stream is messageList.");
                            }

                            // Initialize the entity variable
                            abstractFastTransferStream.AbstractMessageList = new AbstractMessageList
                            {
                                AbsMessage = new AbsMessage
                                {
                                    AbsMessageContent = new AbstractMessageContent()
                                }
                            };

                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyMessage)
                            {
                                if ((currentDownloadContext.CopyMessageCopyFlag & RopFastTransferSourceCopyMessagesCopyFlags.BestBody) == RopFastTransferSourceCopyMessagesCopyFlags.BestBody)
                                {
                                    if (requirementContainer.ContainsKey(211601) && requirementContainer[211601])
                                    {
                                        abstractFastTransferStream.AbstractMessageContent.IsRTFFormat = false;
                                        ModelHelper.CaptureRequirement(211601, @"[In Receiving a RopFastTransferSourceCopyMessages ROP Request] Implementation does output the message body, and the body of the Embedded Message object, in their original format, If the BestBody flag of the CopyFlags field is set. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                    }

                                    if (requirementContainer.ContainsKey(499003) && requirementContainer[499003])
                                    {
                                        abstractFastTransferStream.AbstractMessageContent.IsRTFFormat = false;
                                        ModelHelper.CaptureRequirement(499003, @"[In Appendix A: Product Behavior] Implementation does support this flag [BestBody flag] [in RopFastTransferSourceCopyMessages ROP]. (<5> Section 2.2.3.1.1.3.1: Microsoft Exchange Server 2007 and Microsoft Exchange Server 2010 follow this behavior.)");
                                    }
                                }
                            }

                            // If the folder permission is set to None.
                            if (currentFolder.FolderPermission == PermissionLevels.None || currentFolder.FolderPermission == PermissionLevels.FolderVisible)
                            {
                                if (currentDownloadContext.CopyMessageCopyFlag == RopFastTransferSourceCopyMessagesCopyFlags.Move)
                                {
                                    if (requirementContainer.ContainsKey(2631) && requirementContainer[2631])
                                    {
                                        // The server doesn't output any objects in a FastTransfer stream that the client does not have permissions to delete
                                        abstractFastTransferStream.AbstractMessageList.AbsMessage.AbsMessageContent.IsNoPermissionMessageNotOut = true;
                                        ModelHelper.CaptureRequirement(
                                            2631,
                                            @"[In Receiving a RopFastTransferSourceCopyMessages ROP Request] Implementation does not output any objects in a FastTransfer stream that the client does not have permissions to delete, If the Move flag of the CopyFlags field is set for a download operation. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                    }
                                }

                                if (requirementContainer.ContainsKey(1168) && requirementContainer[1168])
                                {
                                    // The server doesn't have the permissions necessary to access PidTagEcWarning if the folder permission is set to None.
                                    abstractFastTransferStream.AbstractMessageList.IsPidTagEcWarningOut = true;
                                    ModelHelper.CaptureRequirement(
                                        1168,
                                        @"[In messageList Element] Implementation does output MetaTagEcWarning meta-property (section 2.2.4.1.5.2) if a client does not have the permissions necessary to access it, as specified in section 3.2.5.8.1. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                }

                                if (requirementContainer.ContainsKey(34381) && requirementContainer[34381])
                                {
                                    // The server doesn't have the permissions necessary to access PidTagEcWarning if the folder permission is set to None.
                                    abstractFastTransferStream.AbstractMessageList.IsPidTagEcWarningOut = true;
                                    ModelHelper.CaptureRequirement(
                                        34381,
                                        @"[In Download] Implementation does output the MetaTagEcWarning meta-property (section 2.2.4.1.5.2) in a FastTransfer stream 
                                        if a permission check for an object fails, wherever allowed by its syntactical structure, to signal a client about 
                                        incomplete content. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                                }
                            }

                            break;
                        }

                    // In case of the FastTransferStreamType of download context include topFolder.
                    case FastTransferStreamType.TopFolder:
                        {
                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyFolder)
                            {
                                ModelHelper.CaptureRequirement(
                                    3331,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyFolder, ROP request buffer field conditions is always, Root element in the produced FastTransfer stream is topFolder.");
                            }

                            if (priorOperation == MS_OXCFXICS.PriorOperation.RopFastTransferDestinationConfigure && sourOperation == SourceOperation.CopyFolder)
                            {
                                ModelHelper.CaptureRequirement(
                                        602,
                                        @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyFolder, Root element in FastTransfer stream is topFolder.");
                            }

                            // If the logon folder is Ghosted folder
                            if (currentConnection.LogonFolderType == LogonFlags.Ghosted && requirementContainer.ContainsKey(1111) && requirementContainer[1111])
                            {
                                // The PidTagNewFXFolder meta-property MUST be output for the Ghosted folder
                                abstractFastTransferStream.AbstractTopFolder.AbsFolderContent.IsPidTagNewFXFolderOut = true;
                                ModelHelper.CaptureRequirement(
                                    1111,
                                    @"[In folderContent Element] [If there is a valid replica (1) of the public folder on the server and the folder content 
                                    has not replicated to the server yet, the folder content is not included in the FastTransfer stream as part of the 
                                    folderContent element] Implementation does not include any data following the MetaTagNewFXFolder meta-property in 
                                    the buffer returned by the RopFastTransferSourceGetBuffer ROP (section 2.2.3.1.1.5), although additional data can 
                                    be included in the FastTransfer stream. (Microsoft Exchange Server 2007 and above follow this behavior.)");
                            }

                            // Identify whether the subFolder is existent or not.
                            bool isSubFolderExist = false;
                            AbstractFolder subFolder = new AbstractFolder();

                            // Search the folder container to find if the download folder has subFolder
                            foreach (AbstractFolder tempSubFolder in currentConnection.FolderContainer)
                            {
                                if (currentFolder.SubFolderIds.Contains(tempSubFolder.FolderIdIndex))
                                {
                                    isSubFolderExist = true;
                                    subFolder = tempSubFolder;
                                    break;
                                }
                            }

                            if (isSubFolderExist)
                            {
                                // Identify folder Permission is available.
                                if (subFolder.FolderPermission != PermissionLevels.None)
                                {
                                    if ((currentDownloadContext.CopyFolderCopyFlag & CopyFolderCopyFlags.CopySubfolders) == CopyFolderCopyFlags.CopySubfolders || (currentDownloadContext.CopyFolderCopyFlag & CopyFolderCopyFlags.Move) == CopyFolderCopyFlags.Move)
                                    {
                                        // The server recursively include the subFolders of the folder specified in the InputServerObject in the scope.
                                        abstractFastTransferStream.AbstractTopFolder.SubFolderInScope = true;
                                    }

                                    if ((currentDownloadContext.CopyFolderCopyFlag & CopyFolderCopyFlags.Move) == CopyFolderCopyFlags.Move && (currentDownloadContext.CopyFolderCopyFlag & CopyFolderCopyFlags.CopySubfolders) != CopyFolderCopyFlags.CopySubfolders)
                                    {
                                        ModelHelper.CaptureRequirement(
                                            3481,
                                            @"[In Receiving a RopFastTransferSourceCopyFolder ROP Request] If the Move flag of the CopyFlags field is set and the CopySubfolders flag is not set, the server MUST recursively include the subfolders of the folder specified in the InputServerObject field in the scope.");
                                    }
                                }
                            }

                            break;
                        }

                    // In case of the FastTransferStreamType of download context include messageList.
                    case FastTransferStreamType.attachmentContent:
                        {
                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyTo && currentDownloadContext.ObjectType == ObjectType.Attachment)
                            {
                                ModelHelper.CaptureRequirement(
                                    3328,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyTo, ROP request buffer field conditions is The InputServerObject field is an Attachment object<23>, Root element in the produced FastTransfer stream is attachmentContent.");
                            }

                            if (priorDownloadOperation == PriorDownloadOperation.RopFastTransferSourceCopyProperties && currentDownloadContext.ObjectType == ObjectType.Attachment)
                            {
                                ModelHelper.CaptureRequirement(
                                    3329,
                                    @"[In FastTransfer Streams in ROPs] When ROP that initiates an operation is RopFastTranserSourceCopyProperties, ROP request buffer field conditions is The InputServerObject field is an Attachment object<23>, Root element in the produced FastTransfer stream is attachmentContent.");
                            }

                            if (priorOperation == PriorOperation.RopFastTransferDestinationConfigure && currentConnection.AttachmentContainer.Count > 0 && sourOperation == SourceOperation.CopyTo)
                            {
                                ModelHelper.CaptureRequirement(
                                    597,
                                    @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyTo, if the value of the InputServerObject field is an Attachment object, Root element in FastTransfer stream is attachmentContent element.");
                            }

                            if (priorOperation == PriorOperation.RopFastTransferDestinationConfigure && currentDownloadContext.ObjectType == ObjectType.Attachment && sourOperation == SourceOperation.CopyProperties)
                            {
                                ModelHelper.CaptureRequirement(
                                    600,
                                    @"[In RopFastTransferDestinationConfigure ROP Request Buffer] [SourceOperation] When SourceOperation enumeration value is CopyProperties, if the value of the InputServerObject field is an Attachment object, Root element in FastTransfer stream is attachmentContent element.");
                            }

                            break;
                        }

                    default:
                        break;
                }
            }

            if (result == RopResult.Success)
            {
                // If the server returns success result, which means the RopFastTransferSourceGetBuffer ROP downloads the next portion of a FastTransfer stream successfully. Then this requirement can be captured.
                ModelHelper.CaptureRequirement(
                        532,
                        @"[In RopFastTransferSourceGetBuffer ROP] The RopFastTransferSourceGetBuffer ROP ([MS-OXCROPS] section 2.2.12.3) downloads the next portion of a FastTransfer stream that is produced by a previously configured download operation.");
            }

            return result;
        }