private async Task <IEnumerable <Task <SynchronizationReport> > > SynchronizeDestinationAsync(SynchronizationDestination destination, bool forceSyncingAll) { ICredentials credentials = destination.Credentials; var destinationSyncClient = new SynchronizationServerClient(destination.ServerUrl, destination.FileSystem, destination.ApiKey, credentials); bool repeat; do { var lastETag = await destinationSyncClient.GetLastSynchronizationFromAsync(storage.Id).ConfigureAwait(false); var activeTasks = synchronizationQueue.Active; var filesNeedConfirmation = GetSyncingConfigurations(destination).Where(sync => activeTasks.All(x => x.FileName != sync.FileName)).ToList(); var confirmations = await ConfirmPushedFiles(filesNeedConfirmation, destinationSyncClient).ConfigureAwait(false); var needSyncingAgain = new List <FileHeader>(); foreach (var confirmation in confirmations) { if (confirmation.Status == FileStatus.Safe) { if (Log.IsDebugEnabled) { Log.Debug("Destination server {0} said that file '{1}' is safe", destination, confirmation.FileName); } RemoveSyncingConfiguration(confirmation.FileName, destination.Url); } else { storage.Batch(accessor => { var fileHeader = accessor.ReadFile(confirmation.FileName); if (fileHeader != null) { needSyncingAgain.Add(fileHeader); if (Log.IsDebugEnabled) { Log.Debug("Destination server {0} said that file '{1}' is {2}.", destination, confirmation.FileName, confirmation.Status); } } }); } } if (synchronizationQueue.NumberOfPendingSynchronizationsFor(destination.Url) < AvailableSynchronizationRequestsTo(destination.Url)) { repeat = await EnqueueMissingUpdatesAsync(destinationSyncClient, lastETag, needSyncingAgain).ConfigureAwait(false) == false; } else { repeat = false; } }while (repeat); return(SynchronizePendingFilesAsync(destinationSyncClient, forceSyncingAll)); }