private void SaveSynchronizationSourceInformation(ServerInfo sourceServer, Guid lastSourceEtag,
		                                                  StorageActionsAccessor accessor)
		{
			var lastSynchronizationInformation = GetLastSynchronization(sourceServer.Id, accessor);
			if (Buffers.Compare(lastSynchronizationInformation.LastSourceFileEtag.ToByteArray(), lastSourceEtag.ToByteArray()) >
			    0)
			{
				return;
			}

			var synchronizationSourceInfo = new SourceSynchronizationInformation
				                                {
					                                LastSourceFileEtag = lastSourceEtag,
					                                SourceServerUrl = sourceServer.Url,
					                                DestinationServerId = Storage.Id
				                                };

			var key = SynchronizationConstants.RavenSynchronizationSourcesBasePath + "/" + sourceServer.Id;

			accessor.SetConfig(key, synchronizationSourceInfo.AsConfig());

			Log.Debug("Saved last synchronized file ETag {0} from {1} ({2})", lastSourceEtag, sourceServer.Url, sourceServer.Id);
		}
		private IEnumerable<FileHeader> GetFilesToSynchronization(
			SourceSynchronizationInformation destinationsSynchronizationInformationForSource, int take)
		{
			var filesToSynchronization = new List<FileHeader>();

			Log.Debug("Getting files to synchronize with ETag greater than {0} [parameter take = {1}]",
			          destinationsSynchronizationInformationForSource.LastSourceFileEtag, take);

			try
			{
				storage.Batch(
					accessor =>
					filesToSynchronization =
					accessor.GetFilesAfter(destinationsSynchronizationInformationForSource.LastSourceFileEtag, take).ToList());
			}
			catch (Exception e)
			{
				Log.WarnException(
					string.Format("Could not get files to synchronize after: " +
					              destinationsSynchronizationInformationForSource.LastSourceFileEtag), e);
			}

			return filesToSynchronization;
		}
		private SourceSynchronizationInformation GetLastSynchronization(Guid from, StorageActionsAccessor accessor)
		{
			SourceSynchronizationInformation info;
			try
			{
				info =
					accessor.GetConfig(SynchronizationConstants.RavenSynchronizationSourcesBasePath + "/" + from).AsObject
						<SourceSynchronizationInformation>();
			}
			catch (FileNotFoundException)
			{
				info = new SourceSynchronizationInformation
					       {
						       LastSourceFileEtag = Guid.Empty,
						       DestinationServerId = Storage.Id
					       };
			}

			return info;
		}
		private async Task EnqueueMissingUpdatesAsync(RavenFileSystemClient destinationClient,
		                                              SourceSynchronizationInformation lastEtag,
		                                              IList<FileHeader> needSyncingAgain)
		{
			LogFilesInfo("There were {0} file(s) that needed synchronization because the previous one went wrong: {1}",
			             needSyncingAgain);

			var destinationUrl = destinationClient.ServerUrl;
			var filesToSynchronization = new HashSet<FileHeader>(GetFilesToSynchronization(lastEtag, 100),
			                                                     new FileHeaderNameEqualityComparer());

			LogFilesInfo("There were {0} file(s) that needed synchronization because of greater ETag value: {1}",
			             filesToSynchronization);

			foreach (FileHeader needSyncing in needSyncingAgain)
			{
				filesToSynchronization.Add(needSyncing);
			}

			var filteredFilesToSynchronization =
				filesToSynchronization.Where(
					x => synchronizationStrategy.Filter(x, lastEtag.DestinationServerId, filesToSynchronization)).ToList();

			if (filesToSynchronization.Count > 0)
			{
				LogFilesInfo("There were {0} file(s) that needed synchronization after filtering: {1}",
				             filteredFilesToSynchronization);
			}

			if (filteredFilesToSynchronization.Count == 0)
				return;

			foreach (var fileHeader in filteredFilesToSynchronization)
			{
				var file = fileHeader.Name;
				var localMetadata = GetLocalMetadata(file);

				NameValueCollection destinationMetadata;

				try
				{
					destinationMetadata = await destinationClient.GetMetadataForAsync(file);
				}
				catch (Exception ex)
				{
					Log.WarnException(
						string.Format(
							"Could not retrieve a metadata of a file '{0}' from {1} in order to determine needed synchronization type", file,
							destinationUrl), ex);

					continue;
				}

				NoSyncReason reason;
				var work = synchronizationStrategy.DetermineWork(file, localMetadata, destinationMetadata, ServerUrl, out reason);

				if (work == null)
				{
					Log.Debug("File '{0}' were not synchronized to {1}. {2}", file, destinationUrl, reason.GetDescription());

					if (reason == NoSyncReason.ContainedInDestinationHistory)
					{
						var etag = localMetadata.Value<Guid>("ETag");
						destinationClient.Synchronization.IncrementLastETagAsync(storage.Id, ServerUrl, etag);
						RemoveSyncingConfiguration(file, destinationClient.ServerUrl);
					}

					continue;
				}

				synchronizationQueue.EnqueueSynchronization(destinationUrl, work);
			}
		}