Inheritance: System.Runtime.ConstrainedExecution.CriticalFinalizerObject, IDisposable
		public void Generate_check()
		{
			IList<SignatureInfo> sourceSignatureInfos;
			IList<SignatureInfo> seedSignatureInfos;
			using (var sourceSignatureRepository = CreateSignatureRepositoryFor("test"))
			using (var seedSignatureRepository = CreateSignatureRepositoryFor("test"))
			{
				using (var generator = new SigGenerator())
				{
					seedSignatureInfos = generator.GenerateSignatures(GetSeedStream(), "test", seedSignatureRepository);
				}
				var sourceStream = GetSourceStream();
				using (var generator = new SigGenerator())
				{
					sourceSignatureInfos = generator.GenerateSignatures(sourceStream, "test", sourceSignatureRepository);
				}
				var sourceSize = sourceStream.Length;
				using (var tested = new NeedListGenerator(sourceSignatureRepository, seedSignatureRepository))
				{
					var result = tested.CreateNeedsList(seedSignatureInfos.Last(), sourceSignatureInfos.Last());
					Assert.NotNull(result);

					Assert.Equal(0, sourceSize - result.Sum(x => Convert.ToInt32(x.BlockLength)));
				}
			}
		}
		public void Ctor_and_dispose()
		{
			using (var tested = new SigGenerator())
			{
				Assert.NotNull(tested);
			}
		}
		public void Should_be_only_work_with_greater_etag_in_pending_queue()
		{
			using (var sigGenerator = new SigGenerator())
			{
				transactionalStorage.Batch(accessor => accessor.PutFile(FileName, 0, EmptyETagMetadata));

				queue.EnqueueSynchronization(Destination,
				                             new ContentUpdateWorkItem(FileName, "http://localhost:12345", transactionalStorage,
				                                                       sigGenerator));

				Assert.Equal(1, queue.Pending.Count());

				var greaterGuid = Guid.NewGuid();

				transactionalStorage.Batch(accessor => accessor.UpdateFileMetadata(FileName, new NameValueCollection
					                                                                             {
						                                                                             {"ETag", "\"" + greaterGuid + "\""}
					                                                                             }));

				queue.EnqueueSynchronization(Destination,
				                             new ContentUpdateWorkItem(FileName, "http://localhost:12345", transactionalStorage,
				                                                       new SigGenerator()));

				Assert.Equal(1, queue.Pending.Count());
				Assert.Equal(greaterGuid, queue.Pending.ToArray()[0].FileETag);
			}
		}
		public LocalRdcManager(ISignatureRepository signatureRepository, TransactionalStorage transactionalStorage,
		                       SigGenerator sigGenerator)
		{
			_signatureRepository = signatureRepository;
			_transactionalStorage = transactionalStorage;
			_sigGenerator = sigGenerator;
		}
		public SynchronizationTask(TransactionalStorage storage, SigGenerator sigGenerator, NotificationPublisher publisher,
		                           InMemoryConfiguration systemConfiguration)
		{
			this.storage = storage;
			this.publisher = publisher;
			this.systemConfiguration = systemConfiguration;
			synchronizationQueue = new SynchronizationQueue();
			synchronizationStrategy = new SynchronizationStrategy(storage, sigGenerator);

			InitializeTimer();
		}
		public void Should_be_the_same_signatures()
		{
			const int size = 1024*1024*5;
			var randomStream = new RandomStream(size);
			var buffer = new byte[size];
			randomStream.Read(buffer, 0, size);
			var stream = new MemoryStream(buffer);

			var firstSigContentHashes = new List<string>();

			using (var signatureRepository = new VolatileSignatureRepository("test"))
			using (var rested = new SigGenerator())
			{
				var result = rested.GenerateSignatures(stream, "test", signatureRepository);

				foreach (var signatureInfo in result)
				{
					using (var content = signatureRepository.GetContentForReading(signatureInfo.Name))
					{
						firstSigContentHashes.Add(content.GetMD5Hash());
					}
				}
			}

			stream.Position = 0;

			var secondSigContentHashes = new List<string>();

			using (var signatureRepository = new VolatileSignatureRepository("test"))
			using (var rested = new SigGenerator())
			{
				var result = rested.GenerateSignatures(stream, "test", signatureRepository);

				foreach (var signatureInfo in result)
				{
					using (var content = signatureRepository.GetContentForReading(signatureInfo.Name))
					{
						secondSigContentHashes.Add(content.GetMD5Hash());
					}
				}
			}

			Assert.Equal(firstSigContentHashes.Count, secondSigContentHashes.Count);

			for (var i = 0; i < firstSigContentHashes.Count; i++)
			{
				Assert.Equal(firstSigContentHashes[i], secondSigContentHashes[i]);
			}
		}
		public void Generate_check()
		{
			using (var signatureRepository = new VolatileSignatureRepository("test"))
			using (var rested = new SigGenerator())
			{
				var result = rested.GenerateSignatures(_stream, "test", signatureRepository);
				Assert.Equal(2, result.Count);
				using (var content = signatureRepository.GetContentForReading(result[0].Name))
				{
					Assert.Equal("91b64180c75ef27213398979cc20bfb7", content.GetMD5Hash());
				}
				using (var content = signatureRepository.GetContentForReading(result[1].Name))
				{
					Assert.Equal("9fe9d408aed35769e25ece3a56f2d12f", content.GetMD5Hash());
				}
			}
		}
		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 ContentUpdateWorkItem(string file, string sourceServerUrl, TransactionalStorage storage,
		                             SigGenerator sigGenerator)
			: base(file, sourceServerUrl, storage)
		{
			this.sigGenerator = sigGenerator;
		}
		public void Should_detect_that_different_work_is_being_perfomed()
		{
			using (var sigGenerator = new SigGenerator())
			{
				transactionalStorage.Batch(accessor => accessor.PutFile(FileName, 0, EmptyETagMetadata));

				var contentUpdateWorkItem = new ContentUpdateWorkItem(FileName, "http://localhost:12345", transactionalStorage,
				                                                      sigGenerator);

				queue.EnqueueSynchronization(Destination, contentUpdateWorkItem);
				queue.SynchronizationStarted(contentUpdateWorkItem, Destination);

				Assert.True(queue.IsDifferentWorkForTheSameFileBeingPerformed(
					new RenameWorkItem(FileName, "rename.txt", "http://localhost:12345", transactionalStorage), Destination));
			}
		}
		public SynchronizationStrategy(TransactionalStorage storage, SigGenerator sigGenerator)
		{
			this.storage = storage;
			this.sigGenerator = sigGenerator;
		}