public void Should_reuse_pages_when_data_appended(int numberOfPages)
		{
			var file = SyncTestUtils.PreparePagesStream(numberOfPages);

			var sourceContent = new CombinedStream(file, SyncTestUtils.PreparePagesStream(numberOfPages));
				// add new pages at the end
			var destinationContent = file;

			sourceContent.Position = 0;
			source.UploadAsync("test", sourceContent).Wait();
			destinationContent.Position = 0;
			destination.UploadAsync("test", destinationContent).Wait();

			var contentUpdate = new ContentUpdateWorkItem("test", "http://localhost:12345", sourceRfs.Storage,
			                                              sourceRfs.SigGenerator);

			// force to upload entire file, we just want to check which pages will be reused
			contentUpdate.UploadToAsync(destination.ServerUrl).Wait();
			destination.Synchronization.ResolveConflictAsync("test", ConflictResolutionStrategy.RemoteVersion).Wait();
			contentUpdate.UploadToAsync(destination.ServerUrl).Wait();

			FileAndPages fileAndPages = null;
			destinationRfs.Storage.Batch(accessor => fileAndPages = accessor.GetFile("test", 0, 2*numberOfPages));

			Assert.Equal(2*numberOfPages, fileAndPages.Pages.Count);

			for(var i = 0; i < numberOfPages; i++)
			{
				Assert.Equal(i + 1, fileAndPages.Pages[i].Id);
					// if page ids are in the original order it means that they were used the existing pages
			}

			sourceContent.Position = 0;
			Assert.Equal(sourceContent.GetMD5Hash(), destination.GetMetadataForAsync("test").Result["Content-MD5"]);
		}
		public void Should_mark_file_to_be_resolved_using_current_strategy()
		{
			var differenceChunk = new MemoryStream();
			var sw = new StreamWriter(differenceChunk);

			sw.Write("Coconut is Stupid");
			sw.Flush();

			var sourceContent = SyncTestUtils.PrepareSourceStream(10);
			sourceContent.Position = 0;
			var destinationContent = new CombinedStream(differenceChunk, sourceContent);
			var destinationClient = NewClient(0);
			var sourceClient = NewClient(1);
			var sourceMetadata = new NameValueCollection
				                     {
					                     {"SomeTest-metadata", "some-value"}
				                     };
			var destinationMetadata = new NameValueCollection
				                          {
					                          {"SomeTest-metadata", "shouldnt-be-overwritten"}
				                          };

			destinationClient.UploadAsync("test.txt", destinationMetadata, destinationContent).Wait();
			sourceContent.Position = 0;
			sourceClient.UploadAsync("test.txt", sourceMetadata, sourceContent).Wait();


			var shouldBeConflict = sourceClient.Synchronization.StartAsync("test.txt", destinationClient.ServerUrl).Result;

			Assert.Equal("File test.txt is conflicted", shouldBeConflict.Exception.Message);

			destinationClient.Synchronization.ResolveConflictAsync("test.txt", ConflictResolutionStrategy.CurrentVersion).Wait();
			var result = destinationClient.Synchronization.StartAsync("test.txt", sourceClient.ServerUrl).Result;
			Assert.Equal(destinationContent.Length, result.BytesCopied + result.BytesTransfered);

			// check if conflict resolution has been properly set on the source
			string resultMd5;
			using (var resultFileContent = new MemoryStream())
			{
				var metadata = sourceClient.DownloadAsync("test.txt", resultFileContent).Result;
				Assert.Equal("shouldnt-be-overwritten", metadata["SomeTest-metadata"]);
				resultFileContent.Position = 0;
				resultMd5 = resultFileContent.GetMD5Hash();
				resultFileContent.Position = 0;
			}

			destinationContent.Position = 0;
			var destinationMd5 = destinationContent.GetMD5Hash();
			sourceContent.Position = 0;

			Assert.True(resultMd5 == destinationMd5);
		}
		public void Synchronize_file_with_different_beginning(int size)
		{
			var differenceChunk = new MemoryStream();
			var sw = new StreamWriter(differenceChunk);

			sw.Write("Coconut is Stupid");
			sw.Flush();

			var sourceContent = SyncTestUtils.PrepareSourceStream(size);
			sourceContent.Position = 0;
			var destinationContent = new CombinedStream(differenceChunk, sourceContent) {Position = 0};
			var sourceClient = NewClient(0);
			var destinationClient = NewClient(1);
			var sourceMetadata = new NameValueCollection
				                     {
					                     {"SomeTest-metadata", "some-value"}
				                     };
			var destinationMetadata = new NameValueCollection
				                          {
					                          {"SomeTest-metadata", "should-be-overwritten"}
				                          };

			destinationClient.UploadAsync("test.txt", destinationMetadata, destinationContent).Wait();
			sourceContent.Position = 0;
			sourceClient.UploadAsync("test.txt", sourceMetadata, sourceContent).Wait();

			var result = SyncTestUtils.ResolveConflictAndSynchronize(sourceClient, destinationClient, "test.txt");

			Assert.Equal(sourceContent.Length, result.BytesCopied + result.BytesTransfered);

			string resultMd5;
			using (var resultFileContent = new MemoryStream())
			{
				var metadata = destinationClient.DownloadAsync("test.txt", resultFileContent).Result;
				Assert.Equal("some-value", metadata["SomeTest-metadata"]);
				resultFileContent.Position = 0;
				resultMd5 = resultFileContent.GetMD5Hash();
				resultFileContent.Position = 0;
			}

			sourceContent.Position = 0;
			var sourceMd5 = sourceContent.GetMD5Hash();

			Assert.True(resultMd5 == sourceMd5);
		}
		public void Synchronize_file_with_different_beginning()
		{
			const int size = 5000;
			var differenceChunk = new MemoryStream();
			var sw = new StreamWriter(differenceChunk);

			sw.Write("Coconut is Stupid");
			sw.Flush();

			var sourceContent = PrepareSourceStream(size);
			sourceContent.Position = 0;
			var seedContent = new CombinedStream(differenceChunk, sourceContent);

			using (var sourceSignatureRepository = CreateSignatureRepositoryFor("test2"))
			using (var seedSignatureRepository = CreateSignatureRepositoryFor("test1"))
			{
				IList<SignatureInfo> seedSignatureInfos;
				using (var generator = new SigGenerator())
				{
					seedContent.Seek(0, SeekOrigin.Begin);
					seedSignatureInfos = generator.GenerateSignatures(seedContent, "test1", seedSignatureRepository);
				}
				IList<SignatureInfo> sourceSignatureInfos;
				using (var generator = new SigGenerator())
				{
					sourceContent.Seek(0, SeekOrigin.Begin);
					sourceSignatureInfos = generator.GenerateSignatures(sourceContent, "test2", sourceSignatureRepository);
				}
				var sourceSize = sourceContent.Length;

				using (var tested = new NeedListGenerator(seedSignatureRepository, sourceSignatureRepository))
				{
					var result = tested.CreateNeedsList(seedSignatureInfos.Last(), sourceSignatureInfos.Last());
					Assert.NotNull(result);
					Assert.Equal(2, result.Count);
					Assert.Equal(0, sourceSize - result.Sum(x => Convert.ToInt32(x.BlockLength)));
				}
			}
		}
		public void Synchronize_file_with_appended_data(int size)
		{
			var differenceChunk = new MemoryStream();
			var sw = new StreamWriter(differenceChunk);

			sw.Write("Coconut is Stupid");
			sw.Flush();

			var sourceContent = new CombinedStream(SyncTestUtils.PrepareSourceStream(size), differenceChunk) {Position = 0};
			var destinationContent = SyncTestUtils.PrepareSourceStream(size);
			destinationContent.Position = 0;
			var sourceClient = NewClient(0);
			var destinationClient = NewClient(1);

			destinationClient.UploadAsync("test.txt", destinationContent).Wait();
			sourceContent.Position = 0;
			sourceClient.UploadAsync("test.txt", sourceContent).Wait();

			var result = SyncTestUtils.ResolveConflictAndSynchronize(sourceClient, destinationClient, "test.txt");

			Assert.Equal(sourceContent.Length, result.BytesCopied + result.BytesTransfered);

			string resultMd5;
			using (var resultFileContent = new MemoryStream())
			{
				destinationClient.DownloadAsync("test.txt", resultFileContent).Wait();
				resultFileContent.Position = 0;
				resultMd5 = resultFileContent.GetMD5Hash();
				resultFileContent.Position = 0;
			}

			sourceContent.Position = 0;
			var sourceMd5 = sourceContent.GetMD5Hash();

			Assert.True(resultMd5 == sourceMd5);
		}