private Int32 _ExtractOne(Stream output)
        {
            Stream input = this.ArchiveStream;

            // change for workitem 8098
            input.Seek(this.FileDataPosition, SeekOrigin.Begin);
            // workitem 10178
            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(input);

            // to validate the CRC.
            Int32 CrcResult = 0;

            byte[] bytes = new byte[BufferSize];

            // The extraction process varies depending on how the entry was stored.
            // It could have been encrypted, and it coould have been compressed, or both, or
            // neither. So we need to check both the encryption flag and the compression flag,
            // and take the proper action in all cases.

            Int64 LeftToRead = (_CompressionMethod_FromZipFile == (short)CompressionMethod.Deflate)
                ? this.UncompressedSize
                : this._CompressedFileDataSize;

            // Get a stream that either decrypts or not.
            _inputDecryptorStream = GetExtractDecryptor(input);

            Stream input3 = GetExtractDecompressor( _inputDecryptorStream );

            Int64 bytesWritten = 0;
            // As we read, we maybe decrypt, and then we maybe decompress. Then we write.
            using (var s1 = new Ionic.Zlib.CrcCalculatorStream(input3))
            {
                while (LeftToRead > 0)
                {
                    //Console.WriteLine("ExtractOne: LeftToRead {0}", LeftToRead);

                    // Casting LeftToRead down to an int is ok here in the else clause,
                    // because that only happens when it is less than bytes.Length,
                    // which is much less than MAX_INT.
                    int len = (LeftToRead > bytes.Length) ? bytes.Length : (int)LeftToRead;
                    int n = s1.Read(bytes, 0, len);

                    // must check data read - essential for detecting corrupt zip files
                    _CheckRead(n);

                    output.Write(bytes, 0, n);
                    LeftToRead -= n;
                    bytesWritten += n;

                    // fire the progress event, check for cancels
                    OnExtractProgress(bytesWritten, UncompressedSize);
                    if (_ioOperationCanceled)
                    {
                        break;
                    }
                }

                CrcResult = s1.Crc;
            }

            return CrcResult;
        }