public void RenameFile(RenameFileOperation operation)
		{
			var configName = RavenFileNameHelper.RenameOperationConfigNameForFile(operation.Name);
			notificationPublisher.Publish(new FileChange
			{
				File = FilePathTools.Cannoicalise(operation.Name),
				Action = FileChangeAction.Renaming
			});

			storage.Batch(accessor =>
			{
				var previousRenameTombstone = accessor.ReadFile(operation.Rename);

				if (previousRenameTombstone != null &&
					previousRenameTombstone.Metadata[SynchronizationConstants.RavenDeleteMarker] != null)
				{
					// if there is a tombstone delete it
					accessor.Delete(previousRenameTombstone.Name);
				}

				accessor.RenameFile(operation.Name, operation.Rename, true);
				accessor.UpdateFileMetadata(operation.Rename, operation.MetadataAfterOperation);

				// copy renaming file metadata and set special markers
				var tombstoneMetadata =
					new NameValueCollection(operation.MetadataAfterOperation).WithRenameMarkers(operation.Rename);

				accessor.PutFile(operation.Name, 0, tombstoneMetadata, true); // put rename tombstone

				accessor.DeleteConfig(configName);

				search.Delete(operation.Name);
				search.Index(operation.Rename, operation.MetadataAfterOperation);
			});

			notificationPublisher.Publish(new ConfigChange { Name = configName, Action = ConfigChangeAction.Set });
			notificationPublisher.Publish(new FileChange
			{
				File = FilePathTools.Cannoicalise(operation.Rename),
				Action = FileChangeAction.Renamed
			});
		}
		public HttpResponseMessage Patch(string name, string rename)
		{
			name = RavenFileNameHelper.RavenPath(name);
			rename = RavenFileNameHelper.RavenPath(rename);

			try
			{
				ConcurrencyAwareExecutor.Execute(() =>
					Storage.Batch(accessor =>
					{
						AssertFileIsNotBeingSynced(name, accessor, true);

						var metadata = accessor.GetFile(name, 0, 0).Metadata;
						if (metadata.Keys.Contains(SynchronizationConstants.RavenDeleteMarker))
						{
							throw new FileNotFoundException();
						}

						var existingHeader = accessor.ReadFile(rename);
						if (existingHeader != null && !existingHeader.Metadata.ContainsKey(SynchronizationConstants.RavenDeleteMarker))
						{
							throw new HttpResponseException(
								Request.CreateResponse(HttpStatusCode.Forbidden,
													new InvalidOperationException("Cannot rename because file " + rename + " already exists")));
						}

                        Historian.UpdateLastModified(metadata);

                        var operation = new RenameFileOperation
                        {
                            Name = name,
                            Rename = rename,
                            MetadataAfterOperation = metadata
                        };

                        accessor.SetConfig(RavenFileNameHelper.RenameOperationConfigNameForFile(name), JsonExtensions.ToJObject(operation));
                        accessor.PulseTransaction(); // commit rename operation config

                        StorageOperationsTask.RenameFile(operation);
					}), ConcurrencyResponseException);
			}
			catch (FileNotFoundException)
			{
				log.Debug("Cannot rename a file '{0}' to '{1}' because a file was not found", name, rename);
                return GetEmptyMessage(HttpStatusCode.NotFound);
			}

			log.Debug("File '{0}' was renamed to '{1}'", name, rename);

			StartSynchronizeDestinationsInBackground();

            return GetMessageWithString("", HttpStatusCode.NoContent);
		}
		public async Task Should_resume_file_renaming_from_client()
		{
			var client = NewAsyncClient();
			var rfs = GetRavenFileSystem();

			string fileName = FileHeader.Canonize("file.bin");
			string rename = FileHeader.Canonize("renamed.bin");

			await client.UploadAsync(fileName, new RandomStream(1));

			// create config to say to the server that rename operation performed last time were not finished
			var renameOpConfig = RavenFileNameHelper.RenameOperationConfigNameForFile(fileName);
            var renameOperation = new RenameFileOperation
				                    {
					                    Name = fileName,
					                    Rename = rename,
                                        MetadataAfterOperation = new RavenJObject().WithETag(Guid.Empty)
				                    };

            rfs.Storage.Batch(accessor => accessor.SetConfigurationValue(renameOpConfig, renameOperation ));

			await client.Storage.RetryRenamingAsync();

			IEnumerable<string> configNames = await client.Configuration.GetKeyNamesAsync();

			Assert.DoesNotContain(renameOpConfig, configNames);

			var renamedMetadata = await client.GetMetadataForAsync(rename);

			Assert.NotNull(renamedMetadata);
		}
		public void Should_resume_to_rename_file_if_appropriate_config_exists()
		{
			var client = NewAsyncClient();
			var rfs = GetRavenFileSystem();

            string fileName = FileHeader.Canonize("file.bin");
			string rename = FileHeader.Canonize("renamed.bin");

			client.UploadAsync(fileName, new RandomStream(1)).Wait();

			// create config to say to the server that rename operation performed last time were not finished
			var renameOpConfig = RavenFileNameHelper.RenameOperationConfigNameForFile(fileName);
            var renameOperation =  new RenameFileOperation
				                        {
					                        Name = fileName,
					                        Rename = rename,
                                            MetadataAfterOperation = new RavenJObject().WithETag(Guid.Empty)
				                        };

            rfs.Storage.Batch(accessor => accessor.SetConfigurationValue(renameOpConfig, renameOperation));

			rfs.StorageOperationsTask.ResumeFileRenamingAsync().Wait();

			IEnumerable<string> configNames = null;
			rfs.Storage.Batch(accessor => configNames = accessor.GetConfigNames(0, 10).ToArray());

			Assert.DoesNotContain(renameOpConfig, configNames);

			var renamedMetadata = client.GetMetadataForAsync(rename).Result;

			Assert.NotNull(renamedMetadata);

			var results = client.SearchOnDirectoryAsync("/").Result; // make sure that indexes are updated

			Assert.Equal(1, results.FileCount);
			Assert.Equal(rename, results.Files[0].FullPath);
		}