private void TryWriteInputSegment(Stream destination)
        {
            // If there is an available thread && here is data in the input buffer
            if (parallelProcessor.AvailableThreadsExist())
            {
                Segment segmentsBufferSegment = TryGetSegmentsBufferSegment();

                if (segmentsBufferSegment != null)
                {
                    // Write segment in a separate thread
                    parallelProcessor.Process(() =>
                    {
                        // Start writing followed by saving exception if it happens
                        lock (destination) exceptionConsumingSegmentStreamWriter.Write(destination, segmentsBufferSegment);
                    });
                }
            }
        }
        /// <summary>
        /// Writes data from one stream to another using block-by-block algorithm.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        public void Write(Stream source, Stream destination)
        {
            this.source      = source;
            this.destination = destination;

            segmentId = 0;

            parallelProcessor.Process(() => DoBlockByBlockWriting(), configuration.ThreadsCount);

            while (!parallelProcessor.ProcessingFinished())
            {
                ;
            }
        }