// 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.ASCII;
            }
        }


#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.ASCII; // 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;
            }
        }
    }

}
