// ZipOutputStream.cs
//
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2011-July-28 06:34:30>
//
// ------------------------------------------------------------------
//
// This module defines the ZipOutputStream class, which is a stream metaphor for
// generating zip files.  This class does not depend on Ionic.Zip.ZipFile, but rather
// stands alongside it as an alternative "container" for ZipEntry.  It replicates a
// subset of the properties, including these:
//
//  - Comment
//  - Encryption
//  - Password
//  - CodecBufferSize
//  - CompressionLevel
//  - CompressionMethod
//  - EnableZip64 (UseZip64WhenSaving)
//  - IgnoreCase (!CaseSensitiveRetrieval)
//
// It adds these novel methods:
//
//  - PutNextEntry
//
//
// ------------------------------------------------------------------
//

using System;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using Ionic.Zip;
using OfficeOpenXml.Packaging.Ionic.Zlib;

namespace OfficeOpenXml.Packaging.Ionic.Zip
{
    /// <summary>
    ///   Provides a stream metaphor for generating zip files.
    /// </summary>
    ///
    /// <remarks>
    /// <para>
    ///   This class writes zip files, as defined in the <see
    ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">specification
    ///   for zip files described by PKWare</see>.  The compression for this
    ///   implementation is provided by a managed-code version of Zlib, included with
    ///   DotNetZip in the classes in the Ionic.Zlib namespace.
    /// </para>
    ///
    /// <para>
    ///   This class provides an alternative programming model to the one enabled by the
    ///   <see cref="ZipFile"/> class. Use this when creating zip files, as an
    ///   alternative to the <see cref="ZipFile"/> class, when you would like to use a
    ///   <c>Stream</c> type to write the zip file.
    /// </para>
    ///
    /// <para>
    ///   Both the <c>ZipOutputStream</c> class and the <c>ZipFile</c> class can be used
    ///   to create zip files. Both of them support many of the common zip features,
    ///   including Unicode, different compression levels, and ZIP64.   They provide
    ///   very similar performance when creating zip files.
    /// </para>
    ///
    /// <para>
    ///   The <c>ZipFile</c> class is generally easier to use than
    ///   <c>ZipOutputStream</c> and should be considered a higher-level interface.  For
    ///   example, when creating a zip file via calls to the <c>PutNextEntry()</c> and
    ///   <c>Write()</c> methods on the <c>ZipOutputStream</c> class, the caller is
    ///   responsible for opening the file, reading the bytes from the file, writing
    ///   those bytes into the <c>ZipOutputStream</c>, setting the attributes on the
    ///   <c>ZipEntry</c>, and setting the created, last modified, and last accessed
    ///   timestamps on the zip entry. All of these things are done automatically by a
    ///   call to <see cref="ZipFile.AddFile(string,string)">ZipFile.AddFile()</see>.
    ///   For this reason, the <c>ZipOutputStream</c> is generally recommended for use
    ///   only when your application emits arbitrary data, not necessarily data from a
    ///   filesystem file, directly into a zip file, and does so using a <c>Stream</c>
    ///   metaphor.
    /// </para>
    ///
    /// <para>
    ///   Aside from the differences in programming model, there are other
    ///   differences in capability between the two classes.
    /// </para>
    ///
    /// <list type="bullet">
    ///   <item>
    ///     <c>ZipFile</c> can be used to read and extract zip files, in addition to
    ///     creating zip files. <c>ZipOutputStream</c> cannot read zip files. If you want
    ///     to use a stream to read zip files, check out the <see cref="ZipInputStream"/> class.
    ///   </item>
    ///
    ///   <item>
    ///     <c>ZipOutputStream</c> does not support the creation of segmented or spanned
    ///     zip files.
    ///   </item>
    ///
    ///   <item>
    ///     <c>ZipOutputStream</c> cannot produce a self-extracting archive.
    ///   </item>
    /// </list>
    ///
    /// <para>
    ///   Be aware that the <c>ZipOutputStream</c> class implements the <see
    ///   cref="System.IDisposable"/> interface.  In order for
    ///   <c>ZipOutputStream</c> to produce a valid zip file, you use use it within
    ///   a using clause (<c>Using</c> in VB), or call the <c>Dispose()</c> method
    ///   explicitly.  See the examples for how to employ a using clause.
    /// </para>
    ///
    /// <para>
    ///   Also, a note regarding compression performance: On the desktop .NET
    ///   Framework, DotNetZip can use a multi-threaded compression implementation
    ///   that provides significant speed increases on large files, over 300k or so,
    ///   at the cost of increased memory use at runtime.  (The output of the
    ///   compression is almost exactly the same size).  But, the multi-threaded
    ///   approach incurs a performance hit on smaller files. There's no way for the
    ///   ZipOutputStream to know whether parallel compression will be beneficial,
    ///   because the ZipOutputStream does not know how much data you will write
    ///   through the stream.  You may wish to set the <see
    ///   cref="ParallelDeflateThreshold"/> property to zero, if you are compressing
    ///   large files through <c>ZipOutputStream</c>.  This will cause parallel
    ///   compression to be used, always.
    /// </para>
    /// </remarks>
    internal class ZipOutputStream : Stream
    {
        /// <summary>
        ///   Create a ZipOutputStream, wrapping an existing stream.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   The <see cref="ZipFile"/> class is generally easier to use when creating
        ///   zip files. The ZipOutputStream offers a different metaphor for creating a
        ///   zip file, based on the <see cref="System.IO.Stream"/> class.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <param name="stream">
        /// The stream to wrap. It must be writable. This stream will be closed at
        /// the time the ZipOutputStream is closed.
        /// </param>
        ///
        /// <example>
        ///
        ///   This example shows how to create a zip file, using the
        ///   ZipOutputStream class.
        ///
        /// <code lang="C#">
        /// private void Zipup()
        /// {
        ///     if (filesToZip.Count == 0)
        ///     {
        ///         System.Console.WriteLine("Nothing to do.");
        ///         return;
        ///     }
        ///
        ///     using (var raw = File.Open(_outputFileName, FileMode.Create, FileAccess.ReadWrite ))
        ///     {
        ///         using (var output= new ZipOutputStream(raw))
        ///         {
        ///             output.Password = "VerySecret!";
        ///             output.Encryption = EncryptionAlgorithm.WinZipAes256;
        ///
        ///             foreach (string inputFileName in filesToZip)
        ///             {
        ///                 System.Console.WriteLine("file: {0}", inputFileName);
        ///
        ///                 output.PutNextEntry(inputFileName);
        ///                 using (var input = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write ))
        ///                 {
        ///                     byte[] buffer= new byte[2048];
        ///                     int n;
        ///                     while ((n= input.Read(buffer,0,buffer.Length)) > 0)
        ///                     {
        ///                         output.Write(buffer,0,n);
        ///                     }
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Private Sub Zipup()
        ///     Dim outputFileName As String = "XmlData.zip"
        ///     Dim filesToZip As String() = Directory.GetFiles(".", "*.xml")
        ///     If (filesToZip.Length = 0) Then
        ///         Console.WriteLine("Nothing to do.")
        ///     Else
        ///         Using raw As FileStream = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite)
        ///             Using output As ZipOutputStream = New ZipOutputStream(raw)
        ///                 output.Password = "VerySecret!"
        ///                 output.Encryption = EncryptionAlgorithm.WinZipAes256
        ///                 Dim inputFileName As String
        ///                 For Each inputFileName In filesToZip
        ///                     Console.WriteLine("file: {0}", inputFileName)
        ///                     output.PutNextEntry(inputFileName)
        ///                     Using input As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        ///                         Dim n As Integer
        ///                         Dim buffer As Byte() = New Byte(2048) {}
        ///                         Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
        ///                             output.Write(buffer, 0, n)
        ///                         Loop
        ///                     End Using
        ///                 Next
        ///             End Using
        ///         End Using
        ///     End If
        /// End Sub
        /// </code>
        /// </example>
        public ZipOutputStream(Stream stream) : this(stream, false) { }


        /// <summary>
        ///   Create a ZipOutputStream that writes to a filesystem file.
        /// </summary>
        ///
        /// <remarks>
        ///   The <see cref="ZipFile"/> class is generally easier to use when creating
        ///   zip files. The ZipOutputStream offers a different metaphor for creating a
        ///   zip file, based on the <see cref="System.IO.Stream"/> class.
        /// </remarks>
        ///
        /// <param name="fileName">
        ///   The name of the zip file to create.
        /// </param>
        ///
        /// <example>
        ///
        ///   This example shows how to create a zip file, using the
        ///   ZipOutputStream class.
        ///
        /// <code lang="C#">
        /// private void Zipup()
        /// {
        ///     if (filesToZip.Count == 0)
        ///     {
        ///         System.Console.WriteLine("Nothing to do.");
        ///         return;
        ///     }
        ///
        ///     using (var output= new ZipOutputStream(outputFileName))
        ///     {
        ///         output.Password = "VerySecret!";
        ///         output.Encryption = EncryptionAlgorithm.WinZipAes256;
        ///
        ///         foreach (string inputFileName in filesToZip)
        ///         {
        ///             System.Console.WriteLine("file: {0}", inputFileName);
        ///
        ///             output.PutNextEntry(inputFileName);
        ///             using (var input = File.Open(inputFileName, FileMode.Open, FileAccess.Read,
        ///                                          FileShare.Read | FileShare.Write ))
        ///             {
        ///                 byte[] buffer= new byte[2048];
        ///                 int n;
        ///                 while ((n= input.Read(buffer,0,buffer.Length)) > 0)
        ///                 {
        ///                     output.Write(buffer,0,n);
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Private Sub Zipup()
        ///     Dim outputFileName As String = "XmlData.zip"
        ///     Dim filesToZip As String() = Directory.GetFiles(".", "*.xml")
        ///     If (filesToZip.Length = 0) Then
        ///         Console.WriteLine("Nothing to do.")
        ///     Else
        ///         Using output As ZipOutputStream = New ZipOutputStream(outputFileName)
        ///             output.Password = "VerySecret!"
        ///             output.Encryption = EncryptionAlgorithm.WinZipAes256
        ///             Dim inputFileName As String
        ///             For Each inputFileName In filesToZip
        ///                 Console.WriteLine("file: {0}", inputFileName)
        ///                 output.PutNextEntry(inputFileName)
        ///                 Using input As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        ///                     Dim n As Integer
        ///                     Dim buffer As Byte() = New Byte(2048) {}
        ///                     Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
        ///                         output.Write(buffer, 0, n)
        ///                     Loop
        ///                 End Using
        ///             Next
        ///         End Using
        ///     End If
        /// End Sub
        /// </code>
        /// </example>
        public ZipOutputStream(String fileName)
        {
            Stream stream = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            _Init(stream, false, fileName);
        }


        /// <summary>
        ///   Create a ZipOutputStream.
        /// </summary>
        ///
        /// <remarks>
        ///   See the documentation for the <see
        ///   cref="ZipOutputStream(Stream)">ZipOutputStream(Stream)</see>
        ///   constructor for an example.
        /// </remarks>
        ///
        /// <param name="stream">
        ///   The stream to wrap. It must be writable.
        /// </param>
        ///
        /// <param name="leaveOpen">
        ///   true if the application would like the stream
        ///   to remain open after the <c>ZipOutputStream</c> has been closed.
        /// </param>
        public ZipOutputStream(Stream stream, bool leaveOpen)
        {
            _Init(stream, leaveOpen, null);
        }

        private void _Init(Stream stream, bool leaveOpen, string name)
        {
            // workitem 9307
            _outputStream = stream.CanRead ? stream : new CountingStream(stream);
            CompressionLevel = OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.Default;
            CompressionMethod = OfficeOpenXml.Packaging.Ionic.Zip.CompressionMethod.Deflate;
            _encryption = EncryptionAlgorithm.None;
            _entriesWritten = new Dictionary<String, ZipEntry>(StringComparer.Ordinal);
            _zip64 = Zip64Option.Never;
            _leaveUnderlyingStreamOpen = leaveOpen;
            Strategy = Ionic.Zlib.CompressionStrategy.Default;
            _name = name ?? "(stream)";
#if !NETCF
            ParallelDeflateThreshold = -1L;
#endif
        }


        /// <summary>Provides a string representation of the instance.</summary>
        /// <remarks>
        ///   <para>
        ///     This can be useful for debugging purposes.
        ///   </para>
        /// </remarks>
        /// <returns>a string representation of the instance.</returns>
        public override String ToString()
        {
            return String.Format ("ZipOutputStream::{0}(leaveOpen({1})))", _name, _leaveUnderlyingStreamOpen);
        }


        /// <summary>
        ///   Sets the password to be used on the <c>ZipOutputStream</c> instance.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        ///   When writing a zip archive, this password is applied to the entries, not
        ///   to the zip archive itself. It applies to any <c>ZipEntry</c> subsequently
        ///   written to the <c>ZipOutputStream</c>.
        /// </para>
        ///
        /// <para>
        ///   Using a password does not encrypt or protect the "directory" of the
        ///   archive - the list of entries contained in the archive.  If you set the
        ///   <c>Password</c> property, the password actually applies to individual
        ///   entries that are added to the archive, subsequent to the setting of this
        ///   property.  The list of filenames in the archive that is eventually created
        ///   will appear in clear text, but the contents of the individual files are
        ///   encrypted.  This is how Zip encryption works.
        /// </para>
        ///
        /// <para>
        ///   If you set this property, and then add a set of entries to the archive via
        ///   calls to <c>PutNextEntry</c>, then each entry is encrypted with that
        ///   password.  You may also want to change the password between adding
        ///   different entries. If you set the password, add an entry, then set the
        ///   password to <c>null</c> (<c>Nothing</c> in VB), and add another entry, the
        ///   first entry is encrypted and the second is not.
        /// </para>
        ///
        /// <para>
        ///   When setting the <c>Password</c>, you may also want to explicitly set the <see
        ///   cref="Encryption"/> property, to specify how to encrypt the entries added
        ///   to the ZipFile.  If you set the <c>Password</c> to a non-null value and do not
        ///   set <see cref="Encryption"/>, then PKZip 2.0 ("Weak") encryption is used.
        ///   This encryption is relatively weak but is very interoperable. If
        ///   you set the password to a <c>null</c> value (<c>Nothing</c> in VB),
        ///   <c>Encryption</c> is reset to None.
        /// </para>
        ///
        /// <para>
        ///   Special case: if you wrap a ZipOutputStream around a non-seekable stream,
        ///   and use encryption, and emit an entry of zero bytes, the <c>Close()</c> or
        ///   <c>PutNextEntry()</c> following the entry will throw an exception.
        /// </para>
        ///
        /// </remarks>
        public String Password
        {
            set
            {
                if (_disposed)
                {
                    _exceptionPending = true;
                    throw new System.InvalidOperationException("The stream has been closed.");
                }

                _password = value;
                if (_password == null)
                {
                    _encryption = EncryptionAlgorithm.None;
                }
                else if (_encryption == EncryptionAlgorithm.None)
                {
                    _encryption = EncryptionAlgorithm.PkzipWeak;
                }
            }
        }


        /// <summary>
        ///   The Encryption to use for entries added to the <c>ZipOutputStream</c>.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   The specified Encryption is applied to the entries subsequently
        ///   written to the <c>ZipOutputStream</c> instance.
        /// </para>
        ///
        /// <para>
        ///   If you set this to something other than
        ///   EncryptionAlgorithm.None, you will also need to set the
        ///   <see cref="Password"/> to a non-null, non-empty value in
        ///   order to actually get encryption on the entry.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <seealso cref="Password">ZipOutputStream.Password</seealso>
        /// <seealso cref="ZipEntry.Encryption">ZipEntry.Encryption</seealso>
        public EncryptionAlgorithm Encryption
        {
            get
            {
                return _encryption;
            }
            set
            {
                if (_disposed)
                {
                    _exceptionPending = true;
                    throw new System.InvalidOperationException("The stream has been closed.");
                }
                if (value == EncryptionAlgorithm.Unsupported)
                {
                    _exceptionPending = true;
                    throw new InvalidOperationException("You may not set Encryption to that value.");
                }
                _encryption = value;
            }
        }


        /// <summary>
        ///   Size of the work buffer to use for the ZLIB codec during compression.
        /// </summary>
        ///
        /// <remarks>
        ///   Setting this may affect performance.  For larger files, setting this to a
        ///   larger size may improve performance, but I'm not sure.  Sorry, I don't
        ///   currently have good recommendations on how to set it.  You can test it if
        ///   you like.
        /// </remarks>
        public int CodecBufferSize
        {
            get;
            set;
        }


        /// <summary>
        ///   The compression strategy to use for all entries.
        /// </summary>
        ///
        /// <remarks>
        ///   Set the Strategy used by the ZLIB-compatible compressor, when compressing
        ///   data for the entries in the zip archive. Different compression strategies
        ///   work better on different sorts of data. The strategy parameter can affect
        ///   the compression ratio and the speed of compression but not the correctness
        ///   of the compresssion.  For more information see <see
        ///   cref="Ionic.Zlib.CompressionStrategy "/>.
        /// </remarks>
        public CompressionStrategy Strategy
        {
            get;
            set;
        }


        /// <summary>
        ///   The type of timestamp attached to the ZipEntry.
        /// </summary>
        ///
        /// <remarks>
        ///   Set this in order to specify the kind of timestamp that should be emitted
        ///   into the zip file for each entry.
        /// </remarks>
        public ZipEntryTimestamp Timestamp
        {
            get
            {
                return _timestamp;
            }
            set
            {
                if (_disposed)
                {
                    _exceptionPending = true;
                    throw new System.InvalidOperationException("The stream has been closed.");
                }
                _timestamp = value;
            }
        }


        /// <summary>
        ///   Sets the compression level to be used for entries subsequently added to
        ///   the zip archive.
        /// </summary>
        ///
        /// <remarks>
        ///  <para>
        ///    Varying the compression level used on entries can affect the
        ///    size-vs-speed tradeoff when compression and decompressing data streams
        ///    or files.
        ///  </para>
        ///
        ///  <para>
        ///    As with some other properties on the <c>ZipOutputStream</c> class, like <see
        ///    cref="Password"/>, and <see cref="Encryption"/>,
        ///    setting this property on a <c>ZipOutputStream</c>
        ///    instance will cause the specified <c>CompressionLevel</c> to be used on all
        ///    <see cref="ZipEntry"/> items that are subsequently added to the
        ///    <c>ZipOutputStream</c> instance.
        ///  </para>
        ///
        ///  <para>
        ///    If you do not set this property, the default compression level is used,
        ///    which normally gives a good balance of compression efficiency and
        ///    compression speed.  In some tests, using <c>BestCompression</c> can
        ///    double the time it takes to compress, while delivering just a small
        ///    increase in compression efficiency.  This behavior will vary with the
        ///    type of data you compress.  If you are in doubt, just leave this setting
        ///    alone, and accept the default.
        ///  </para>
        /// </remarks>
        public OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel CompressionLevel
        {
            get;
            set;
        }

        /// <summary>
        ///   The compression method used on each entry added to the ZipOutputStream.
        /// </summary>
        public CompressionMethod CompressionMethod
        {
            get;
            set;
        }


        /// <summary>
        ///   A comment attached to the zip archive.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        ///   The application sets this property to specify a comment to be embedded
        ///   into the generated zip archive.
        /// </para>
        ///
        /// <para>
        ///   According to <see
        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
        ///   zip specification</see>, the comment is not encrypted, even if there is a
        ///   password set on the zip file.
        /// </para>
        ///
        /// <para>
        ///   The specification does not describe how to indicate the encoding used
        ///   on a comment string. Many "compliant" zip tools and libraries use
        ///   IBM437 as the code page for comments; DotNetZip, too, follows that
        ///   practice.  On the other hand, there are situations where you want a
        ///   Comment to be encoded with something else, for example using code page
        ///   950 "Big-5 Chinese". To fill that need, DotNetZip will encode the
        ///   comment following the same procedure it follows for encoding
        ///   filenames: (a) if <see cref="AlternateEncodingUsage"/> is
        ///   <c>Never</c>, it uses the default encoding (IBM437). (b) if <see
        ///   cref="AlternateEncodingUsage"/> is <c>Always</c>, it always uses the
        ///   alternate encoding (<see cref="AlternateEncoding"/>). (c) if <see
        ///   cref="AlternateEncodingUsage"/> is <c>AsNecessary</c>, it uses the
        ///   alternate encoding only if the default encoding is not sufficient for
        ///   encoding the comment - in other words if decoding the result does not
        ///   produce the original string.  This decision is taken at the time of
        ///   the call to <c>ZipFile.Save()</c>.
        /// </para>
        ///
        /// </remarks>
        public string Comment
        {
            get { return _comment; }
            set
            {
                if (_disposed)
                {
                    _exceptionPending = true;
                    throw new System.InvalidOperationException("The stream has been closed.");
                }
                _comment = value;
            }
        }



        /// <summary>
        ///   Specify whether to use ZIP64 extensions when saving a zip archive.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   The default value for the property is <see
        ///   cref="Zip64Option.Never"/>. <see cref="Zip64Option.AsNecessary"/> is
        ///   safest, in the sense that you will not get an Exception if a
        ///   pre-ZIP64 limit is exceeded.
        /// </para>
        ///
        /// <para>
        ///   You must set this property before calling <c>Write()</c>.
        /// </para>
        ///
        /// </remarks>
        public Zip64Option EnableZip64
        {
            get
            {
                return _zip64;
            }
            set
            {
                if (_disposed)
                {
                    _exceptionPending = true;
                    throw new System.InvalidOperationException("The stream has been closed.");
                }
                _zip64 = value;
            }
        }


        /// <summary>
        ///   Indicates whether ZIP64 extensions were used when saving the zip archive.
        /// </summary>
        ///
        /// <remarks>
        ///   The value is defined only after the <c>ZipOutputStream</c> has been closed.
        /// </remarks>
        public bool OutputUsedZip64
        {
            get
            {
                return _anyEntriesUsedZip64 || _directoryNeededZip64;
            }
        }


        /// <summary>
        ///   Whether the ZipOutputStream should use case-insensitive comparisons when
        ///   checking for uniqueness of zip entries.
        /// </summary>
        ///
        /// <remarks>
        ///   <para>
        ///   Though the zip specification doesn't prohibit zipfiles with duplicate
        ///   entries, Sane zip files have no duplicates, and the DotNetZip library
        ///   cannot create zip files with duplicate entries. If an application attempts
        ///   to call <see cref="PutNextEntry(String)"/> with a name that duplicates one
        ///   already used within the archive, the library will throw an Exception.
        ///   </para>
        ///   <para>
        ///   This property allows the application to specify whether the
        ///   ZipOutputStream instance considers ordinal case when checking for
        ///   uniqueness of zip entries.
        ///   </para>
        /// </remarks>
        public bool IgnoreCase
        {
          get
          {
              return !_DontIgnoreCase;
          }

          set
          {
              _DontIgnoreCase = !value;
          }

        }


        /// <summary>
        ///   Indicates whether to encode entry filenames and entry comments using
        ///   Unicode (UTF-8).
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   <see href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">The
        ///   PKWare zip specification</see> provides for encoding file names and file
        ///   comments in either the IBM437 code page, or in UTF-8.  This flag selects
        ///   the encoding according to that specification.  By default, this flag is
        ///   false, and filenames and comments are encoded into the zip file in the
        ///   IBM437 codepage.  Setting this flag to true will specify that filenames
        ///   and comments that cannot be encoded with IBM437 will be encoded with
        ///   UTF-8.
        /// </para>
        ///
        /// <para>
        ///   Zip files created with strict adherence to the PKWare specification with
        ///   respect to UTF-8 encoding can contain entries with filenames containing
        ///   any combination of Unicode characters, including the full range of
        ///   characters from Chinese, Latin, Hebrew, Greek, Cyrillic, and many other
        ///   alphabets.  However, because at this time, the UTF-8 portion of the PKWare
        ///   specification is not broadly supported by other zip libraries and
        ///   utilities, such zip files may not be readable by your favorite zip tool or
        ///   archiver. In other words, interoperability will decrease if you set this
        ///   flag to true.
        /// </para>
        ///
        /// <para>
        ///   In particular, Zip files created with strict adherence to the PKWare
        ///   specification with respect to UTF-8 encoding will not work well with
        ///   Explorer in Windows XP or Windows Vista, because Windows compressed
        ///   folders, as far as I know, do not support UTF-8 in zip files.  Vista can
        ///   read the zip files, but shows the filenames incorrectly. Unpacking from
        ///   Windows Vista Explorer will result in filenames that have rubbish
        ///   characters in place of the high-order UTF-8 bytes.
        /// </para>
        ///
        /// <para>
        ///   Also, zip files that use UTF-8 encoding will not work well with Java
        ///   applications that use the java.util.zip classes, as of v5.0 of the Java
        ///   runtime. The Java runtime does not correctly implement the PKWare
        ///   specification in this regard.
        /// </para>
        ///
        /// <para>
        ///   As a result, we have the unfortunate situation that "correct" behavior by
        ///   the DotNetZip library with regard to Unicode encoding of filenames during
        ///   zip creation will result in zip files that are readable by strictly
        ///   compliant and current tools (for example the most recent release of the
        ///   commercial WinZip tool); but these zip files will not be readable by
        ///   various other tools or libraries, including Windows Explorer.
        /// </para>
        ///
        /// <para>
        ///   The DotNetZip library can read and write zip files with UTF8-encoded
        ///   entries, according to the PKware spec.  If you use DotNetZip for both
        ///   creating and reading the zip file, and you use UTF-8, there will be no
        ///   loss of information in the filenames. For example, using a self-extractor
        ///   created by this library will allow you to unpack files correctly with no
        ///   loss of information in the filenames.
        /// </para>
        ///
        /// <para>
        ///   If you do not set this flag, it will remain false.  If this flag is false,
        ///   the <c>ZipOutputStream</c> will encode all filenames and comments using
        ///   the IBM437 codepage.  This can cause "loss of information" on some
        ///   filenames, but the resulting zipfile will be more interoperable with other
        ///   utilities. As an example of the loss of information, diacritics can be
        ///   lost.  The o-tilde character will be down-coded to plain o.  The c with a
        ///   cedilla (Unicode 0xE7) used in Portugese will be downcoded to a c.
        ///   Likewise, the O-stroke character (Unicode 248), used in Danish and
        ///   Norwegian, will be down-coded to plain o. Chinese characters cannot be
        ///   represented in codepage IBM437; when using the default encoding, Chinese
        ///   characters in filenames will be represented as ?. These are all examples
        ///   of "information loss".
        /// </para>
        ///
        /// <para>
        ///   The loss of information associated to the use of the IBM437 encoding is
        ///   inconvenient, and can also lead to runtime errors. For example, using
        ///   IBM437, any sequence of 4 Chinese characters will be encoded as ????.  If
        ///   your application creates a <c>ZipOutputStream</c>, does not set the
        ///   encoding, then adds two files, each with names of four Chinese characters
        ///   each, this will result in a duplicate filename exception.  In the case
        ///   where you add a single file with a name containing four Chinese
        ///   characters, the zipfile will save properly, but extracting that file
        ///   later, with any zip tool, will result in an error, because the question
        ///   mark is not legal for use within filenames on Windows.  These are just a
        ///   few examples of the problems associated to loss of information.
        /// </para>
        ///
        /// <para>
        ///   This flag is independent of the encoding of the content within the entries
        ///   in the zip file. Think of the zip file as a container - it supports an
        ///   encoding.  Within the container are other "containers" - the file entries
        ///   themselves.  The encoding within those entries is independent of the
        ///   encoding of the zip archive container for those entries.
        /// </para>
        ///
        /// <para>
        ///   Rather than specify the encoding in a binary fashion using this flag, an
        ///   application can specify an arbitrary encoding via the <see
        ///   cref="ProvisionalAlternateEncoding"/> property.  Setting the encoding
        ///   explicitly when creating zip archives will result in non-compliant zip
        ///   files that, curiously, are fairly interoperable.  The challenge is, the
        ///   PKWare specification does not provide for a way to specify that an entry
        ///   in a zip archive uses a code page that is neither IBM437 nor UTF-8.
        ///   Therefore if you set the encoding explicitly when creating a zip archive,
        ///   you must take care upon reading the zip archive to use the same code page.
        ///   If you get it wrong, the behavior is undefined and may result in incorrect
        ///   filenames, exceptions, stomach upset, hair loss, and acne.
        /// </para>
        /// </remarks>
        /// <seealso cref="ProvisionalAlternateEncoding"/>
        [Obsolete("Beginning with v1.9.1.6 of DotNetZip, this property is obsolete. It will be removed in a future version of the library. Use AlternateEncoding and AlternateEncodingUsage instead.")]
        public bool UseUnicodeAsNecessary
        {
            get
            {
                return (_alternateEncoding == System.Text.Encoding.UTF8) &&
                    (AlternateEncodingUsage == ZipOption.AsNecessary);
            }
            set
            {
                if (value)
                {
                    _alternateEncoding = System.Text.Encoding.UTF8;
                    _alternateEncodingUsage = ZipOption.AsNecessary;

                }
                else
                {
                    _alternateEncoding = Ionic.Zip.ZipOutputStream.DefaultEncoding;
                    _alternateEncodingUsage = ZipOption.Never;
                }
            }
        }


        /// <summary>
        ///   The text encoding to use when emitting entries into the zip archive, for
        ///   those entries whose filenames or comments cannot be encoded with the
        ///   default (IBM437) encoding.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   In <see href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">its
        ///   zip specification</see>, PKWare describes two options for encoding
        ///   filenames and comments: using IBM437 or UTF-8.  But, some archiving tools
        ///   or libraries do not follow the specification, and instead encode
        ///   characters using the system default code page.  For example, WinRAR when
        ///   run on a machine in Shanghai may encode filenames with the Big-5 Chinese
        ///   (950) code page.  This behavior is contrary to the Zip specification, but
        ///   it occurs anyway.
        /// </para>
        ///
        /// <para>
        ///   When using DotNetZip to write zip archives that will be read by one of
        ///   these other archivers, set this property to specify the code page to use
        ///   when encoding the <see cref="ZipEntry.FileName"/> and <see
        ///   cref="ZipEntry.Comment"/> for each <c>ZipEntry</c> in the zip file, for
        ///   values that cannot be encoded with the default codepage for zip files,
        ///   IBM437.  This is why this property is "provisional".  In all cases, IBM437
        ///   is used where possible, in other words, where no loss of data would
        ///   result. It is possible, therefore, to have a given entry with a
        ///   <c>Comment</c> encoded in IBM437 and a <c>FileName</c> encoded with the
        ///   specified "provisional" codepage.
        /// </para>
        ///
        /// <para>
        ///   Be aware that a zip file created after you've explicitly set the
        ///   <c>ProvisionalAlternateEncoding</c> property to a value other than
        ///   IBM437 may not be compliant to the PKWare specification, and may not be
        ///   readable by compliant archivers.  On the other hand, many (most?)
        ///   archivers are non-compliant and can read zip files created in arbitrary
        ///   code pages.  The trick is to use or specify the proper codepage when
        ///   reading the zip.
        /// </para>
        ///
        /// <para>
        ///   When creating a zip archive using this library, it is possible to change
        ///   the value of <c>ProvisionalAlternateEncoding</c> between each entry you
        ///   add, and between adding entries and the call to <c>Close()</c>. Don't do
        ///   this. It will likely result in a zipfile that is not readable.  For best
        ///   interoperability, either leave <c>ProvisionalAlternateEncoding</c>
        ///   alone, or specify it only once, before adding any entries to the
        ///   <c>ZipOutputStream</c> instance.  There is one exception to this
        ///   recommendation, described later.
        /// </para>
        ///
        /// <para>
        ///   When using an arbitrary, non-UTF8 code page for encoding, there is no
        ///   standard way for the creator application - whether DotNetZip, WinZip,
        ///   WinRar, or something else - to formally specify in the zip file which
        ///   codepage has been used for the entries. As a result, readers of zip files
        ///   are not able to inspect the zip file and determine the codepage that was
        ///   used for the entries contained within it.  It is left to the application
        ///   or user to determine the necessary codepage when reading zip files encoded
        ///   this way.  If you use an incorrect codepage when reading a zipfile, you
        ///   will get entries with filenames that are incorrect, and the incorrect
        ///   filenames may even contain characters that are not legal for use within
        ///   filenames in Windows. Extracting entries with illegal characters in the
        ///   filenames will lead to exceptions. It's too bad, but this is just the way
        ///   things are with code pages in zip files. Caveat Emptor.
        /// </para>
        ///
        /// <para>
        ///   One possible approach for specifying the code page for a given zip file is
        ///   to describe the code page in a human-readable form in the Zip comment. For
        ///   example, the comment may read "Entries in this archive are encoded in the
        ///   Big5 code page".  For maximum interoperability, the zip comment in this
        ///   case should be encoded in the default, IBM437 code page.  In this case,
        ///   the zip comment is encoded using a different page than the filenames.  To
        ///   do this, Specify <c>ProvisionalAlternateEncoding</c> to your desired
        ///   region-specific code page, once before adding any entries, and then set
        ///   the <see cref="Comment"/> property and reset
        ///   <c>ProvisionalAlternateEncoding</c> to IBM437 before calling <c>Close()</c>.
        /// </para>
        /// </remarks>
        [Obsolete("use AlternateEncoding and AlternateEncodingUsage instead.")]
        public System.Text.Encoding ProvisionalAlternateEncoding
        {
            get
            {
                if (_alternateEncodingUsage == ZipOption.AsNecessary)
                    return _alternateEncoding;
                return null;
            }
            set
            {
                _alternateEncoding = value;
                _alternateEncodingUsage = ZipOption.AsNecessary;
            }
        }

        /// <summary>
        ///   A Text Encoding to use when encoding the filenames and comments for
        ///   all the ZipEntry items, during a ZipFile.Save() operation.
        /// </summary>
        /// <remarks>
        ///   <para>
        ///     Whether the encoding specified here is used during the save depends
        ///     on <see cref="AlternateEncodingUsage"/>.
        ///   </para>
        /// </remarks>
        public System.Text.Encoding AlternateEncoding
        {
            get
            {
                return _alternateEncoding;
            }
            set
            {
                _alternateEncoding = value;
            }
        }

        /// <summary>
        ///   A flag that tells if and when this instance should apply
        ///   AlternateEncoding to encode the filenames and comments associated to
        ///   of ZipEntry objects contained within this instance.
        /// </summary>
        public ZipOption AlternateEncodingUsage
        {
            get
            {
                return _alternateEncodingUsage;
            }
            set
            {
                _alternateEncodingUsage = value;
            }
        }

        /// <summary>
        /// The default text encoding used in zip archives.  It is numeric 437, also
        /// known as IBM437.
        /// </summary>
        /// <seealso cref="Ionic.Zip.ZipFile.ProvisionalAlternateEncoding"/>
        public static System.Text.Encoding DefaultEncoding
        {
            get
            {
                return System.Text.Encoding.GetEncoding("IBM437");
            }
        }


#if !NETCF
        /// <summary>
        ///   The size threshold for an entry, above which a parallel deflate is used.
        /// </summary>
        ///
        /// <remarks>
        ///
        ///   <para>
        ///     DotNetZip will use multiple threads to compress any ZipEntry, when
        ///     the <c>CompressionMethod</c> is Deflate, and if the entry is
        ///     larger than the given size.  Zero means "always use parallel
        ///     deflate", while -1 means "never use parallel deflate".
        ///   </para>
        ///
        ///   <para>
        ///     If the entry size cannot be known before compression, as with any entry
        ///     added via a ZipOutputStream, then Parallel deflate will never be
        ///     performed, unless the value of this property is zero.
        ///   </para>
        ///
        ///   <para>
        ///     A parallel deflate operations will speed up the compression of
        ///     large files, on computers with multiple CPUs or multiple CPU
        ///     cores.  For files above 1mb, on a dual core or dual-cpu (2p)
        ///     machine, the time required to compress the file can be 70% of the
        ///     single-threaded deflate.  For very large files on 4p machines the
        ///     compression can be done in 30% of the normal time.  The downside
        ///     is that parallel deflate consumes extra memory during the deflate,
        ///     and the deflation is slightly less effective.
        ///   </para>
        ///
        ///   <para>
        ///     Parallel deflate tends to not be as effective as single-threaded deflate
        ///     because the original data stream is split into multiple independent
        ///     buffers, each of which is compressed in parallel.  But because they are
        ///     treated independently, there is no opportunity to share compression
        ///     dictionaries, and additional framing bytes must be added to the output
        ///     stream.  For that reason, a deflated stream may be slightly larger when
        ///     compressed using parallel deflate, as compared to a traditional
        ///     single-threaded deflate. For files of about 512k, the increase over the
        ///     normal deflate is as much as 5% of the total compressed size. For larger
        ///     files, the difference can be as small as 0.1%.
        ///   </para>
        ///
        ///   <para>
        ///     Multi-threaded compression does not give as much an advantage when using
        ///     Encryption. This is primarily because encryption tends to slow down
        ///     the entire pipeline. Also, multi-threaded compression gives less of an
        ///     advantage when using lower compression levels, for example <see
        ///     cref="Ionic.Zlib.CompressionLevel.BestSpeed"/>.  You may have to perform
        ///     some tests to determine the best approach for your situation.
        ///   </para>
        ///
        ///   <para>
        ///     The default value for this property is -1, which means parallel
        ///     compression will not be performed unless you set it to zero.
        ///   </para>
        ///
        /// </remarks>
        public long ParallelDeflateThreshold
        {
            set
            {
                if ((value != 0) && (value != -1) && (value < 64 * 1024))
                    throw new ArgumentOutOfRangeException("value must be greater than 64k, or 0, or -1");
                _ParallelDeflateThreshold = value;
            }
            get
            {
                return _ParallelDeflateThreshold;
            }
        }


        /// <summary>
        ///   The maximum number of buffer pairs to use when performing
        ///   parallel compression.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This property sets an upper limit on the number of memory
        ///   buffer pairs to create when performing parallel
        ///   compression.  The implementation of the parallel
        ///   compression stream allocates multiple buffers to
        ///   facilitate parallel compression.  As each buffer fills up,
        ///   the stream uses <see
        ///   cref="System.Threading.ThreadPool.QueueUserWorkItem(WaitCallback)">
        ///   ThreadPool.QueueUserWorkItem()</see> to compress those
        ///   buffers in a background threadpool thread. After a buffer
        ///   is compressed, it is re-ordered and written to the output
        ///   stream.
        /// </para>
        ///
        /// <para>
        ///   A higher number of buffer pairs enables a higher degree of
        ///   parallelism, which tends to increase the speed of compression on
        ///   multi-cpu computers.  On the other hand, a higher number of buffer
        ///   pairs also implies a larger memory consumption, more active worker
        ///   threads, and a higher cpu utilization for any compression. This
        ///   property enables the application to limit its memory consumption and
        ///   CPU utilization behavior depending on requirements.
        /// </para>
        ///
        /// <para>
        ///   For each compression "task" that occurs in parallel, there are 2
        ///   buffers allocated: one for input and one for output.  This property
        ///   sets a limit for the number of pairs.  The total amount of storage
        ///   space allocated for buffering will then be (N*S*2), where N is the
        ///   number of buffer pairs, S is the size of each buffer (<see
        ///   cref="CodecBufferSize"/>).  By default, DotNetZip allocates 4 buffer
        ///   pairs per CPU core, so if your machine has 4 cores, and you retain
        ///   the default buffer size of 128k, then the
        ///   ParallelDeflateOutputStream will use 4 * 4 * 2 * 128kb of buffer
        ///   memory in total, or 4mb, in blocks of 128kb.  If you then set this
        ///   property to 8, then the number will be 8 * 2 * 128kb of buffer
        ///   memory, or 2mb.
        /// </para>
        ///
        /// <para>
        ///   CPU utilization will also go up with additional buffers, because a
        ///   larger number of buffer pairs allows a larger number of background
        ///   threads to compress in parallel. If you find that parallel
        ///   compression is consuming too much memory or CPU, you can adjust this
        ///   value downward.
        /// </para>
        ///
        /// <para>
        ///   The default value is 16. Different values may deliver better or
        ///   worse results, depending on your priorities and the dynamic
        ///   performance characteristics of your storage and compute resources.
        /// </para>
        ///
        /// <para>
        ///   This property is not the number of buffer pairs to use; it is an
        ///   upper limit. An illustration: Suppose you have an application that
        ///   uses the default value of this property (which is 16), and it runs
        ///   on a machine with 2 CPU cores. In that case, DotNetZip will allocate
        ///   4 buffer pairs per CPU core, for a total of 8 pairs.  The upper
        ///   limit specified by this property has no effect.
        /// </para>
        ///
        /// <para>
        ///   The application can set this value at any time, but it is
        ///   effective only if set before calling
        ///   <c>ZipOutputStream.Write()</c> for the first time.
        /// </para>
        /// </remarks>
        ///
        /// <seealso cref="ParallelDeflateThreshold"/>
        ///
        public int ParallelDeflateMaxBufferPairs
        {
            get
            {
                return _maxBufferPairs;
            }
            set
            {
                if (value < 4)
                    throw new ArgumentOutOfRangeException("ParallelDeflateMaxBufferPairs",
                                                "Value must be 4 or greater.");
                _maxBufferPairs = value;
            }
        }
#endif


        private void InsureUniqueEntry(ZipEntry ze1)
        {
            if (_entriesWritten.ContainsKey(ze1.FileName))
            {
                _exceptionPending = true;
                throw new ArgumentException(String.Format("The entry '{0}' already exists in the zip archive.", ze1.FileName));
            }
        }


        internal Stream OutputStream
        {
            get
            {
                return _outputStream;
            }
        }

        internal String Name
        {
            get
            {
                return _name;
            }
        }

        /// <summary>
        ///   Returns true if an entry by the given name has already been written
        ///   to the ZipOutputStream.
        /// </summary>
        ///
        /// <param name="name">
        ///   The name of the entry to scan for.
        /// </param>
        ///
        /// <returns>
        /// true if an entry by the given name has already been written.
        /// </returns>
        public bool ContainsEntry(string name)
        {
            return _entriesWritten.ContainsKey(SharedUtilities.NormalizePathForUseInZipFile(name));
        }


        /// <summary>
        ///   Write the data from the buffer to the stream.
        /// </summary>
        ///
        /// <remarks>
        ///   As the application writes data into this stream, the data may be
        ///   compressed and encrypted before being written out to the underlying
        ///   stream, depending on the settings of the <see cref="CompressionLevel"/>
        ///   and the <see cref="Encryption"/> properties.
        /// </remarks>
        ///
        /// <param name="buffer">The buffer holding data to write to the stream.</param>
        /// <param name="offset">the offset within that data array to find the first byte to write.</param>
        /// <param name="count">the number of bytes to write.</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (_disposed)
            {
                _exceptionPending = true;
                throw new System.InvalidOperationException("The stream has been closed.");
            }

            if (buffer==null)
            {
                _exceptionPending = true;
                throw new System.ArgumentNullException("buffer");
            }

            if (_currentEntry == null)
            {
                _exceptionPending = true;
                throw new System.InvalidOperationException("You must call PutNextEntry() before calling Write().");
            }

            if (_currentEntry.IsDirectory)
            {
                _exceptionPending = true;
                throw new System.InvalidOperationException("You cannot Write() data for an entry that is a directory.");
            }

            if (_needToWriteEntryHeader)
                _InitiateCurrentEntry(false);

            if (count != 0)
                _entryOutputStream.Write(buffer, offset, count);
        }



        /// <summary>
        ///   Specify the name of the next entry that will be written to the zip file.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   Call this method just before calling <see cref="Write(byte[], int, int)"/>, to
        ///   specify the name of the entry that the next set of bytes written to
        ///   the <c>ZipOutputStream</c> belongs to. All subsequent calls to <c>Write</c>,
        ///   until the next call to <c>PutNextEntry</c>,
        ///   will be inserted into the named entry in the zip file.
        /// </para>
        ///
        /// <para>
        ///   If the <paramref name="entryName"/> used in <c>PutNextEntry()</c> ends in
        ///   a slash, then the entry added is marked as a directory. Because directory
        ///   entries do not contain data, a call to <c>Write()</c>, before an
        ///   intervening additional call to <c>PutNextEntry()</c>, will throw an
        ///   exception.
        /// </para>
        ///
        /// <para>
        ///   If you don't call <c>Write()</c> between two calls to
        ///   <c>PutNextEntry()</c>, the first entry is inserted into the zip file as a
        ///   file of zero size.  This may be what you want.
        /// </para>
        ///
        /// <para>
        ///   Because <c>PutNextEntry()</c> closes out the prior entry, if any, this
        ///   method may throw if there is a problem with the prior entry.
        /// </para>
        ///
        /// <para>
        ///   This method returns the <c>ZipEntry</c>.  You can modify public properties
        ///   on the <c>ZipEntry</c>, such as <see cref="ZipEntry.Encryption"/>, <see
        ///   cref="ZipEntry.Password"/>, and so on, until the first call to
        ///   <c>ZipOutputStream.Write()</c>, or until the next call to
        ///   <c>PutNextEntry()</c>.  If you modify the <c>ZipEntry</c> <em>after</em>
        ///   having called <c>Write()</c>, you may get a runtime exception, or you may
        ///   silently get an invalid zip archive.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        ///
        ///   This example shows how to create a zip file, using the
        ///   <c>ZipOutputStream</c> class.
        ///
        /// <code>
        /// private void Zipup()
        /// {
        ///     using (FileStream fs raw = File.Open(_outputFileName, FileMode.Create, FileAccess.ReadWrite ))
        ///     {
        ///         using (var output= new ZipOutputStream(fs))
        ///         {
        ///             output.Password = "VerySecret!";
        ///             output.Encryption = EncryptionAlgorithm.WinZipAes256;
        ///             output.PutNextEntry("entry1.txt");
        ///             byte[] buffer= System.Text.Encoding.ASCII.GetBytes("This is the content for entry #1.");
        ///             output.Write(buffer,0,buffer.Length);
        ///             output.PutNextEntry("entry2.txt");  // this will be zero length
        ///             output.PutNextEntry("entry3.txt");
        ///             buffer= System.Text.Encoding.ASCII.GetBytes("This is the content for entry #3.");
        ///             output.Write(buffer,0,buffer.Length);
        ///         }
        ///     }
        /// }
        /// </code>
        /// </example>
        ///
        /// <param name="entryName">
        ///   The name of the entry to be added, including any path to be used
        ///   within the zip file.
        /// </param>
        ///
        /// <returns>
        ///   The ZipEntry created.
        /// </returns>
        ///
        public ZipEntry PutNextEntry(String entryName)
        {
            if (String.IsNullOrEmpty(entryName))
                throw new ArgumentNullException("entryName");

            if (_disposed)
            {
                _exceptionPending = true;
                throw new System.InvalidOperationException("The stream has been closed.");
            }

            _FinishCurrentEntry();
            _currentEntry = ZipEntry.CreateForZipOutputStream(entryName);
            _currentEntry._container = new ZipContainer(this);
            _currentEntry._BitField |= 0x0008;  // workitem 8932
            _currentEntry.SetEntryTimes(DateTime.Now, DateTime.Now, DateTime.Now);
            _currentEntry.CompressionLevel = this.CompressionLevel;
            _currentEntry.CompressionMethod = this.CompressionMethod;
            _currentEntry.Password = _password; // workitem 13909
            _currentEntry.Encryption = this.Encryption;
            // workitem 12634
            _currentEntry.AlternateEncoding = this.AlternateEncoding;
            _currentEntry.AlternateEncodingUsage = this.AlternateEncodingUsage;

            if (entryName.EndsWith("/"))  _currentEntry.MarkAsDirectory();

            _currentEntry.EmitTimesInWindowsFormatWhenSaving = ((_timestamp & ZipEntryTimestamp.Windows) != 0);
            _currentEntry.EmitTimesInUnixFormatWhenSaving = ((_timestamp & ZipEntryTimestamp.Unix) != 0);
            InsureUniqueEntry(_currentEntry);
            _needToWriteEntryHeader = true;

            return _currentEntry;
        }



        private void _InitiateCurrentEntry(bool finishing)
        {
            // If finishing==true, this means we're initiating the entry at the time of
            // Close() or PutNextEntry().  If this happens, it means no data was written
            // for the entry - Write() was never called.  (The usual case us to call
            // _InitiateCurrentEntry(bool) from within Write().)  If finishing==true,
            // the entry could be either a zero-byte file or a directory.

            _entriesWritten.Add(_currentEntry.FileName,_currentEntry);
            _entryCount++; // could use _entriesWritten.Count, but I don't want to incur
            // the cost.

            if (_entryCount > 65534 && _zip64 == Zip64Option.Never)
            {
                _exceptionPending = true;
                throw new System.InvalidOperationException("Too many entries. Consider setting ZipOutputStream.EnableZip64.");
            }

            // Write out the header.
            //
            // If finishing, and encryption is in use, then we don't want to emit the
            // normal encryption header.  Signal that with a cycle=99 to turn off
            // encryption for zero-byte entries or directories.
            //
            // If finishing, then we know the stream length is zero.  Else, unknown
            // stream length.  Passing stream length == 0 allows an optimization so as
            // not to setup an encryption or deflation stream, when stream length is
            // zero.

            _currentEntry.WriteHeader(_outputStream, finishing ? 99 : 0);
            _currentEntry.StoreRelativeOffset();

            if (!_currentEntry.IsDirectory)
            {
                _currentEntry.WriteSecurityMetadata(_outputStream);
                _currentEntry.PrepOutputStream(_outputStream,
                                               finishing ? 0 : -1,
                                               out _outputCounter,
                                               out _encryptor,
                                               out _deflater,
                                               out _entryOutputStream);
            }
            _needToWriteEntryHeader = false;
        }



        private void _FinishCurrentEntry()
        {
            if (_currentEntry != null)
            {
                if (_needToWriteEntryHeader)
                    _InitiateCurrentEntry(true); // an empty entry - no writes

                _currentEntry.FinishOutputStream(_outputStream, _outputCounter, _encryptor, _deflater, _entryOutputStream);
                _currentEntry.PostProcessOutput(_outputStream);
                // workitem 12964
                if (_currentEntry.OutputUsedZip64!=null)
                    _anyEntriesUsedZip64 |= _currentEntry.OutputUsedZip64.Value;

                // reset all the streams
                _outputCounter = null; _encryptor = _deflater = null; _entryOutputStream = null;
            }
        }



        /// <summary>
        /// Dispose the stream
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method writes the Zip Central directory, then closes the stream.  The
        ///   application must call Dispose() (or Close) in order to produce a valid zip file.
        /// </para>
        ///
        /// <para>
        ///   Typically the application will call <c>Dispose()</c> implicitly, via a <c>using</c>
        ///   statement in C#, or a <c>Using</c> statement in VB.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <param name="disposing">set this to true, always.</param>
        protected override void Dispose(bool disposing)
        {
            if (_disposed) return;

            if (disposing) // not called from finalizer
            {
                // handle pending exceptions
                if (!_exceptionPending)
                {
                    _FinishCurrentEntry();
                    _directoryNeededZip64 = ZipOutput.WriteCentralDirectoryStructure(_outputStream,
                                                                                     _entriesWritten.Values,
                                                                                     1, // _numberOfSegmentsForMostRecentSave,
                                                                                     _zip64,
                                                                                     Comment,
                                                                                     new ZipContainer(this));
                    Stream wrappedStream = null;
                    CountingStream cs = _outputStream as CountingStream;
                    if (cs != null)
                    {
                        wrappedStream = cs.WrappedStream;
#if NETCF
                    cs.Close();
#else
                        cs.Dispose();
#endif
                    }
                    else
                    {
                        wrappedStream = _outputStream;
                    }

                    if (!_leaveUnderlyingStreamOpen)
                    {
#if NETCF
                    wrappedStream.Close();
#else
                        wrappedStream.Dispose();
#endif
                    }
                    _outputStream = null;
                }
            }
            _disposed = true;
        }



        /// <summary>
        /// Always returns false.
        /// </summary>
        public override bool CanRead { get { return false; } }

        /// <summary>
        /// Always returns false.
        /// </summary>
        public override bool CanSeek { get { return false; } }

        /// <summary>
        /// Always returns true.
        /// </summary>
        public override bool CanWrite { get { return true; } }

        /// <summary>
        /// Always returns a NotSupportedException.
        /// </summary>
        public override long Length { get { throw new NotSupportedException(); } }

        /// <summary>
        /// Setting this property always returns a NotSupportedException. Getting it
        /// returns the value of the Position on the underlying stream.
        /// </summary>
        public override long Position
        {
            get { return _outputStream.Position; }
            set { throw new NotSupportedException(); }
        }

        /// <summary>
        /// This is a no-op.
        /// </summary>
        public override void Flush() { }

        /// <summary>
        /// This method always throws a NotSupportedException.
        /// </summary>
        /// <param name="buffer">ignored</param>
        /// <param name="offset">ignored</param>
        /// <param name="count">ignored</param>
        /// <returns>nothing</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException("Read");
        }

        /// <summary>
        /// This method always throws a NotSupportedException.
        /// </summary>
        /// <param name="offset">ignored</param>
        /// <param name="origin">ignored</param>
        /// <returns>nothing</returns>
        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotSupportedException("Seek");
        }

        /// <summary>
        /// This method always throws a NotSupportedException.
        /// </summary>
        /// <param name="value">ignored</param>
        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }


        private EncryptionAlgorithm _encryption;
        private ZipEntryTimestamp _timestamp;
        internal String _password;
        private String _comment;
        private Stream _outputStream;
        private ZipEntry _currentEntry;
        internal Zip64Option _zip64;
        private Dictionary<String, ZipEntry> _entriesWritten;
        private int _entryCount;
        private ZipOption _alternateEncodingUsage = ZipOption.Never;
        private System.Text.Encoding _alternateEncoding
            = System.Text.Encoding.GetEncoding("IBM437"); // default = IBM437

        private bool _leaveUnderlyingStreamOpen;
        private bool _disposed;
        private bool _exceptionPending; // **see note below
        private bool _anyEntriesUsedZip64, _directoryNeededZip64;
        private CountingStream _outputCounter;
        private Stream _encryptor;
        private Stream _deflater;
        private Ionic.Crc.CrcCalculatorStream _entryOutputStream;
        private bool _needToWriteEntryHeader;
        private string _name;
        private bool _DontIgnoreCase;
#if !NETCF
        internal ParallelDeflateOutputStream ParallelDeflater;
        private long _ParallelDeflateThreshold;
        private int _maxBufferPairs = 16;
#endif

        // **Note regarding exceptions:

        // When ZipOutputStream is employed within a using clause, which
        // is the typical scenario, and an exception is thrown within
        // the scope of the using, Close()/Dispose() is invoked
        // implicitly before processing the initial exception.  In that
        // case, _exceptionPending is true, and we don't want to try to
        // write anything in the Close/Dispose logic.  Doing so can
        // cause additional exceptions that mask the original one. So,
        // the _exceptionPending flag is used to track that, and to
        // allow the original exception to be propagated to the
        // application without extra "noise."

    }



    internal class ZipContainer
    {
        private ZipFile _zf;
        private ZipOutputStream _zos;
        private ZipInputStream _zis;

        public ZipContainer(Object o)
        {
            _zf = (o as ZipFile);
            _zos = (o as ZipOutputStream);
            _zis = (o as ZipInputStream);
        }

        public ZipFile ZipFile
        {
            get { return _zf; }
        }

        public ZipOutputStream ZipOutputStream
        {
            get { return _zos; }
        }

        public string Name
        {
            get
            {
                if (_zf != null) return _zf.Name;
                if (_zis != null) throw new NotSupportedException();
                return _zos.Name;
            }
        }

        public string Password
        {
            get
            {
                if (_zf != null) return _zf._Password;
                if (_zis != null) return _zis._Password;
                return _zos._password;
            }
        }

        public Zip64Option Zip64
        {
            get
            {
                if (_zf != null) return _zf._zip64;
                if (_zis != null) throw new NotSupportedException();
                return _zos._zip64;
            }
        }

        public int BufferSize
        {
            get
            {
                if (_zf != null) return _zf.BufferSize;
                if (_zis != null) throw new NotSupportedException();
                return 0;
            }
        }

#if !NETCF
        public Ionic.Zlib.ParallelDeflateOutputStream ParallelDeflater
        {
            get
            {
                if (_zf != null) return _zf.ParallelDeflater;
                if (_zis != null) return null;
                return _zos.ParallelDeflater;
            }
            set
            {
                if (_zf != null) _zf.ParallelDeflater = value;
                else if (_zos != null) _zos.ParallelDeflater = value;
            }
        }

        public long ParallelDeflateThreshold
        {
            get
            {
                if (_zf != null) return _zf.ParallelDeflateThreshold;
                return _zos.ParallelDeflateThreshold;
            }
        }
        public int ParallelDeflateMaxBufferPairs
        {
            get
            {
                if (_zf != null) return _zf.ParallelDeflateMaxBufferPairs;
                return _zos.ParallelDeflateMaxBufferPairs;
            }
        }
#endif

        public int CodecBufferSize
        {
            get
            {
                if (_zf != null) return _zf.CodecBufferSize;
                if (_zis != null) return _zis.CodecBufferSize;
                return _zos.CodecBufferSize;
            }
        }

        public Ionic.Zlib.CompressionStrategy Strategy
        {
            get
            {
                if (_zf != null) return _zf.Strategy;
                return _zos.Strategy;
            }
        }

        public Zip64Option UseZip64WhenSaving
        {
            get
            {
                if (_zf != null) return _zf.UseZip64WhenSaving;
                return _zos.EnableZip64;
            }
        }

        public System.Text.Encoding AlternateEncoding
        {
            get
            {
                if (_zf != null) return _zf.AlternateEncoding;
                if (_zos!=null) return _zos.AlternateEncoding;
                return null;
            }
        }
        public System.Text.Encoding DefaultEncoding
        {
            get
            {
                if (_zf != null) return ZipFile.DefaultEncoding;
                if (_zos!=null) return ZipOutputStream.DefaultEncoding;
                return null;
            }
        }
        public ZipOption AlternateEncodingUsage
        {
            get
            {
                if (_zf != null) return _zf.AlternateEncodingUsage;
                if (_zos!=null) return _zos.AlternateEncodingUsage;
                return ZipOption.Never; // n/a
            }
        }

        public Stream ReadStream
        {
            get
            {
                if (_zf != null) return _zf.ReadStream;
                return _zis.ReadStream;
            }
        }
    }

}