public IList<RdcNeed> CreateNeedsList(SignatureInfo seedSignature, SignatureInfo sourceSignature,
		                                      CancellationToken token)
		{
			var result = new List<RdcNeed>();
			using (var seedStream = _seedSignatureRepository.GetContentForReading(seedSignature.Name))
			using (var sourceStream = _sourceSignatureRepository.GetContentForReading(sourceSignature.Name))
			{
				var fileReader = (IRdcFileReader) new RdcFileReader(seedStream);
				IRdcComparator comparator;
				if (_rdcLibrary.CreateComparator(fileReader, ComparatorBufferSize, out comparator) != 0)
					throw new RdcException("Cannot create comparator");

				var inputBuffer = new RdcBufferPointer
					                  {
						                  Size = 0,
						                  Used = 0,
						                  Data = Marshal.AllocCoTaskMem(InputBufferSize + 16)
					                  };

				var outputBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof (RdcNeed))*256);

				try
				{
					var eofInput = false;
					var eofOutput = false;
					var outputPointer = new RdcNeedPointer();

					while (!eofOutput)
					{
						token.ThrowIfCancellationRequested();

						if (inputBuffer.Size == inputBuffer.Used && !eofInput)
						{
							var bytesRead = 0;
							try
							{
								bytesRead = RdcBufferTools.IntPtrCopy(sourceStream, inputBuffer.Data, InputBufferSize);
							}
							catch (Exception ex)
							{
								throw new RdcException("Failed to read from the source stream.", ex);
							}

							inputBuffer.Size = (uint) bytesRead;
							inputBuffer.Used = 0;

							if (bytesRead < InputBufferSize)
							{
								eofInput = true;
							}
						}

						// Initialize our output needs array
						outputPointer.Size = 256;
						outputPointer.Used = 0;
						outputPointer.Data = outputBuffer;

						RdcError error;

						var hr = comparator.Process(eofInput, ref eofOutput, ref inputBuffer, ref outputPointer, out error);

						if (hr != 0)
							throw new RdcException("Failed to process the signature block!", hr, error);

						// Convert the stream to a Needs array.
						var needs = GetRdcNeedList(outputPointer);
						result.AddRange(needs);
					}
				}
				finally
				{
					// Free our resources
					if (outputBuffer != IntPtr.Zero)
						Marshal.FreeCoTaskMem(outputBuffer);

					if (inputBuffer.Data != IntPtr.Zero)
						Marshal.FreeCoTaskMem(inputBuffer.Data);
				}
				return result;
			}
		}
		private static RdcNeed[] GetRdcNeedList(RdcNeedPointer pointer)
		{
			var result = new RdcNeed[pointer.Used];

			var ptr = pointer.Data;
			var needSize = Marshal.SizeOf(typeof (RdcNeed));

			// Get our native needs pointer 
			// and deserialize to our managed 
			// RdcNeed array.
			for (var i = 0; i < result.Length; i++)
			{
				result[i] = (RdcNeed) Marshal.PtrToStructure(ptr, typeof (RdcNeed));

				// Advance the intermediate pointer
				// to our next RdcNeed struct.
				ptr = new IntPtr(ptr.ToInt32() + needSize);
			}
			return result;
		}