Beispiel #1
0
 private void ProcessSyncStateFolders(Folder deviceFolder, ISyncLogger syncLogger)
 {
     using (QueryResult queryResult = deviceFolder.FolderQuery(FolderQueryFlags.None, null, null, DeviceSyncStateMetadata.NullSyncPropertiesFolders))
     {
         for (;;)
         {
             IStorePropertyBag[] propertyBags = queryResult.GetPropertyBags(100);
             if (propertyBags == null || propertyBags.Length == 0)
             {
                 break;
             }
             foreach (IStorePropertyBag propertyBag in propertyBags)
             {
                 SyncStateMetadata metadataFromPropertyBag = this.GetMetadataFromPropertyBag(deviceFolder.Session as MailboxSession, propertyBag, syncLogger);
                 if (metadataFromPropertyBag != null)
                 {
                     syncLogger.TraceDebug <SyncStateMetadata>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.ProcessSyncStateFolders] Found SyncState: {0}", metadataFromPropertyBag);
                     this.syncStateMap.TryAdd(metadataFromPropertyBag.Name, metadataFromPropertyBag);
                 }
                 else
                 {
                     syncLogger.TraceDebug <DeviceIdentity>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.ProcessSyncStateFolders] Discovered unusable sync state for device {0}", this.Id);
                 }
             }
         }
     }
 }
Beispiel #2
0
 private void ProcessSyncStateItems(Folder deviceFolder, ISyncLogger syncLogger)
 {
     using (QueryResult queryResult = deviceFolder.ItemQuery(ItemQueryType.None, null, null, DeviceSyncStateMetadata.NullSyncPropertiesItems))
     {
         for (;;)
         {
             IStorePropertyBag[] propertyBags = queryResult.GetPropertyBags(100);
             if (propertyBags == null || propertyBags.Length == 0)
             {
                 break;
             }
             foreach (IStorePropertyBag storePropertyBag in propertyBags)
             {
                 string            displayName             = (string)storePropertyBag.TryGetProperty(ItemSchema.Subject);
                 SyncStateMetadata metadataFromPropertyBag = this.GetMetadataFromPropertyBag(storePropertyBag, displayName, syncLogger);
                 if (metadataFromPropertyBag != null)
                 {
                     StoreObjectId objectId = ((VersionedId)storePropertyBag.TryGetProperty(ItemSchema.Id)).ObjectId;
                     metadataFromPropertyBag.FolderSyncStateId = null;
                     metadataFromPropertyBag.ItemSyncStateId   = objectId;
                     syncLogger.TraceDebug <SyncStateMetadata>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.ProcessSyncStateItems] Found Item SyncState: {0}", metadataFromPropertyBag);
                     this.syncStateMap.TryAdd(metadataFromPropertyBag.Name, metadataFromPropertyBag);
                 }
                 else
                 {
                     syncLogger.TraceDebug <DeviceIdentity>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.ProcessSyncStateItems] Discovered unusable sync state for device {0}", this.Id);
                 }
             }
         }
     }
 }
Beispiel #3
0
 private SyncStateMetadata GetSyncStateItemMetadata(MailboxSession mailboxSession, Folder parentFolder, string displayName, ISyncLogger syncLogger = null)
 {
     if (syncLogger == null)
     {
         syncLogger = TracingLogger.Singleton;
     }
     using (QueryResult queryResult = parentFolder.ItemQuery(ItemQueryType.None, null, new SortBy[]
     {
         new SortBy(ItemSchema.Subject, SortOrder.Ascending)
     }, DeviceSyncStateMetadata.NullSyncPropertiesItems))
     {
         if (queryResult.SeekToCondition(SeekReference.OriginBeginning, new ComparisonFilter(ComparisonOperator.Equal, ItemSchema.Subject, displayName)))
         {
             IStorePropertyBag storePropertyBag = queryResult.GetPropertyBags(1)[0];
             StoreObjectId     objectId         = ((VersionedId)storePropertyBag.TryGetProperty(ItemSchema.Id)).ObjectId;
             syncLogger.TraceDebug <string, SmtpAddress, string>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncStateItemMetadata] Sync state '{0}' for mailbox '{1}' is stored on item id '{2}'", displayName, mailboxSession.MailboxOwner.MailboxInfo.PrimarySmtpAddress, objectId.ToBase64String());
             SyncStateMetadata metadataFromPropertyBag = this.GetMetadataFromPropertyBag(storePropertyBag, displayName, syncLogger);
             metadataFromPropertyBag.FolderSyncStateId = parentFolder.Id.ObjectId;
             metadataFromPropertyBag.ItemSyncStateId   = objectId;
             return(metadataFromPropertyBag);
         }
     }
     syncLogger.TraceDebug <string>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncStateItemMetadata] Did not find child item with name {0}", displayName);
     return(null);
 }
        private static FolderSyncStateMetadata GetFolderSyncStateMetadata(SyncStateStorage syncStateStorage, MailboxSession mailboxSession, string name, ISyncLogger syncLogger = null)
        {
            if (syncLogger == null)
            {
                syncLogger = TracingLogger.Singleton;
            }
            SyncStateMetadata       syncState = syncStateStorage.DeviceMetadata.GetSyncState(mailboxSession, name, syncLogger);
            FolderSyncStateMetadata folderSyncStateMetadata = syncState as FolderSyncStateMetadata;

            if (folderSyncStateMetadata == null)
            {
                syncLogger.TraceDebug <SmtpAddress, string>(ExTraceGlobals.SyncProcessTracer, 0L, "[FolderSyncState.GetFolderSyncStateMetadata] SyncStateMetadata in place of FolderSyncStateMetadata for Mailbox: {0}, State: {1}.  Trying re-read...", mailboxSession.MailboxOwner.MailboxInfo.PrimarySmtpAddress, name);
                syncStateStorage.DeviceMetadata.TryRemove(name, syncLogger);
                syncState = syncStateStorage.DeviceMetadata.GetSyncState(mailboxSession, name, syncLogger);
                folderSyncStateMetadata = (syncState as FolderSyncStateMetadata);
                if (folderSyncStateMetadata == null)
                {
                    syncStateStorage.DeleteFolderSyncState(name);
                    syncStateStorage.DeviceMetadata.TryRemove(name, null);
                    throw new CorruptSyncStateException(ServerStrings.ExSyncStateCorrupted(name), new InvalidOperationException("SyncStateMetadata in place of FolderSyncStateMetadata"));
                }
                syncLogger.TraceDebug <string>(ExTraceGlobals.SyncProcessTracer, 0L, "[FolderSyncState.GetFolderSyncStateMetadata] Re-read of sync state {0} was successful.", name);
            }
            return(folderSyncStateMetadata);
        }
        internal static FolderHierarchySyncState GetSyncState(SyncStateStorage syncStateStorage, Folder syncStateParentFolder, StoreObjectId storeObjectId, ISyncLogger syncLogger = null)
        {
            SyncStateInfo syncStateInfo        = new FolderHierarchySyncStateInfo();
            StoreObject   syncStateStoreObject = SyncState.GetSyncStateStoreObject(syncStateStorage, syncStateParentFolder, syncStateInfo, syncLogger, new PropertyDefinition[0]);

            if (syncStateStoreObject == null)
            {
                return(null);
            }
            SyncStateMetadata syncState = syncStateStorage.DeviceMetadata.GetSyncState(syncStateParentFolder.Session as MailboxSession, syncStateInfo.UniqueName, syncLogger);

            return(new FolderHierarchySyncState(syncStateStorage, syncStateStoreObject, syncState, syncStateInfo, false, syncLogger));
        }
Beispiel #6
0
        internal static CustomSyncState GetSyncState(SyncStateStorage syncStateStorage, Folder syncStateParentFolder, SyncStateInfo syncStateInfo, ISyncLogger syncLogger, params PropertyDefinition[] propertiesToFetch)
        {
            if (syncLogger == null)
            {
                syncLogger = TracingLogger.Singleton;
            }
            SyncStateMetadata syncStateMetadata    = null;
            StoreObject       syncStateStoreObject = SyncState.GetSyncStateStoreObject(syncStateStorage, syncStateParentFolder, syncStateInfo, syncLogger, out syncStateMetadata, propertiesToFetch);

            if (syncStateStoreObject == null)
            {
                return(null);
            }
            return(new CustomSyncState(syncStateStorage, syncStateStoreObject, syncStateMetadata, syncStateInfo, false));
        }
Beispiel #7
0
        internal static CustomSyncState CreateSyncState(SyncStateStorage syncStateStorage, SyncStateInfo syncStateInfo, Folder syncStateParentFolder, ISyncLogger syncLogger = null)
        {
            if (syncLogger == null)
            {
                syncLogger = TracingLogger.Singleton;
            }
            StoreObject storeObject = SyncState.CreateSyncStateStoreObject(syncStateStorage, syncStateInfo, syncStateParentFolder, null, null, syncLogger);

            if (syncStateStorage.DeviceMetadata.TryRemove(syncStateInfo.UniqueName, syncLogger) != null)
            {
                syncLogger.TraceDebug <DeviceIdentity, string>(ExTraceGlobals.SyncTracer, 0L, "[CustomSyncState.CreateSyncState] Removed stale cached sync state metadata for device {0}, sync state {1}", syncStateStorage.DeviceMetadata.Id, syncStateInfo.UniqueName);
            }
            SyncStateMetadata syncStateMetadata = (storeObject is Item) ? new SyncStateMetadata(syncStateStorage.DeviceMetadata, syncStateInfo.UniqueName, syncStateStorage.SaveOnDirectItems ? null : storeObject.ParentId, storeObject.Id.ObjectId) : new SyncStateMetadata(syncStateStorage.DeviceMetadata, syncStateInfo.UniqueName, storeObject.Id.ObjectId, null);

            return(new CustomSyncState(syncStateStorage, storeObject, syncStateMetadata, syncStateInfo, true));
        }
        private static void GetSyncStateBlob(MailboxSession session, SyncStateMetadata syncStateMetadata, SyncStateFolderData data)
        {
            switch (syncStateMetadata.StorageType)
            {
            case StorageType.Folder:
                using (Folder folder = Folder.Bind(session, syncStateMetadata.FolderSyncStateId, new PropertyDefinition[]
                {
                    ItemSchema.SyncCustomState
                }))
                {
                    object obj   = folder.TryGetProperty(ItemSchema.SyncCustomState);
                    byte[] array = obj as byte[];
                    data.SyncStateBlob = Convert.ToBase64String(array);
                    data.SyncStateSize = array.Length;
                    data.Created       = (DateTime)folder.CreationTime;
                    return;
                }
                break;

            case StorageType.Item:
            case StorageType.DirectItem:
                break;

            default:
                return;
            }
            using (Item item = Item.Bind(session, syncStateMetadata.ItemSyncStateId, new PropertyDefinition[]
            {
                ItemSchema.SyncCustomState
            }))
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (Stream stream = item.OpenPropertyStream(ItemSchema.SyncCustomState, PropertyOpenMode.ReadOnly))
                    {
                        byte[] data2 = new byte[1024];
                        Util.StreamHandler.CopyStreamData(stream, memoryStream, null, 0, data2);
                        memoryStream.Flush();
                    }
                    data.Created       = (DateTime)item.CreationTime;
                    data.SyncStateSize = (int)memoryStream.Position;
                    string syncStateBlob = Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Position, Base64FormattingOptions.None);
                    data.SyncStateBlob = syncStateBlob;
                }
            }
        }
Beispiel #9
0
        private AggregateOperationResult InternalDeleteSyncState(string name)
        {
            this.CheckDisposed("DeleteCustomSyncState");
            this.syncLogger.Information <int>(ExTraceGlobals.SyncTracer, (long)this.GetHashCode(), "SyncStateStorage::InternalDeleteSyncState. Hashcode = {0}", this.GetHashCode());
            ArgumentValidator.ThrowIfNullOrEmpty("name", name);
            SyncStateMetadata syncState = this.DeviceMetadata.GetSyncState(this.folder.Session as MailboxSession, name, this.syncLogger);

            this.DeviceMetadata.TryRemove(name, this.syncLogger);
            AggregateOperationResult result = null;

            if (syncState != null)
            {
                if (syncState.FolderSyncStateId == null && syncState.ItemSyncStateId != null)
                {
                    this.syncLogger.Information <string>(ExTraceGlobals.SyncTracer, (long)this.GetHashCode(), "[SyncStateStorage.InternalDeleteSyncState] Deleting direct item sync state {0}", name);
                    result = this.folder.DeleteObjects(DeleteItemFlags.SoftDelete, new StoreId[]
                    {
                        syncState.ItemSyncStateId
                    });
                }
                else if (syncState.FolderSyncStateId != null)
                {
                    this.syncLogger.Information <string>(ExTraceGlobals.SyncTracer, (long)this.GetHashCode(), "[SyncStateStorage.InternalDeleteSyncState] Deleting sync folder for sync state {0}", name);
                    result = this.folder.DeleteObjects(DeleteItemFlags.SoftDelete, new StoreId[]
                    {
                        syncState.FolderSyncStateId
                    });
                }
                else
                {
                    this.syncLogger.Information <string>(ExTraceGlobals.SyncTracer, (long)this.GetHashCode(), "[SyncStateStorage.InternalDeleteSyncState] Metadata had null for both item and folder id.  Weird - not deleting anything.  Sync State: {0}", name);
                }
                StoreObjectId storeObjectId = (syncState.FolderSyncStateId != null) ? syncState.FolderSyncStateId : syncState.ItemSyncStateId;
                if (storeObjectId != null)
                {
                    this.TraceAggregateOperationResultFromDelete(result, name, storeObjectId);
                }
            }
            return(result);
        }
Beispiel #10
0
        public SyncStateMetadata TryAdd(SyncStateMetadata syncStateMetadata, ISyncLogger syncLogger = null)
        {
            if (syncLogger == null)
            {
                syncLogger = TracingLogger.Singleton;
            }
            SyncStateMetadata syncStateMetadata2 = this.syncStateMap.GetOrAdd(syncStateMetadata.Name, syncStateMetadata);

            if (syncStateMetadata.GetType().IsSubclassOf(syncStateMetadata2.GetType()))
            {
                syncLogger.TraceDebug <string, string>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.TryAdd] New sync state metadata instance ({0}) is subclass of cached one ({1}).  Replacing.", syncStateMetadata.GetType().Name, syncStateMetadata2.GetType().Name);
                this.syncStateMap[syncStateMetadata.Name] = syncStateMetadata;
                syncStateMetadata2 = syncStateMetadata;
            }
            FolderSyncStateMetadata folderSyncStateMetadata = syncStateMetadata2 as FolderSyncStateMetadata;

            if (folderSyncStateMetadata != null && folderSyncStateMetadata.IPMFolderId != null)
            {
                syncLogger.TraceDebug <string>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.TryAdd] Encountered FolderSyncStateMetadata instance for '{0}'.  Adding source key to reverse mapping.", syncStateMetadata.Name);
                this.ipmToFolderSyncStateMap[folderSyncStateMetadata.IPMFolderId] = folderSyncStateMetadata;
            }
            return(syncStateMetadata2);
        }
 protected FolderHierarchySyncState(SyncStateStorage syncStateStorage, StoreObject storeObject, SyncStateMetadata syncStateMetadata, SyncStateInfo syncStateInfo, bool newSyncState, ISyncLogger syncLogger = null) : base(syncStateStorage, storeObject, syncStateMetadata, syncStateInfo, newSyncState, syncLogger)
 {
 }
Beispiel #12
0
        public SyncStateMetadata GetSyncState(MailboxSession mailboxSession, string name, ISyncLogger syncLogger = null)
        {
            if (syncLogger == null)
            {
                syncLogger = TracingLogger.Singleton;
            }
            SyncStateMetadata result;

            if (this.syncStateMap.TryGetValue(name, out result))
            {
                syncLogger.TraceDebug <string>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] Cache hit for sync state: {0}", name);
                return(result);
            }
            syncLogger.TraceDebug <string>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] Cache MISS for sync state: {0}", name);
            using (Folder folder = Folder.Bind(mailboxSession, this.DeviceFolderId, new PropertyDefinition[]
            {
                FolderSchema.ItemCount,
                FolderSchema.ChildCount
            }))
            {
                int itemCount = folder.ItemCount;
                syncLogger.TraceDebug <string, int, bool>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] deviceFolder {0} has {1} items and subfolders? {2}", folder.DisplayName, itemCount, folder.HasSubfolders);
                SyncStateMetadata syncStateMetadata = null;
                if (itemCount > 0)
                {
                    syncStateMetadata = this.GetSyncStateItemMetadata(mailboxSession, folder, name, syncLogger);
                    if (syncStateMetadata != null)
                    {
                        syncLogger.TraceDebug <SyncStateMetadata>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] Retrieved DIRECT item sync state: {0}", syncStateMetadata);
                        syncStateMetadata.FolderSyncStateId = null;
                    }
                }
                if (syncStateMetadata == null && folder.HasSubfolders)
                {
                    using (QueryResult queryResult = folder.FolderQuery(FolderQueryFlags.None, null, new SortBy[]
                    {
                        new SortBy(FolderSchema.DisplayName, SortOrder.Ascending)
                    }, DeviceSyncStateMetadata.NullSyncPropertiesFolders))
                    {
                        if (queryResult.SeekToCondition(SeekReference.OriginBeginning, new ComparisonFilter(ComparisonOperator.Equal, FolderSchema.DisplayName, name)))
                        {
                            IStorePropertyBag propertyBag = queryResult.GetPropertyBags(1)[0];
                            syncStateMetadata = this.GetMetadataFromPropertyBag(mailboxSession, propertyBag, syncLogger);
                            if (syncStateMetadata != null)
                            {
                                syncLogger.TraceDebug <SyncStateMetadata>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] Retrieved sub folder sync state: {0}", syncStateMetadata);
                            }
                        }
                    }
                }
                if (syncStateMetadata != null)
                {
                    SyncStateMetadata syncStateMetadata2 = this.syncStateMap.GetOrAdd(syncStateMetadata.Name, syncStateMetadata);
                    if (syncStateMetadata2.StorageType != syncStateMetadata.StorageType)
                    {
                        syncLogger.TraceDebug <StorageType, StorageType>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] Metadata was already cached but had store type: {0}.  New instance was: {1}.  Using new instance.", syncStateMetadata2.StorageType, syncStateMetadata.StorageType);
                        this.syncStateMap[syncStateMetadata.Name] = syncStateMetadata;
                        syncStateMetadata2 = syncStateMetadata;
                    }
                    return(syncStateMetadata2);
                }
                syncLogger.TraceDebug <string, Guid>(ExTraceGlobals.SyncProcessTracer, (long)this.GetHashCode(), "[DeviceSyncStateMetadata.GetSyncState] Cache miss for sync state {0}, Mailbox {1}, but search did not find it.", name, mailboxSession.MailboxGuid);
            }
            return(null);
        }
        internal static FolderSyncState GetSyncState(SyncStateStorage syncStateStorage, Folder deviceFolder, ISyncProviderFactory syncProviderFactory, Func <SyncStateStorage, StoreObject, FolderSyncStateMetadata, SyncStateInfo, ISyncProviderFactory, bool, ISyncLogger, FolderSyncState> creator, ISyncLogger syncLogger = null)
        {
            if (syncLogger == null)
            {
                syncLogger = TracingLogger.Singleton;
            }
            ArgumentValidator.ThrowIfNull("syncStateStorage", syncStateStorage);
            ArgumentValidator.ThrowIfNull("deviceFolder", deviceFolder);
            ArgumentValidator.ThrowIfNull("syncProviderFactory", syncProviderFactory);
            byte[] collectionIdBytes = syncProviderFactory.GetCollectionIdBytes();
            if (collectionIdBytes == null || collectionIdBytes.Length == 0)
            {
                throw new ArgumentException("SyncProviderFactory CollectionId bytes cannot be null or empty.");
            }
            StoreObjectId storeObjectId = null;

            try
            {
                storeObjectId = StoreObjectId.Deserialize(collectionIdBytes);
            }
            catch (ArgumentException innerException)
            {
                syncLogger.TraceError <string>(ExTraceGlobals.SyncTracer, 0L, "[FolderSyncState.GetSyncState(syncProviderFactory)] The IPMFolderBytes that the provider gave us are invalid for folder {0}", deviceFolder.DisplayName);
                throw new CorruptSyncStateException(ServerStrings.ExSyncStateCorrupted(deviceFolder.DisplayName), innerException);
            }
            FolderSyncStateMetadata folderSyncStateMetadata = null;

            if (!syncStateStorage.DeviceMetadata.SyncStatesByIPMFolderId.TryGetValue(storeObjectId, out folderSyncStateMetadata))
            {
                syncLogger.TraceDebug <DeviceIdentity, string>(ExTraceGlobals.SyncTracer, 0L, "[FolderSyncState.GetSyncState(syncProviderFactory)] Cache miss for device {0}, IPM folder Id {1}", syncStateStorage.DeviceMetadata.Id, storeObjectId.ToBase64String());
                return(null);
            }
            SyncStateMetadata syncStateMetadata = folderSyncStateMetadata;
            StoreObject       storeObject       = SyncState.GetSyncStateStoreObject(deviceFolder, ref syncStateMetadata, syncLogger, new PropertyDefinition[]
            {
                InternalSchema.SyncFolderSourceKey
            });

            if (!object.ReferenceEquals(folderSyncStateMetadata, syncStateMetadata))
            {
                FolderSyncStateMetadata folderSyncStateMetadata2 = syncStateMetadata as FolderSyncStateMetadata;
                if (folderSyncStateMetadata2 == null)
                {
                    syncLogger.TraceDebug <string, string>(ExTraceGlobals.SyncProcessTracer, 0L, "[FolderSyncState.GetSyncState] Device {0} has non-folder sync state for {1}.  Returning null.", deviceFolder.DisplayName, folderSyncStateMetadata.Name);
                    if (storeObject != null)
                    {
                        storeObject.Dispose();
                        storeObject = null;
                    }
                }
                else
                {
                    syncLogger.TraceDebug <string, string>(ExTraceGlobals.SyncProcessTracer, 0L, "[FolderSyncState.GetSyncState] Device {0} had  state folder sync state metadata for {1}.  Replacing.", deviceFolder.DisplayName, folderSyncStateMetadata.Name);
                    folderSyncStateMetadata = folderSyncStateMetadata2;
                }
            }
            if (storeObject == null)
            {
                return(null);
            }
            SyncStateInfo syncStateInfo = new FolderSyncStateInfo(folderSyncStateMetadata.Name);

            if (creator == null)
            {
                return(new FolderSyncState(syncStateStorage, storeObject, folderSyncStateMetadata, syncStateInfo, syncProviderFactory, false, syncLogger));
            }
            return(creator(syncStateStorage, storeObject, folderSyncStateMetadata, syncStateInfo, syncProviderFactory, false, syncLogger));
        }
Beispiel #14
0
 protected CustomSyncState(SyncStateStorage syncStateStorage, StoreObject storeObject, SyncStateMetadata syncStateMetadata, SyncStateInfo syncStateInfo, bool syncStateIsNew) : base(syncStateStorage, storeObject, syncStateMetadata, syncStateInfo, syncStateIsNew, null)
 {
 }