private async Task <IDictionary <string, CatalogItemSummary> > SaveItems(Guid commitId, DateTime commitTimeStamp, CancellationToken cancellationToken)
        {
            ConcurrentDictionary <string, CatalogItemSummary> pageItems = new ConcurrentDictionary <string, CatalogItemSummary>();

            int batchIndex = 0;

            var saveTasks = new List <Task>();

            foreach (CatalogItem item in _batch)
            {
                ResourceSaveOperation saveOperationForItem = null;

                try
                {
                    item.TimeStamp   = commitTimeStamp;
                    item.CommitId    = commitId;
                    item.BaseAddress = Storage.BaseAddress;

                    saveOperationForItem = CreateSaveOperationForItem(Storage, Context, item, cancellationToken);
                    if (saveOperationForItem.SaveTask != null)
                    {
                        saveTasks.Add(saveOperationForItem.SaveTask);
                    }

                    IGraph pageContent = item.CreatePageContent(Context);

                    if (!pageItems.TryAdd(saveOperationForItem.ResourceUri.AbsoluteUri, new CatalogItemSummary(item.GetItemType(), commitId, commitTimeStamp, null, pageContent)))
                    {
                        throw new Exception("Duplicate page: " + saveOperationForItem.ResourceUri.AbsoluteUri);
                    }

                    batchIndex++;
                }
                catch (Exception e)
                {
                    string msg = (saveOperationForItem == null || saveOperationForItem.ResourceUri == null)
                        ? string.Format("batch index: {0}", batchIndex)
                        : string.Format("batch index: {0} resourceUri: {1}", batchIndex, saveOperationForItem.ResourceUri);

                    throw new Exception(msg, e);
                }
            }

            await Task.WhenAll(saveTasks);

            return(pageItems);
        }
        protected virtual ResourceSaveOperation CreateSaveOperationForItem(IStorage storage, CatalogContext context, CatalogItem item, CancellationToken cancellationToken)
        {
            // This method decides what to do with the item.
            // Standard method of operation: if content == null, don't do a thing. Else, write content.

            var content     = item.CreateContent(Context); // note: always do this first
            var resourceUri = item.GetItemAddress();

            var operation = new ResourceSaveOperation();

            operation.ResourceUri = resourceUri;

            if (content != null)
            {
                operation.SaveTask = storage.SaveAsync(resourceUri, content, cancellationToken);
            }

            return(operation);
        }
        protected override ResourceSaveOperation CreateSaveOperationForItem(IStorage storage, CatalogContext context, CatalogItem item, CancellationToken cancellationToken)
        {
            // This method decides what to do with the item.
            // If it's a RegistrationMakerCatalogItem and it already exists, then don't write content.
            var registrationMakerCatalogItem = item as RegistrationMakerCatalogItem;
            if (registrationMakerCatalogItem != null)
            {
                var content = item.CreateContent(Context); // note: always do this first
                var resourceUri = item.GetItemAddress();

                var saveOperation = new ResourceSaveOperation();
                saveOperation.ResourceUri = resourceUri;

                if (!registrationMakerCatalogItem.IsExistingItem && content != null)
                {
                    saveOperation.SaveTask = storage.Save(resourceUri, content, cancellationToken);
                }
                else
                {
                    Trace.WriteLine(string.Format("Resource {0} already exists. Skipping.", resourceUri), "Debug");
                }

                return saveOperation;
            }

            return base.CreateSaveOperationForItem(storage, context, item, cancellationToken);
        }
        protected virtual ResourceSaveOperation CreateSaveOperationForItem(IStorage storage, CatalogContext context, CatalogItem item, CancellationToken cancellationToken)
        {
            // This method decides what to do with the item.
            // Standard method of operation: if content == null, don't do a thing. Else, write content.

            var content = item.CreateContent(Context); // note: always do this first
            var resourceUri = item.GetItemAddress();

            var operation = new ResourceSaveOperation();
            operation.ResourceUri = resourceUri;

            if (content != null)
            {
                operation.SaveTask = storage.Save(resourceUri, content, cancellationToken);
            }

            return operation;
        }