/// <summary>
        /// Compress the entirety of the MemoryStream to the destination Stream, or if compressing increases the size, just copy the original data over
        /// </summary>
        /// <param name="uncompressedSource">A MemoryStream that will have its full contents compressed</param>
        /// <param name="compressedDestination">Output Stream to write results to</param>
        /// <param name="compressionKind">Compression Type</param>
        /// <param name="compressionStrategy">The balance of speed vs size for the compressor</param>
        public static void CompressCopyTo(MemoryStream uncompressedSource, IOStream compressedDestination, CompressionKind compressionKind, CompressionStrategy compressionStrategy)
        {
            uncompressedSource.Seek(0, SeekOrigin.Begin);

            if (compressionKind == CompressionKind.None)
            {
                uncompressedSource.CopyTo(compressedDestination);
            }
            else
            {
                var temporaryStream = new MemoryStream();                   //How can we avoid this?? We need to know the length of the compressed stream to write the header before we can write the stream itself...
                using (var compressingStream = CompressionFactory.CreateCompressorStream(compressionKind, compressionStrategy, temporaryStream))
                    uncompressedSource.CopyTo(compressingStream);

                if (temporaryStream.Length >= uncompressedSource.Length)
                {
                    //Write the original data rather than the compressed data
                    uncompressedSource.Seek(0, SeekOrigin.Begin);
                    WriteBlockHeader(compressedDestination, (int)uncompressedSource.Length, false);
                    uncompressedSource.CopyTo(compressedDestination);
                }
                else
                {
                    temporaryStream.Seek(0, SeekOrigin.Begin);
                    WriteBlockHeader(compressedDestination, (int)temporaryStream.Length, true);
                    temporaryStream.CopyTo(compressedDestination);
                }
            }
        }
        /// <summary>
        /// Provides a Stream that when read from, reads consecutive blocks of compressed data from an ORC Stream.
        /// All data in the <paramref name="inputStream"/> will be consumed.
        /// </summary>
        public static IOStream GetDecompressingStream(IOStream inputStream, CompressionKind compressionKind)
        {
            if (compressionKind == CompressionKind.None)
            {
                return(inputStream);
            }
            else
            {
                return(new ConcatenatingStream(() =>
                {
                    int blockLength;
                    bool isCompressed;
                    bool headerAvailable = ReadBlockHeader(inputStream, out blockLength, out isCompressed);
                    if (!headerAvailable)
                    {
                        return null;
                    }

                    var streamSegment = new StreamSegment(inputStream, blockLength, true);

                    if (!isCompressed)
                    {
                        return streamSegment;
                    }
                    else
                    {
                        return CompressionFactory.CreateDecompressorStream(compressionKind, streamSegment);
                    }
                }, false));
            }
        }