public virtual async Task <StorageDeleteOperationResult> DeleteBackup(string identifier, StorageBackup backup)
        {
            if (backup == null)
            {
                throw new ArgumentNullException(nameof(backup));
            }
            if (!await Exists(backup.Identifier))
            {
                return(new StorageDeleteOperationResult(false));
            }
            StorageMetaData metaData = await LoadMetaData(identifier);

            if (metaData.Has("Backups"))
            {
                List <StorageBackup> backups        = metaData.Get <List <StorageBackup> >("Backups");
                StorageBackup        backupToRemove = backup;
                foreach (StorageBackup currentBackup in backups)
                {
                    if (currentBackup.Identifier == backup.Identifier)
                    {
                        backupToRemove = currentBackup;
                    }
                }
                backups.Remove(backupToRemove);
                metaData["Backups"] = backups;
                await SaveMetaData(identifier, metaData);
            }
            return(await Delete(backup.Identifier));
        }
        public virtual async Task <StorageBackup> GetLatestBackup(string identifier)
        {
            StorageMetaData metaData = await LoadMetaData(identifier);

            if (metaData.Has("Backups"))
            {
                List <StorageBackup> backups      = metaData.Get <List <StorageBackup> >("Backups");
                StorageBackup        latestBackup = null;
                foreach (StorageBackup backup in backups)
                {
                    if (latestBackup == null)
                    {
                        latestBackup = backup;
                    }
                    else if (backup.BackupTimeUtc > latestBackup.BackupTimeUtc)
                    {
                        if (await Exists(backup.Identifier))
                        {
                            latestBackup = backup;
                        }
                    }
                }
                return(latestBackup);
            }
            return(null);
        }
        public virtual async Task <List <StorageBackup> > GetBackups(string identifier)
        {
            StorageMetaData metaData = await LoadMetaData(identifier);

            if (metaData.Has("Backups"))
            {
                return(metaData.Get <List <StorageBackup> >("Backups"));
            }
            return(null);
        }
        public virtual async Task <bool> DeleteBackups(string identifier)
        {
            StorageMetaData metaData = await LoadMetaData(identifier);

            if (metaData.Has("Backups"))
            {
                bool allSucceed = true;
                List <StorageBackup> backups = metaData.Get <List <StorageBackup> >("Backups");
                foreach (StorageBackup backup in backups)
                {
                    if (await Exists(backup.Identifier))
                    {
                        allSucceed &= (await Delete(backup.Identifier)).Succeed;
                    }
                }
                backups.Clear();
                metaData["Backups"] = backups;
                await SaveMetaData(identifier, metaData);

                return(allSucceed);
            }
            return(false);
        }
        public virtual async Task <StorageBackup> CreateBackup(string identifier)
        {
            DateTime      backupTimeUtc    = DateTime.UtcNow;
            string        backupIdentifier = identifier + backupTimeUtc.Ticks + this.BackupSuffix;
            StorageBackup backup           = new StorageBackup(backupIdentifier, backupTimeUtc);

            await Copy(identifier, backupIdentifier, false);

            // Update source item meta data after creating backup
            StorageMetaData metaData = await LoadMetaData(identifier);

            List <StorageBackup> backups = new List <StorageBackup>();

            if (metaData.Has("Backups"))
            {
                backups = metaData.Get <List <StorageBackup> >("Backups");
            }
            backups.Add(backup);
            metaData["Backups"] = backups;
            await SaveMetaData(identifier, metaData);

            return(backup);
        }