private Int32 ExtractOne(Stream output)
        {
            Int32 CrcResult = 0;
            Stream input = this.ArchiveStream;

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

                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.None)
                    ? 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 Crisis.Ionic.Crc.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;
                }
            }
            finally
            {
                var zss = input as ZipSegmentedStream;
                if (zss != null)
                {
#if NETCF
                    zss.Close();
#else
                    // need to dispose it
                    zss.Dispose();
#endif
                    _archiveStream = null;
                }
            }

            return CrcResult;
        }