public DeflateStream(Stream stream, CompressionMode mode, bool leaveOpen)
        {

            if (stream == null)
                throw new ArgumentNullException("stream");

            if (CompressionMode.Compress != mode && CompressionMode.Decompress != mode)
                throw new ArgumentOutOfRangeException("mode");

            this.BaseStream = stream;
            _mode = mode;
            _leaveOpen = leaveOpen;

            switch (_mode)
            {
                case CompressionMode.Decompress:
                    if (!BaseStream.CanRead)
                        throw new ArgumentException("Stream is not readable.", "stream");

                    _inflater = new Inflater();

                    _callBack = ReadCallback;
                    break;

                case CompressionMode.Compress:
                    if (!BaseStream.CanWrite)
                        throw new ArgumentException("Stream is not writeable", "stream");

                    _deflater = new Deflater();

                    _asyncWriterDelegate = this.InternalWrite;
                    _callBack = WriteCallback;
                    break;

            }

            _buffer = new byte[DefaultBufferSize];
        }
        // Implies mode = Compress
        public DeflateStream(Stream stream, bool leaveOpen)
        {

            if (stream == null)
                throw new ArgumentNullException("stream");

            if (!stream.CanWrite)
                throw new ArgumentException("Stream is not writeable.", "stream");

            this.BaseStream = stream;
            _mode = CompressionMode.Compress;
            _leaveOpen = leaveOpen;

            _deflater = new Deflater();

            _asyncWriterDelegate = this.InternalWrite;
            _callBack = WriteCallback;

            _buffer = new byte[DefaultBufferSize];
        }
        protected override void Dispose(bool disposing)
        {
            try
            {
                this.PurgeBuffers(disposing);
            }
            finally
            {

                // Close the underlying stream even if PurgeBuffers threw.
                // Stream.Close() may throw here (may or may not be due to the same error).
                // In this case, we still need to clean up internal resources, hence the inner finally blocks.
                try
                {

                    if (disposing && !_leaveOpen && BaseStream != null)
                        this.BaseStream.Dispose();

                }
                finally
                {
                    this.BaseStream = null;
                    try
                    {
                        if (_deflater != null)
                            _deflater.Dispose();
                    }
                    finally
                    {
                        _deflater = null;
                        base.Dispose(disposing);
                    }
                }
            } 
        }