Beispiel #1
0
        protected override bool IsIgnorableItem(MessageRec msg)
        {
            if (base.IsIgnorableItem(msg))
            {
                return(true);
            }
            if (msg.CreationTimestamp > ((MergeJob)base.MRSJob).MailboxSnapshotTimestamp)
            {
                return(true);
            }
            if (msg.IsFAI && base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption != FAICopyOption.Copy)
            {
                MrsTracer.Service.Debug("Ignoring FAI item because FAICopyOption!=Copy", new object[0]);
                return(true);
            }
            string text;

            if (FolderContentsMapper.ShouldItemBeIgnored(msg, (base.SyncState == null) ? null : base.SyncState.BadItems, base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, out text))
            {
                return(true);
            }
            this.EnsureDumpsterContentsIsLoaded();
            if (this.targetDeletedContents.Contains(msg.EntryId))
            {
                MrsTracer.Service.Debug("Item is deleted, ignoring.", new object[0]);
                return(true);
            }
            return(false);
        }
Beispiel #2
0
        private void ApplyFolderChanges(SyncContext ctx, FolderChangesManifest folderChanges, FolderMapping fm, ISourceFolder srcFolder, IDestinationFolder destFolder)
        {
            int num  = 0;
            int num2 = 0;
            int num3 = 0;
            int num4 = 0;
            int num5 = 0;
            FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(fm, srcFolder, this.SourceHierarchy, destFolder, this.DestHierarchy, base.MRSJob.CachedRequestJob.ConflictResolutionOption ?? ConflictResolutionOption.KeepSourceItem, base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None);
            List <MessageRec>    list;

            byte[][] array;
            byte[][] array2;
            byte[][] array3;
            int      skipped;

            folderContentsMapper.ComputeIncrementalMapping(folderChanges, (base.SyncState == null) ? null : base.SyncState.BadItems, out list, out array, out array2, out array3, out skipped);
            this.CopyMessageBatch(folderContentsMapper, list, fm);
            destFolder.DeleteMessages(array);
            destFolder.SetReadFlagsOnMessages(SetReadFlags.None, array2);
            destFolder.SetReadFlagsOnMessages(SetReadFlags.ClearRead, array3);
            if (list != null)
            {
                foreach (MessageRec messageRec in list)
                {
                    if (messageRec.IsNew)
                    {
                        num++;
                    }
                    else
                    {
                        num2++;
                    }
                }
            }
            if (array != null)
            {
                num3 += array.Length;
            }
            if (array2 != null)
            {
                num4 += array2.Length;
            }
            if (array3 != null)
            {
                num5 += array3.Length;
            }
            ctx.CopyMessagesCount += new CopyMessagesCount(num, num2, num3, num4, num5, skipped);
        }
        protected virtual bool ShouldItemBeCopied(MessageRec sourceMR, MessageRec targetMR, HashSet <byte[]> duplicateTargetSecondaryKeys)
        {
            if (targetMR == null)
            {
                return(true);
            }
            if (!sourceMR.IsFAI && this.conflictResolutionOption == ConflictResolutionOption.KeepAll)
            {
                return(false);
            }
            DateTime dateTimeValue  = FolderContentsMapper.GetDateTimeValue(sourceMR, PropTag.LastModificationTime);
            DateTime dateTimeValue2 = FolderContentsMapper.GetDateTimeValue(targetMR, this.destHierarchy.SourceLastModifiedTimestampPtag);
            DateTime dateTimeValue3 = FolderContentsMapper.GetDateTimeValue(targetMR, PropTag.LastModificationTime);

            return(dateTimeValue != dateTimeValue2 && (this.conflictResolutionOption != ConflictResolutionOption.KeepLatestItem || !(dateTimeValue <= dateTimeValue3)));
        }
 private byte[] GetKeyPlusLMTHash(MessageRec mr, PropTag keyPtag, PropTag lmtPtag)
 {
     byte[] array = ((keyPtag == PropTag.EntryId) ? mr.EntryId : mr[keyPtag]) as byte[];
     if (array == null)
     {
         return(null);
     }
     if (this.conflictResolutionOption != ConflictResolutionOption.KeepAll)
     {
         return(array);
     }
     byte[] bytes  = BitConverter.GetBytes(FolderContentsMapper.GetDateTimeValue(mr, lmtPtag).ToBinary());
     byte[] array2 = new byte[array.Length + bytes.Length];
     array.CopyTo(array2, 0);
     bytes.CopyTo(array2, array.Length);
     return(array2);
 }
Beispiel #5
0
        public void MergeFolderContentsPaged(FolderMapping folder, FolderContentsCrawler sourceFolderCrawler, IDestinationFolder destFolder, TimeSpan maxOperationDuration)
        {
            MrsTracer.Service.Function("MailboxMerger.MergeFolderContentsPaged({0})", new object[]
            {
                folder.FullFolderName
            });
            ISourceFolder wrappedObject = sourceFolderCrawler.WrappedObject;

            if (this.ContentRestriction != null)
            {
                wrappedObject.SetContentsRestriction(this.ContentRestriction);
            }
            FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(folder, wrappedObject, this.SourceHierarchy, destFolder, this.DestHierarchy, this.GetConflictResolutionOption(folder), base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None);
            DateTime             utcNow = DateTime.UtcNow;
            int               alreadyCopiedCount;
            ulong             alreadyCopiedSize;
            List <MessageRec> itemsToCopy;
            List <MessageRec> list;

            while (folderContentsMapper.ComputeMappingPaged(sourceFolderCrawler, (base.SyncState == null) ? null : base.SyncState.BadItems, out alreadyCopiedCount, out alreadyCopiedSize, out itemsToCopy, out list))
            {
                SyncProtocol syncProtocol = base.MRSJob.CachedRequestJob.SyncProtocol;
                foreach (MessageRec messageRec in list)
                {
                    destFolder.SetMessageProps(messageRec.EntryId, messageRec.AdditionalProps);
                }
                base.MailboxSizeTracker.TrackFolder(folder.EntryId, sourceFolderCrawler.TotalMessageCount, alreadyCopiedCount, alreadyCopiedSize);
                base.MRSJob.MessagesWritten     += base.MailboxSizeTracker.AlreadyCopiedCount;
                base.MRSJob.MessageSizeWritten  += base.MailboxSizeTracker.AlreadyCopiedSize;
                base.MRSJob.TotalMessages        = base.MailboxSizeTracker.MessageCount;
                base.MRSJob.TotalMessageByteSize = base.MailboxSizeTracker.TotalMessageSize;
                this.CopyMessageBatch(folderContentsMapper, itemsToCopy, folder);
                DateTime utcNow2 = DateTime.UtcNow;
                if (utcNow2 - utcNow >= maxOperationDuration)
                {
                    MrsTracer.Service.Debug("MergeFolderContentsPaged times out for assigned duration {0}. Start:{1}, End:{2}", new object[]
                    {
                        maxOperationDuration,
                        utcNow,
                        utcNow2
                    });
                    return;
                }
            }
        }
        private Dictionary <string, List <MessageRec> > CreateFaiMap(IReadOnlyCollection <MessageRec> messages, EntryIdMap <BadItemMarker> badItemMarkers)
        {
            Dictionary <string, List <MessageRec> > dictionary = new Dictionary <string, List <MessageRec> >(StringComparer.OrdinalIgnoreCase);

            foreach (MessageRec messageRec in messages)
            {
                string text;
                if (messageRec.IsFAI && !FolderContentsMapper.ShouldItemBeIgnored(messageRec, badItemMarkers, this.faiCopyOption, out text) && !string.IsNullOrEmpty(text))
                {
                    List <MessageRec> list;
                    if (!dictionary.TryGetValue(text, out list))
                    {
                        list = new List <MessageRec>(1);
                        dictionary.Add(text, list);
                    }
                    list.Add(messageRec);
                }
            }
            return(dictionary);
        }
Beispiel #7
0
        public void MergeFolderContents(FolderMapping fm, ISourceFolder srcFolder, IDestinationFolder destFolder)
        {
            MrsTracer.Service.Function("MailboxMerger.MergeFolderContents({0})", new object[]
            {
                fm.FullFolderName
            });
            if (this.ContentRestriction != null)
            {
                srcFolder.SetContentsRestriction(this.ContentRestriction);
            }
            FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(fm, srcFolder, this.SourceHierarchy, destFolder, this.DestHierarchy, this.GetConflictResolutionOption(fm), base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None);
            int               num;
            ulong             num2;
            List <MessageRec> list;
            List <MessageRec> list2;

            folderContentsMapper.ComputeMapping((base.SyncState == null) ? null : base.SyncState.BadItems, out num, out num2, out list, out list2);
            SyncProtocol syncProtocol = base.MRSJob.CachedRequestJob.SyncProtocol;

            foreach (MessageRec messageRec in list2)
            {
                destFolder.SetMessageProps(messageRec.EntryId, messageRec.AdditionalProps);
            }
            base.MailboxSizeTracker.TrackFolder(fm.EntryId, list, num, num2);
            int   num3;
            ulong num4;

            base.MailboxSizeTracker.GetFolderSize(fm.EntryId, out num3, out num4);
            base.Report.Append(MrsStrings.ReportFolderMergeStats(num3 - num, new ByteQuantifiedSize(num4 - num2).ToString(), num, new ByteQuantifiedSize(num2).ToString()));
            base.MRSJob.TotalMessages        = base.MailboxSizeTracker.MessageCount;
            base.MRSJob.TotalMessageByteSize = base.MailboxSizeTracker.TotalMessageSize;
            base.MRSJob.MessagesWritten      = base.MailboxSizeTracker.AlreadyCopiedCount;
            base.MRSJob.MessageSizeWritten   = base.MailboxSizeTracker.AlreadyCopiedSize;
            this.CopyMessageBatch(folderContentsMapper, list, fm);
            base.MailboxSizeTracker.TrackFolder(fm.EntryId, null, num3, num4);
        }
Beispiel #8
0
        private void CopyMessageBatch(FolderContentsMapper mapper, List <MessageRec> itemsToCopy, FolderMapping fm)
        {
            if (itemsToCopy == null || itemsToCopy.Count == 0)
            {
                return;
            }
            MrsTracer.Service.Debug("Sorting {0} messages in folder '{1}'", new object[]
            {
                itemsToCopy.Count,
                fm.FullFolderName
            });
            MessageRecSorter           messageRecSorter = new MessageRecSorter();
            Queue <List <MessageRec> > queue            = messageRecSorter.Sort(itemsToCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? MessageRecSortBy.SkipSort : MessageRecSortBy.DescendingTimeStamp);

            byte[][] folderIDs = new byte[][]
            {
                fm.TargetFolder.EntryId
            };
            while (queue.Count > 0)
            {
                base.MRSJob.CheckServersHealth();
                List <MessageRec> list = queue.Dequeue();
                ulong             num  = 0UL;
                foreach (MessageRec messageRec in list)
                {
                    num += (ulong)((long)messageRec.MessageSize);
                }
                MrsTracer.Service.Debug("Copying a batch of {0} messages, {1}", new object[]
                {
                    list.Count,
                    new ByteQuantifiedSize(num)
                });
                List <BadMessageRec> list2 = new List <BadMessageRec>();
                MapiUtils.ExportMessagesWithBadItemDetection(base.SourceMailbox, list, delegate
                {
                    IFxProxyPool fxProxyPool        = this.DestMailbox.GetFxProxyPool(folderIDs);
                    IFxProxyPool fxProxyTransformer = mapper.GetFxProxyTransformer(fxProxyPool);
                    return(this.CreateFxProxyPoolTransmissionPipeline(fxProxyTransformer));
                }, ExportMessagesFlags.OneByOne, ((base.Flags & MailboxCopierFlags.TargetIsPST) != MailboxCopierFlags.None) ? MailboxCopierBase.PSTIncludeMessagePtags : null, null, base.MRSJob.TestIntegration, ref list2);
                if (list2 != null && list2.Count > 0)
                {
                    List <BadMessageRec> list3 = new List <BadMessageRec>();
                    foreach (BadMessageRec badMessageRec in list2)
                    {
                        if (badMessageRec.Kind == BadItemKind.MissingItem)
                        {
                            MrsTracer.Service.Warning("Message {0} is missing in source, skipping.", new object[]
                            {
                                TraceUtils.DumpEntryId(badMessageRec.EntryId)
                            });
                        }
                        else
                        {
                            list3.Add(badMessageRec);
                        }
                    }
                    this.ReportBadItems(list3);
                }
                if (base.MRSJob.TestIntegration.LogContentDetails)
                {
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.AppendLine(string.Format("CopyMessageBatch: {0} items copied", list.Count));
                    foreach (MessageRec messageRec2 in list)
                    {
                        stringBuilder.AppendLine(string.Format("ItemID {0}, FolderID {1}{2}", TraceUtils.DumpEntryId(messageRec2.EntryId), TraceUtils.DumpEntryId(messageRec2.FolderId), messageRec2.IsFAI ? ", FAI" : string.Empty));
                    }
                    base.MRSJob.Report.AppendDebug(stringBuilder.ToString());
                }
                base.MRSJob.MessagesWritten    += list.Count;
                base.MRSJob.MessageSizeWritten += num;
                base.MRSJob.ProgressTracker.AddItems((uint)list.Count);
                SaveStateFlags saveStateFlags = SaveStateFlags.Lazy;
                if (num > 0UL)
                {
                    base.UpdateTimestampWhenPersistentProgressWasMade();
                    saveStateFlags |= SaveStateFlags.RelinquishLongRunningJob;
                }
                base.MRSJob.SaveState(saveStateFlags, null);
            }
        }
        public void ComputeMapping(IReadOnlyCollection <MessageRec> sourceMessages, IReadOnlyCollection <MessageRec> targetMessages, EntryIdMap <BadItemMarker> badItemMarkers, out int skippedItemCount, out ulong skippedItemSize, out List <MessageRec> itemsToCopy, out List <MessageRec> targetMessagePropsChanges)
        {
            itemsToCopy = new List <MessageRec>(sourceMessages.Count);
            targetMessagePropsChanges = new List <MessageRec>();
            skippedItemCount          = 0;
            skippedItemSize           = 0UL;
            if (sourceMessages.Count == 0)
            {
                MrsTracer.Service.Debug("No more contents in source folder", new object[0]);
                return;
            }
            EntryIdMap <MessageRec> entryIdMap  = new EntryIdMap <MessageRec>();
            HashSet <byte[]>        hashSet     = new HashSet <byte[]>(ArrayComparer <byte> .EqualityComparer);
            EntryIdMap <MessageRec> entryIdMap2 = new EntryIdMap <MessageRec>();
            Dictionary <string, List <MessageRec> > dictionary  = null;
            Dictionary <string, List <MessageRec> > dictionary2 = null;

            if (this.faiCopyOption == FAICopyOption.MapByMessageClass)
            {
                dictionary  = this.CreateFaiMap(sourceMessages, badItemMarkers);
                dictionary2 = this.CreateFaiMap(targetMessages, badItemMarkers);
            }
            foreach (MessageRec messageRec in targetMessages)
            {
                byte[] keyPlusLMTHash = this.GetKeyPlusLMTHash(messageRec, this.destHierarchy.SourceEntryIDPtag, this.destHierarchy.SourceLastModifiedTimestampPtag);
                if (keyPlusLMTHash != null)
                {
                    entryIdMap2[keyPlusLMTHash] = messageRec;
                }
                List <byte[]> secondaryKeys = this.GetSecondaryKeys(messageRec, MessageRecType.Target);
                this.RegisterUniqueTargetSecondaryKeys(messageRec, secondaryKeys, entryIdMap, hashSet);
            }
            HashSet <byte[]> uniqueSecondaryKeys = new HashSet <byte[]>(ArrayComparer <byte> .EqualityComparer);
            HashSet <byte[]> hashSet2            = new HashSet <byte[]>(ArrayComparer <byte> .EqualityComparer);

            foreach (MessageRec message in sourceMessages)
            {
                List <byte[]> secondaryKeys2 = this.GetSecondaryKeys(message, MessageRecType.Source);
                this.IdentifyDuplicateSecondaryKeys(message, secondaryKeys2, uniqueSecondaryKeys, hashSet2);
            }
            foreach (MessageRec messageRec2 in sourceMessages)
            {
                string text;
                if (FolderContentsMapper.ShouldItemBeIgnored(messageRec2, badItemMarkers, this.faiCopyOption, out text))
                {
                    skippedItemCount++;
                    skippedItemSize += (ulong)((long)messageRec2.MessageSize);
                }
                else
                {
                    MessageRec        messageRec3 = null;
                    List <MessageRec> list;
                    List <MessageRec> list2;
                    if (this.faiCopyOption == FAICopyOption.MapByMessageClass && messageRec2.IsFAI && !string.IsNullOrEmpty(text) && dictionary.TryGetValue(text, out list) && list.Count == 1 && dictionary2.TryGetValue(text, out list2) && list2.Count == 1)
                    {
                        messageRec3 = list2[0];
                        MrsTracer.Service.Debug("Mapped FAI message with message class '{0}'", new object[]
                        {
                            text
                        });
                    }
                    if (messageRec3 == null)
                    {
                        this.MapSourceToTargetMessage(messageRec2, entryIdMap2, entryIdMap, hashSet, hashSet2, out messageRec3);
                    }
                    MessageRec item = null;
                    if (this.ShouldTargetMessagePropsBeUpdated(messageRec2, messageRec3, out item))
                    {
                        skippedItemCount++;
                        skippedItemSize += (ulong)((long)messageRec2.MessageSize);
                        targetMessagePropsChanges.Add(item);
                    }
                    else if (this.ShouldItemBeCopied(messageRec2, messageRec3, hashSet))
                    {
                        itemsToCopy.Add(messageRec2);
                        this.sourceMapping[messageRec2.EntryId] = messageRec2;
                        if (messageRec3 != null)
                        {
                            this.targetMapping[messageRec2.EntryId] = messageRec3;
                        }
                    }
                    else
                    {
                        skippedItemCount++;
                        skippedItemSize += (ulong)((long)messageRec2.MessageSize);
                    }
                }
            }
        }
 public TranslatingMessageProxy(IMessageProxy destMessage, PropValueData[] dataToSetOnSave, FolderContentsMapper mapper) : base(destMessage, mapper)
 {
     this.dataToSetOnSave = dataToSetOnSave;
 }
 public TranslatingFolderProxy(FolderContentsMapper.TranslatingProxyPool owner, IFolderProxy destFolder, FolderContentsMapper mapper) : base(destFolder, mapper)
 {
     this.owner = owner;
 }
 public TranslatingEntryProxy(IMapiFxProxyEx destProxy, FolderContentsMapper mapper) : base(destProxy, true)
 {
     this.mapper = mapper;
 }
 public TranslatingProxyPool(FolderContentsMapper mapper, IFxProxyPool destination) : base(destination, true)
 {
     this.mapper            = mapper;
     this.uploadedSourceIDs = new List <byte[]>();
 }
        public void ComputeIncrementalMapping(FolderChangesManifest folderChanges, EntryIdMap <BadItemMarker> badItemMarkers, out List <MessageRec> itemsToCopy, out byte[][] deletedTargetEntryIDs, out byte[][] readTargetEntryIDs, out byte[][] unreadTargetEntryIDs, out int skippedItemCount)
        {
            MrsTracer.Service.Function("FolderContentsMapper.ComputeIncrementalMapping", new object[0]);
            skippedItemCount      = 0;
            itemsToCopy           = null;
            deletedTargetEntryIDs = null;
            readTargetEntryIDs    = null;
            unreadTargetEntryIDs  = null;
            List <byte[]> list  = new List <byte[]>();
            List <byte[]> list2 = new List <byte[]>();
            List <byte[]> list3 = new List <byte[]>();

            if (folderChanges.ChangedMessages != null)
            {
                foreach (MessageRec messageRec in folderChanges.ChangedMessages)
                {
                    list2.Add(messageRec.EntryId);
                    if (!messageRec.IsDeleted)
                    {
                        list.Add(messageRec.EntryId);
                    }
                    else
                    {
                        list3.Add(messageRec.EntryId);
                    }
                }
            }
            if (folderChanges.ReadMessages != null)
            {
                list2.AddRange(folderChanges.ReadMessages);
            }
            if (folderChanges.UnreadMessages != null)
            {
                list2.AddRange(folderChanges.UnreadMessages);
            }
            if (list2.Count == 0)
            {
                return;
            }
            list2.Sort(ArrayComparer <byte> .Comparer);
            List <PropTag> list4 = new List <PropTag>();

            list4.Add(PropTag.SearchKey);
            list4.Add(PropTag.LastModificationTime);
            list4.Add(PropTag.MessageClass);
            List <MessageRec> list5 = null;

            if (list.Count > 0)
            {
                MrsTracer.Service.Debug("Loading changed source messages", new object[0]);
                list.Sort(ArrayComparer <byte> .Comparer);
                list5 = this.srcFolder.LookupMessages(PropTag.EntryId, list, list4.ToArray());
            }
            EntryIdMap <MessageRec> entryIdMap = new EntryIdMap <MessageRec>();

            if (this.conflictResolutionOption != ConflictResolutionOption.KeepAll)
            {
                list4.Add(this.destHierarchy.SourceEntryIDPtag);
                list4.Add(this.destHierarchy.SourceLastModifiedTimestampPtag);
                MrsTracer.Service.Debug("Looking up target messages", new object[0]);
                List <MessageRec> list6 = this.destFolder.LookupMessages(this.destHierarchy.SourceEntryIDPtag, list2, list4.ToArray());
                foreach (MessageRec messageRec2 in list6)
                {
                    byte[] array = messageRec2[this.destHierarchy.SourceEntryIDPtag] as byte[];
                    if (array != null)
                    {
                        this.targetMapping[array] = messageRec2;
                    }
                    byte[] keyPlusLMTHash = this.GetKeyPlusLMTHash(messageRec2, this.destHierarchy.SourceEntryIDPtag, this.destHierarchy.SourceLastModifiedTimestampPtag);
                    if (keyPlusLMTHash != null)
                    {
                        entryIdMap[keyPlusLMTHash] = messageRec2;
                    }
                }
            }
            if (list5 == null)
            {
                MrsTracer.Service.Debug("ChangedSourceIds {0}, SourceMessages looked up is null", new object[]
                {
                    list.Count
                });
            }
            else
            {
                if (list5.Count != list.Count)
                {
                    MrsTracer.Service.Debug("ChangedSourceIds {0}, SourceMessages looked up {1}", new object[]
                    {
                        list.Count,
                        list5.Count
                    });
                }
                itemsToCopy = new List <MessageRec>();
                foreach (MessageRec messageRec3 in list5)
                {
                    string text;
                    if (FolderContentsMapper.ShouldItemBeIgnored(messageRec3, badItemMarkers, this.faiCopyOption, out text))
                    {
                        skippedItemCount++;
                    }
                    else
                    {
                        MessageRec messageRec4 = null;
                        this.MapSourceToTargetMessageBySourceEntryId(messageRec3, entryIdMap, out messageRec4);
                        if (!this.ShouldItemBeCopied(messageRec3, messageRec4, null))
                        {
                            skippedItemCount++;
                        }
                        else
                        {
                            if (messageRec4 == null)
                            {
                                messageRec3.Flags |= MsgRecFlags.New;
                            }
                            itemsToCopy.Add(messageRec3);
                            this.sourceMapping[messageRec3.EntryId] = messageRec3;
                        }
                    }
                }
            }
            if (list3.Count > 0)
            {
                deletedTargetEntryIDs = this.RemapSourceIDsToTargetIDs(list3);
            }
            if (folderChanges.ReadMessages != null && folderChanges.ReadMessages.Count > 0)
            {
                readTargetEntryIDs = this.RemapSourceIDsToTargetIDs(folderChanges.ReadMessages);
            }
            if (folderChanges.UnreadMessages != null && folderChanges.UnreadMessages.Count > 0)
            {
                unreadTargetEntryIDs = this.RemapSourceIDsToTargetIDs(folderChanges.UnreadMessages);
            }
        }