The ContentsSync element contains the result of the contents synchronization download operation. contentsSync = [progressTotal] *( [ProgressPerMessage] messageChange ) [deletions] [readStateChanges] state IncrSyncEnd
Inheritance: SyntacticalBase
        /// <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 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;
        }