Use System.IO.Compression instead of custom ZIP library for EPPlus.

Change-Id: I4dc2d0c7889d885efdce1d786551414295b0e9c5
Reviewed-on: https://gnocchi-internal-review.git.corp.google.com/c/third_party/epplus/+/207480
Reviewed-by: Hughes Hilton <hugheshilton@google.com>
diff --git a/EPPlus/EPPlusSDK.csproj b/EPPlus/EPPlusSDK.csproj
index 9b5f21b..9203ac9 100644
--- a/EPPlus/EPPlusSDK.csproj
+++ b/EPPlus/EPPlusSDK.csproj
@@ -4,7 +4,7 @@
     <RootNamespace>OfficeOpenXml</RootNamespace>
     <AssemblyName>EPPlus</AssemblyName>
     <PackageId>Appsheet.EPPlus</PackageId>
-    <Version>1.0.3</Version>
+    <Version>1.0.4</Version>
     <DefaultItemExcludes>$(DefaultItemExcludes);Properties/AssemblyInfo.cs;FormulaParsing/LexicalAnalysis/TokenSeparatorHandlers/**;FormulaParsing/LexicalAnalysis/TokenHandler.cs;FormulaParsing/Excel/Functions/Math/Rank.cs</DefaultItemExcludes>
     <DefineConstants>Core;STANDARD20</DefineConstants>
     <ImplicitUsings>disable</ImplicitUsings>
diff --git a/EPPlus/ExcelWorkbook.cs b/EPPlus/ExcelWorkbook.cs
index e47b791..ba02560 100644
--- a/EPPlus/ExcelWorkbook.cs
+++ b/EPPlus/ExcelWorkbook.cs
@@ -31,7 +31,6 @@
  * Richard Tallent		Fix escaping of quotes					2012-10-31
  *******************************************************************************/
 using System;
-using System.Linq;
 using System.Xml;
 using System.IO;
 using System.Collections.Generic;
@@ -40,7 +39,6 @@
 using OfficeOpenXml.Utils;
 using OfficeOpenXml.FormulaParsing;
 using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
-using OfficeOpenXml.Packaging.Ionic.Zip;
 using System.Drawing;
 
 namespace OfficeOpenXml
@@ -794,26 +792,9 @@
 			}
 		}
 
-        private void SaveSharedStringHandler(ZipOutputStream stream, CompressionLevel compressionLevel, string fileName)
+        private void SaveSharedStringHandler(StreamWriter sw)
 		{
-            //Packaging.ZipPackagePart stringPart;
-            //if (_package.Package.PartExists(SharedStringsUri))
-            //{
-            //    stringPart=_package.Package.GetPart(SharedStringsUri);
-            //}
-            //else
-            //{
-            //    stringPart = _package.Package.CreatePart(SharedStringsUri, @"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", _package.Compression);
-                  //Part.CreateRelationship(UriHelper.GetRelativeUri(WorkbookUri, SharedStringsUri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/sharedStrings");
-            //}
-
-			//StreamWriter sw = new StreamWriter(stringPart.GetStream(FileMode.Create, FileAccess.Write));
-            //Init Zip
-            stream.CompressionLevel = (OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel)compressionLevel;
-            stream.PutNextEntry(fileName);
-
             var cache = new StringBuilder();            
-            var sw = new StreamWriter(stream);
             cache.AppendFormat("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"{0}\" uniqueCount=\"{0}\">", _sharedStrings.Count);
 			foreach (string t in _sharedStrings.Keys)
 			{
diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs
index 6ee3dd1..f8b6aeb 100644
--- a/EPPlus/ExcelWorksheet.cs
+++ b/EPPlus/ExcelWorksheet.cs
@@ -44,10 +44,10 @@
 using OfficeOpenXml.DataValidation;
 using OfficeOpenXml.Table.PivotTable;
 using System.ComponentModel;
+using System.IO.Compression;
 using OfficeOpenXml.ConditionalFormatting;
 using OfficeOpenXml.Utils;
 using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
-using OfficeOpenXml.Packaging.Ionic.Zip;
   
 namespace OfficeOpenXml
 {
@@ -2878,80 +2878,79 @@
                     }
                 }
         }
-        internal void SaveHandler(ZipOutputStream stream, CompressionLevel compressionLevel, string fileName)
+        internal void SaveHandler(StreamWriter streamWriter)
         {
-                    //Init Zip
-                    stream.CodecBufferSize = 8096;
-                    stream.CompressionLevel = (OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel)compressionLevel;
-                    stream.PutNextEntry(fileName);
+            //Create the nodes if they do not exist.
+            if (this is ExcelChartsheet)
+            {
+                streamWriter.Write(_worksheetXml.OuterXml);
+            }
+            else
+            {
+                CreateNode("d:cols");
+                CreateNode("d:sheetData");
+                CreateNode("d:mergeCells");
+                CreateNode("d:hyperlinks");
+                CreateNode("d:rowBreaks");
+                CreateNode("d:colBreaks");
 
-                    
-                    SaveXml(stream);
+                //StreamWriter sw=new StreamWriter(Part.GetStream(FileMode.Create, FileAccess.Write));
+                var xml = _worksheetXml.OuterXml;
+                int colStart = 0, colEnd = 0;
+                GetBlockPos(xml, "cols", ref colStart, ref colEnd);
+
+                streamWriter.Write(xml.Substring(0, colStart));
+                var colBreaks = new List<int>();
+                //if (_columns.Count > 0)
+                //{
+                UpdateColumnData(streamWriter);
+                //}
+
+                int cellStart = colEnd, cellEnd = colEnd;
+                GetBlockPos(xml, "sheetData", ref cellStart, ref cellEnd);
+
+                streamWriter.Write(xml.Substring(colEnd, cellStart - colEnd));
+                var rowBreaks = new List<int>();
+                UpdateRowCellData(streamWriter);
+
+                int mergeStart = cellEnd, mergeEnd = cellEnd;
+
+                GetBlockPos(xml, "mergeCells", ref mergeStart, ref mergeEnd);
+                streamWriter.Write(xml.Substring(cellEnd, mergeStart - cellEnd));
+
+                CleanupMergedCells(_mergedCells);
+                if (_mergedCells.Count > 0)
+                {
+                    UpdateMergedCells(streamWriter);
+                }
+
+                int hyperStart = mergeEnd, hyperEnd = mergeEnd;
+                GetBlockPos(xml, "hyperlinks", ref hyperStart, ref hyperEnd);
+                streamWriter.Write(xml.Substring(mergeEnd, hyperStart - mergeEnd));
+                //if (_hyperLinkCells.Count > 0)
+                //{
+                UpdateHyperLinks(streamWriter);
+                // }
+
+                int rowBreakStart = hyperEnd, rowBreakEnd = hyperEnd;
+                GetBlockPos(xml, "rowBreaks", ref rowBreakStart, ref rowBreakEnd);
+                streamWriter.Write(xml.Substring(hyperEnd, rowBreakStart - hyperEnd));
+                //if (rowBreaks.Count > 0)
+                //{
+                UpdateRowBreaks(streamWriter);
+                //}
+
+                int colBreakStart = rowBreakEnd, colBreakEnd = rowBreakEnd;
+                GetBlockPos(xml, "colBreaks", ref colBreakStart, ref colBreakEnd);
+                streamWriter.Write(xml.Substring(rowBreakEnd, colBreakStart - rowBreakEnd));
+                //if (colBreaks.Count > 0)
+                //{
+                UpdateColBreaks(streamWriter);
+                //}
+                streamWriter.Write(xml.Substring(colBreakEnd, xml.Length - colBreakEnd));
+            }
         }
-
         
-
-        ///// <summary>
-        ///// Saves the worksheet to the package.
-        ///// </summary>
-        //internal void Save()  // Worksheet Save
-        //{
-        //    DeletePrinterSettings();
-
-        //    if (_worksheetXml != null)
-        //    {
-                
-        //        // save the header & footer (if defined)
-        //        if (_headerFooter != null)
-        //            HeaderFooter.Save();
-
-        //        var d = Dimension;
-        //        if (d == null)
-        //        {
-        //            this.DeleteAllNode("d:dimension/@ref");
-        //        }
-        //        else
-        //        {
-        //            this.SetXmlNodeString("d:dimension/@ref", d.Address);
-        //        }
-                
-
-        //        if (_drawings != null && _drawings.Count == 0)
-        //        {
-        //            //Remove node if no drawings exists.
-        //            DeleteNode("d:drawing");
-        //        }
-
-        //        SaveComments();
-        //        HeaderFooter.SaveHeaderFooterImages();
-        //        SaveTables();
-        //        SavePivotTables();
-        //        SaveXml();
-        //    }
-            
-        //    if (Drawings.UriDrawing!=null)
-        //    {
-        //        if (Drawings.Count == 0)
-        //        {                    
-        //            Part.DeleteRelationship(Drawings._drawingRelation.Id);
-        //            _package.Package.DeletePart(Drawings.UriDrawing);                    
-        //        }
-        //        else
-        //        {
-        //            Packaging.ZipPackagePart partPack = Drawings.Part;
-        //            Drawings.DrawingXml.Save(partPack.GetStream(FileMode.Create, FileAccess.Write));
-        //            foreach (ExcelDrawing d in Drawings)
-        //            {
-        //                if (d is ExcelChart)
-        //                {
-        //                    ExcelChart c = (ExcelChart)d;
-        //                    c.ChartXml.Save(c.Part.GetStream(FileMode.Create, FileAccess.Write));
-        //                }
-        //            }
-        //        }
-        //    }
-        //}
-
         /// <summary>
         /// Delete the printersettings relationship and part.
         /// </summary>
@@ -3285,81 +3284,6 @@
         {
             return string.Format("SUBTOTAL({0},{1}[{2}])", FunctionNum, col._tbl.Name, col.Name);
         }
-        private void SaveXml(Stream stream)
-        {
-            //Create the nodes if they do not exist.
-            StreamWriter sw = new StreamWriter(stream, System.Text.Encoding.UTF8, 65536);
-            if (this is ExcelChartsheet)
-            {
-                sw.Write(_worksheetXml.OuterXml);
-            }
-            else
-            {
-                CreateNode("d:cols");
-                CreateNode("d:sheetData");
-                CreateNode("d:mergeCells");
-                CreateNode("d:hyperlinks");
-                CreateNode("d:rowBreaks");
-                CreateNode("d:colBreaks");
-
-                //StreamWriter sw=new StreamWriter(Part.GetStream(FileMode.Create, FileAccess.Write));
-                var xml = _worksheetXml.OuterXml;
-                int colStart = 0, colEnd = 0;
-                GetBlockPos(xml, "cols", ref colStart, ref colEnd);
-
-                sw.Write(xml.Substring(0, colStart));
-                var colBreaks = new List<int>();
-                //if (_columns.Count > 0)
-                //{
-                UpdateColumnData(sw);
-                //}
-
-                int cellStart = colEnd, cellEnd = colEnd;
-                GetBlockPos(xml, "sheetData", ref cellStart, ref cellEnd);
-
-                sw.Write(xml.Substring(colEnd, cellStart - colEnd));
-                var rowBreaks = new List<int>();
-                UpdateRowCellData(sw);
-
-                int mergeStart = cellEnd, mergeEnd = cellEnd;
-
-                GetBlockPos(xml, "mergeCells", ref mergeStart, ref mergeEnd);
-                sw.Write(xml.Substring(cellEnd, mergeStart - cellEnd));
-
-                CleanupMergedCells(_mergedCells);
-                if (_mergedCells.Count > 0)
-                {
-                    UpdateMergedCells(sw);
-                }
-
-                int hyperStart = mergeEnd, hyperEnd = mergeEnd;
-                GetBlockPos(xml, "hyperlinks", ref hyperStart, ref hyperEnd);
-                sw.Write(xml.Substring(mergeEnd, hyperStart - mergeEnd));
-                //if (_hyperLinkCells.Count > 0)
-                //{
-                UpdateHyperLinks(sw);
-                // }
-
-                int rowBreakStart = hyperEnd, rowBreakEnd = hyperEnd;
-                GetBlockPos(xml, "rowBreaks", ref rowBreakStart, ref rowBreakEnd);
-                sw.Write(xml.Substring(hyperEnd, rowBreakStart - hyperEnd));
-                //if (rowBreaks.Count > 0)
-                //{
-                UpdateRowBreaks(sw);
-                //}
-
-                int colBreakStart = rowBreakEnd, colBreakEnd = rowBreakEnd;
-                GetBlockPos(xml, "colBreaks", ref colBreakStart, ref colBreakEnd);
-                sw.Write(xml.Substring(rowBreakEnd, colBreakStart - rowBreakEnd));
-                //if (colBreaks.Count > 0)
-                //{
-                UpdateColBreaks(sw);
-                //}
-                sw.Write(xml.Substring(colBreakEnd, xml.Length - colBreakEnd));
-            }
-            sw.Flush();
-            //sw.Close();
-        }
 
         private void CleanupMergedCells(MergeCellsCollection _mergedCells)
         {
diff --git a/EPPlus/Packaging/DotNetZip/CRC32.cs b/EPPlus/Packaging/DotNetZip/CRC32.cs
deleted file mode 100644
index cf9574d..0000000
--- a/EPPlus/Packaging/DotNetZip/CRC32.cs
+++ /dev/null
@@ -1,814 +0,0 @@
-// CRC32.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2011 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: <2011-August-02 18:25:54>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the CRC32 class, which can do the CRC32 algorithm, using
-// arbitrary starting polynomials, and bit reversal. The bit reversal is what
-// distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP
-// files, or GZIP files. This class does both.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using Interop = System.Runtime.InteropServices;
-
-namespace OfficeOpenXml.Packaging.Ionic.Crc
-{
-    /// <summary>
-    ///   Computes a CRC-32. The CRC-32 algorithm is parameterized - you
-    ///   can set the polynomial and enable or disable bit
-    ///   reversal. This can be used for GZIP, BZip2, or ZIP.
-    /// </summary>
-    /// <remarks>
-    ///   This type is used internally by DotNetZip; it is generally not used
-    ///   directly by applications wishing to create, read, or manipulate zip
-    ///   archive files.
-    /// </remarks>
-
-    [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000C")]
-    [Interop.ComVisible(true)]
-#if !NETCF
-    [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
-#endif
-    internal class CRC32
-    {
-        /// <summary>
-        ///   Indicates the total number of bytes applied to the CRC.
-        /// </summary>
-        public Int64 TotalBytesRead
-        {
-            get
-            {
-                return _TotalBytesRead;
-            }
-        }
-
-        /// <summary>
-        /// Indicates the current CRC for all blocks slurped in.
-        /// </summary>
-        public Int32 Crc32Result
-        {
-            get
-            {
-                return unchecked((Int32)(~_register));
-            }
-        }
-
-        /// <summary>
-        /// Returns the CRC32 for the specified stream.
-        /// </summary>
-        /// <param name="input">The stream over which to calculate the CRC32</param>
-        /// <returns>the CRC32 calculation</returns>
-        public Int32 GetCrc32(System.IO.Stream input)
-        {
-            return GetCrc32AndCopy(input, null);
-        }
-
-        /// <summary>
-        /// Returns the CRC32 for the specified stream, and writes the input into the
-        /// output stream.
-        /// </summary>
-        /// <param name="input">The stream over which to calculate the CRC32</param>
-        /// <param name="output">The stream into which to deflate the input</param>
-        /// <returns>the CRC32 calculation</returns>
-        public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output)
-        {
-            if (input == null)
-                throw new Exception("The input stream must not be null.");
-
-            unchecked
-            {
-                byte[] buffer = new byte[BUFFER_SIZE];
-                int readSize = BUFFER_SIZE;
-
-                _TotalBytesRead = 0;
-                int count = input.Read(buffer, 0, readSize);
-                if (output != null) output.Write(buffer, 0, count);
-                _TotalBytesRead += count;
-                while (count > 0)
-                {
-                    SlurpBlock(buffer, 0, count);
-                    count = input.Read(buffer, 0, readSize);
-                    if (output != null) output.Write(buffer, 0, count);
-                    _TotalBytesRead += count;
-                }
-
-                return (Int32)(~_register);
-            }
-        }
-
-
-        /// <summary>
-        ///   Get the CRC32 for the given (word,byte) combo.  This is a
-        ///   computation defined by PKzip for PKZIP 2.0 (weak) encryption.
-        /// </summary>
-        /// <param name="W">The word to start with.</param>
-        /// <param name="B">The byte to combine it with.</param>
-        /// <returns>The CRC-ized result.</returns>
-        public Int32 ComputeCrc32(Int32 W, byte B)
-        {
-            return _InternalComputeCrc32((UInt32)W, B);
-        }
-
-        internal Int32 _InternalComputeCrc32(UInt32 W, byte B)
-        {
-            return (Int32)(crc32Table[(W ^ B) & 0xFF] ^ (W >> 8));
-        }
-
-
-        /// <summary>
-        /// Update the value for the running CRC32 using the given block of bytes.
-        /// This is useful when using the CRC32() class in a Stream.
-        /// </summary>
-        /// <param name="block">block of bytes to slurp</param>
-        /// <param name="offset">starting point in the block</param>
-        /// <param name="count">how many bytes within the block to slurp</param>
-        public void SlurpBlock(byte[] block, int offset, int count)
-        {
-            if (block == null)
-                throw new Exception("The data buffer must not be null.");
-
-            // bzip algorithm
-            for (int i = 0; i < count; i++)
-            {
-                int x = offset + i;
-                byte b = block[x];
-                if (this.reverseBits)
-                {
-                    UInt32 temp = (_register >> 24) ^ b;
-                    _register = (_register << 8) ^ crc32Table[temp];
-                }
-                else
-                {
-                    UInt32 temp = (_register & 0x000000FF) ^ b;
-                    _register = (_register >> 8) ^ crc32Table[temp];
-                }
-            }
-            _TotalBytesRead += count;
-        }
-
-
-        /// <summary>
-        ///   Process one byte in the CRC.
-        /// </summary>
-        /// <param name = "b">the byte to include into the CRC .  </param>
-        public void UpdateCRC(byte b)
-        {
-            if (this.reverseBits)
-            {
-                UInt32 temp = (_register >> 24) ^ b;
-                _register = (_register << 8) ^ crc32Table[temp];
-            }
-            else
-            {
-                UInt32 temp = (_register & 0x000000FF) ^ b;
-                _register = (_register >> 8) ^ crc32Table[temp];
-            }
-        }
-
-        /// <summary>
-        ///   Process a run of N identical bytes into the CRC.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     This method serves as an optimization for updating the CRC when a
-        ///     run of identical bytes is found. Rather than passing in a buffer of
-        ///     length n, containing all identical bytes b, this method accepts the
-        ///     byte value and the length of the (virtual) buffer - the length of
-        ///     the run.
-        ///   </para>
-        /// </remarks>
-        /// <param name = "b">the byte to include into the CRC.  </param>
-        /// <param name = "n">the number of times that byte should be repeated. </param>
-        public void UpdateCRC(byte b, int n)
-        {
-            while (n-- > 0)
-            {
-                if (this.reverseBits)
-                {
-                    uint temp = (_register >> 24) ^ b;
-                    _register = (_register << 8) ^ crc32Table[(temp >= 0)
-                                                              ? temp
-                                                              : (temp + 256)];
-                }
-                else
-                {
-                    UInt32 temp = (_register & 0x000000FF) ^ b;
-                    _register = (_register >> 8) ^ crc32Table[(temp >= 0)
-                                                              ? temp
-                                                              : (temp + 256)];
-
-                }
-            }
-        }
-
-
-
-        private static uint ReverseBits(uint data)
-        {
-            unchecked
-            {
-                uint ret = data;
-                ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555;
-                ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333;
-                ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F;
-                ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24);
-                return ret;
-            }
-        }
-
-        private static byte ReverseBits(byte data)
-        {
-            unchecked
-            {
-                uint u = (uint)data * 0x00020202;
-                uint m = 0x01044010;
-                uint s = u & m;
-                uint t = (u << 2) & (m << 1);
-                return (byte)((0x01001001 * (s + t)) >> 24);
-            }
-        }
-
-
-
-        private void GenerateLookupTable()
-        {
-            crc32Table = new UInt32[256];
-            unchecked
-            {
-                UInt32 dwCrc;
-                byte i = 0;
-                do
-                {
-                    dwCrc = i;
-                    for (byte j = 8; j > 0; j--)
-                    {
-                        if ((dwCrc & 1) == 1)
-                        {
-                            dwCrc = (dwCrc >> 1) ^ dwPolynomial;
-                        }
-                        else
-                        {
-                            dwCrc >>= 1;
-                        }
-                    }
-                    if (reverseBits)
-                    {
-                        crc32Table[ReverseBits(i)] = ReverseBits(dwCrc);
-                    }
-                    else
-                    {
-                        crc32Table[i] = dwCrc;
-                    }
-                    i++;
-                } while (i!=0);
-            }
-
-#if VERBOSE
-            Console.WriteLine();
-            Console.WriteLine("private static readonly UInt32[] crc32Table = {");
-            for (int i = 0; i < crc32Table.Length; i+=4)
-            {
-                Console.Write("   ");
-                for (int j=0; j < 4; j++)
-                {
-                    Console.Write(" 0x{0:X8}U,", crc32Table[i+j]);
-                }
-                Console.WriteLine();
-            }
-            Console.WriteLine("};");
-            Console.WriteLine();
-#endif
-        }
-
-
-        private uint gf2_matrix_times(uint[] matrix, uint vec)
-        {
-            uint sum = 0;
-            int i=0;
-            while (vec != 0)
-            {
-                if ((vec & 0x01)== 0x01)
-                    sum ^= matrix[i];
-                vec >>= 1;
-                i++;
-            }
-            return sum;
-        }
-
-        private void gf2_matrix_square(uint[] square, uint[] mat)
-        {
-            for (int i = 0; i < 32; i++)
-                square[i] = gf2_matrix_times(mat, mat[i]);
-        }
-
-
-
-        /// <summary>
-        ///   Combines the given CRC32 value with the current running total.
-        /// </summary>
-        /// <remarks>
-        ///   This is useful when using a divide-and-conquer approach to
-        ///   calculating a CRC.  Multiple threads can each calculate a
-        ///   CRC32 on a segment of the data, and then combine the
-        ///   individual CRC32 values at the end.
-        /// </remarks>
-        /// <param name="crc">the crc value to be combined with this one</param>
-        /// <param name="length">the length of data the CRC value was calculated on</param>
-        public void Combine(int crc, int length)
-        {
-            uint[] even = new uint[32];     // even-power-of-two zeros operator
-            uint[] odd = new uint[32];      // odd-power-of-two zeros operator
-
-            if (length == 0)
-                return;
-
-            uint crc1= ~_register;
-            uint crc2= (uint) crc;
-
-            // put operator for one zero bit in odd
-            odd[0] = this.dwPolynomial;  // the CRC-32 polynomial
-            uint row = 1;
-            for (int i = 1; i < 32; i++)
-            {
-                odd[i] = row;
-                row <<= 1;
-            }
-
-            // put operator for two zero bits in even
-            gf2_matrix_square(even, odd);
-
-            // put operator for four zero bits in odd
-            gf2_matrix_square(odd, even);
-
-            uint len2 = (uint) length;
-
-            // apply len2 zeros to crc1 (first square will put the operator for one
-            // zero byte, eight zero bits, in even)
-            do {
-                // apply zeros operator for this bit of len2
-                gf2_matrix_square(even, odd);
-
-                if ((len2 & 1)== 1)
-                    crc1 = gf2_matrix_times(even, crc1);
-                len2 >>= 1;
-
-                if (len2 == 0)
-                    break;
-
-                // another iteration of the loop with odd and even swapped
-                gf2_matrix_square(odd, even);
-                if ((len2 & 1)==1)
-                    crc1 = gf2_matrix_times(odd, crc1);
-                len2 >>= 1;
-
-
-            } while (len2 != 0);
-
-            crc1 ^= crc2;
-
-            _register= ~crc1;
-
-            //return (int) crc1;
-            return;
-        }
-
-
-        /// <summary>
-        ///   Create an instance of the CRC32 class using the default settings: no
-        ///   bit reversal, and a polynomial of 0xEDB88320.
-        /// </summary>
-        public CRC32() : this(false)
-        {
-        }
-
-        /// <summary>
-        ///   Create an instance of the CRC32 class, specifying whether to reverse
-        ///   data bits or not.
-        /// </summary>
-        /// <param name='reverseBits'>
-        ///   specify true if the instance should reverse data bits.
-        /// </param>
-        /// <remarks>
-        ///   <para>
-        ///     In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
-        ///     want a CRC32 with compatibility with BZip2, you should pass true
-        ///     here. In the CRC-32 used by GZIP and PKZIP, the bits are not
-        ///     reversed; Therefore if you want a CRC32 with compatibility with
-        ///     those, you should pass false.
-        ///   </para>
-        /// </remarks>
-        public CRC32(bool reverseBits) :
-            this( unchecked((int)0xEDB88320), reverseBits)
-        {
-        }
-
-
-        /// <summary>
-        ///   Create an instance of the CRC32 class, specifying the polynomial and
-        ///   whether to reverse data bits or not.
-        /// </summary>
-        /// <param name='polynomial'>
-        ///   The polynomial to use for the CRC, expressed in the reversed (LSB)
-        ///   format: the highest ordered bit in the polynomial value is the
-        ///   coefficient of the 0th power; the second-highest order bit is the
-        ///   coefficient of the 1 power, and so on. Expressed this way, the
-        ///   polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320.
-        /// </param>
-        /// <param name='reverseBits'>
-        ///   specify true if the instance should reverse data bits.
-        /// </param>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
-        ///     want a CRC32 with compatibility with BZip2, you should pass true
-        ///     here for the <c>reverseBits</c> parameter. In the CRC-32 used by
-        ///     GZIP and PKZIP, the bits are not reversed; Therefore if you want a
-        ///     CRC32 with compatibility with those, you should pass false for the
-        ///     <c>reverseBits</c> parameter.
-        ///   </para>
-        /// </remarks>
-        public CRC32(int polynomial, bool reverseBits)
-        {
-            this.reverseBits = reverseBits;
-            this.dwPolynomial = (uint) polynomial;
-            this.GenerateLookupTable();
-        }
-
-        /// <summary>
-        ///   Reset the CRC-32 class - clear the CRC "remainder register."
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Use this when employing a single instance of this class to compute
-        ///     multiple, distinct CRCs on multiple, distinct data blocks.
-        ///   </para>
-        /// </remarks>
-        public void Reset()
-        {
-            _register = 0xFFFFFFFFU;
-        }
-
-        // private member vars
-        private UInt32 dwPolynomial;
-        private Int64 _TotalBytesRead;
-        private bool reverseBits;
-        private UInt32[] crc32Table;
-        private const int BUFFER_SIZE = 8192;
-        private UInt32 _register = 0xFFFFFFFFU;
-    }
-
-
-    /// <summary>
-    /// A Stream that calculates a CRC32 (a checksum) on all bytes read,
-    /// or on all bytes written.
-    /// </summary>
-    ///
-    /// <remarks>
-    /// <para>
-    /// This class can be used to verify the CRC of a ZipEntry when
-    /// reading from a stream, or to calculate a CRC when writing to a
-    /// stream.  The stream should be used to either read, or write, but
-    /// not both.  If you intermix reads and writes, the results are not
-    /// defined.
-    /// </para>
-    ///
-    /// <para>
-    /// This class is intended primarily for use internally by the
-    /// DotNetZip library.
-    /// </para>
-    /// </remarks>
-    internal class CrcCalculatorStream : System.IO.Stream, System.IDisposable
-    {
-        private static readonly Int64 UnsetLengthLimit = -99;
-
-        internal System.IO.Stream _innerStream;
-        private CRC32 _Crc32;
-        private Int64 _lengthLimit = -99;
-        private bool _leaveOpen;
-
-        /// <summary>
-        /// The default constructor.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Instances returned from this constructor will leave the underlying
-        ///     stream open upon Close().  The stream uses the default CRC32
-        ///     algorithm, which implies a polynomial of 0xEDB88320.
-        ///   </para>
-        /// </remarks>
-        /// <param name="stream">The underlying stream</param>
-        public CrcCalculatorStream(System.IO.Stream stream)
-            : this(true, CrcCalculatorStream.UnsetLengthLimit, stream, null)
-        {
-        }
-
-        /// <summary>
-        ///   The constructor allows the caller to specify how to handle the
-        ///   underlying stream at close.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The stream uses the default CRC32 algorithm, which implies a
-        ///     polynomial of 0xEDB88320.
-        ///   </para>
-        /// </remarks>
-        /// <param name="stream">The underlying stream</param>
-        /// <param name="leaveOpen">true to leave the underlying stream
-        /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param>
-        public CrcCalculatorStream(System.IO.Stream stream, bool leaveOpen)
-            : this(leaveOpen, CrcCalculatorStream.UnsetLengthLimit, stream, null)
-        {
-        }
-
-        /// <summary>
-        ///   A constructor allowing the specification of the length of the stream
-        ///   to read.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The stream uses the default CRC32 algorithm, which implies a
-        ///     polynomial of 0xEDB88320.
-        ///   </para>
-        ///   <para>
-        ///     Instances returned from this constructor will leave the underlying
-        ///     stream open upon Close().
-        ///   </para>
-        /// </remarks>
-        /// <param name="stream">The underlying stream</param>
-        /// <param name="length">The length of the stream to slurp</param>
-        public CrcCalculatorStream(System.IO.Stream stream, Int64 length)
-            : this(true, length, stream, null)
-        {
-            if (length < 0)
-                throw new ArgumentException("length");
-        }
-
-        /// <summary>
-        ///   A constructor allowing the specification of the length of the stream
-        ///   to read, as well as whether to keep the underlying stream open upon
-        ///   Close().
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The stream uses the default CRC32 algorithm, which implies a
-        ///     polynomial of 0xEDB88320.
-        ///   </para>
-        /// </remarks>
-        /// <param name="stream">The underlying stream</param>
-        /// <param name="length">The length of the stream to slurp</param>
-        /// <param name="leaveOpen">true to leave the underlying stream
-        /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param>
-        public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen)
-            : this(leaveOpen, length, stream, null)
-        {
-            if (length < 0)
-                throw new ArgumentException("length");
-        }
-
-        /// <summary>
-        ///   A constructor allowing the specification of the length of the stream
-        ///   to read, as well as whether to keep the underlying stream open upon
-        ///   Close(), and the CRC32 instance to use.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The stream uses the specified CRC32 instance, which allows the
-        ///     application to specify how the CRC gets calculated.
-        ///   </para>
-        /// </remarks>
-        /// <param name="stream">The underlying stream</param>
-        /// <param name="length">The length of the stream to slurp</param>
-        /// <param name="leaveOpen">true to leave the underlying stream
-        /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param>
-        /// <param name="crc32">the CRC32 instance to use to calculate the CRC32</param>
-        public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen,
-                                   CRC32 crc32)
-            : this(leaveOpen, length, stream, crc32)
-        {
-            if (length < 0)
-                throw new ArgumentException("length");
-        }
-
-
-        // This ctor is private - no validation is done here.  This is to allow the use
-        // of a (specific) negative value for the _lengthLimit, to indicate that there
-        // is no length set.  So we validate the length limit in those ctors that use an
-        // explicit param, otherwise we don't validate, because it could be our special
-        // value.
-        private CrcCalculatorStream
-            (bool leaveOpen, Int64 length, System.IO.Stream stream, CRC32 crc32)
-            : base()
-        {
-            _innerStream = stream;
-            _Crc32 = crc32 ?? new CRC32();
-            _lengthLimit = length;
-            _leaveOpen = leaveOpen;
-        }
-
-
-        /// <summary>
-        ///   Gets the total number of bytes run through the CRC32 calculator.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This is either the total number of bytes read, or the total number of
-        ///   bytes written, depending on the direction of this stream.
-        /// </remarks>
-        public Int64 TotalBytesSlurped
-        {
-            get { return _Crc32.TotalBytesRead; }
-        }
-
-        /// <summary>
-        ///   Provides the current CRC for all blocks slurped in.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The running total of the CRC is kept as data is written or read
-        ///     through the stream.  read this property after all reads or writes to
-        ///     get an accurate CRC for the entire stream.
-        ///   </para>
-        /// </remarks>
-        public Int32 Crc
-        {
-            get { return _Crc32.Crc32Result; }
-        }
-
-        /// <summary>
-        ///   Indicates whether the underlying stream will be left open when the
-        ///   <c>CrcCalculatorStream</c> is Closed.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Set this at any point before calling <see cref="Close()"/>.
-        ///   </para>
-        /// </remarks>
-        public bool LeaveOpen
-        {
-            get { return _leaveOpen; }
-            set { _leaveOpen = value; }
-        }
-
-        /// <summary>
-        /// Read from the stream
-        /// </summary>
-        /// <param name="buffer">the buffer to read</param>
-        /// <param name="offset">the offset at which to start</param>
-        /// <param name="count">the number of bytes to read</param>
-        /// <returns>the number of bytes actually read</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            int bytesToRead = count;
-
-            // Need to limit the # of bytes returned, if the stream is intended to have
-            // a definite length.  This is especially useful when returning a stream for
-            // the uncompressed data directly to the application.  The app won't
-            // necessarily read only the UncompressedSize number of bytes.  For example
-            // wrapping the stream returned from OpenReader() into a StreadReader() and
-            // calling ReadToEnd() on it, We can "over-read" the zip data and get a
-            // corrupt string.  The length limits that, prevents that problem.
-
-            if (_lengthLimit != CrcCalculatorStream.UnsetLengthLimit)
-            {
-                if (_Crc32.TotalBytesRead >= _lengthLimit) return 0; // EOF
-                Int64 bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead;
-                if (bytesRemaining < count) bytesToRead = (int)bytesRemaining;
-            }
-            int n = _innerStream.Read(buffer, offset, bytesToRead);
-            if (n > 0) _Crc32.SlurpBlock(buffer, offset, n);
-            return n;
-        }
-
-        /// <summary>
-        /// Write to the stream.
-        /// </summary>
-        /// <param name="buffer">the buffer from which to write</param>
-        /// <param name="offset">the offset at which to start writing</param>
-        /// <param name="count">the number of bytes to write</param>
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            if (count > 0) _Crc32.SlurpBlock(buffer, offset, count);
-            _innerStream.Write(buffer, offset, count);
-        }
-
-        /// <summary>
-        /// Indicates whether the stream supports reading.
-        /// </summary>
-        public override bool CanRead
-        {
-            get { return _innerStream.CanRead; }
-        }
-
-        /// <summary>
-        ///   Indicates whether the stream supports seeking.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Always returns false.
-        ///   </para>
-        /// </remarks>
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-        /// <summary>
-        /// Indicates whether the stream supports writing.
-        /// </summary>
-        public override bool CanWrite
-        {
-            get { return _innerStream.CanWrite; }
-        }
-
-        /// <summary>
-        /// Flush the stream.
-        /// </summary>
-        public override void Flush()
-        {
-            _innerStream.Flush();
-        }
-
-        /// <summary>
-        ///   Returns the length of the underlying stream.
-        /// </summary>
-        public override long Length
-        {
-            get
-            {
-                if (_lengthLimit == CrcCalculatorStream.UnsetLengthLimit)
-                    return _innerStream.Length;
-                else return _lengthLimit;
-            }
-        }
-
-        /// <summary>
-        ///   The getter for this property returns the total bytes read.
-        ///   If you use the setter, it will throw
-        /// <see cref="NotSupportedException"/>.
-        /// </summary>
-        public override long Position
-        {
-            get { return _Crc32.TotalBytesRead; }
-            set { throw new NotSupportedException(); }
-        }
-
-        /// <summary>
-        /// Seeking is not supported on this stream. This method always throws
-        /// <see cref="NotSupportedException"/>
-        /// </summary>
-        /// <param name="offset">N/A</param>
-        /// <param name="origin">N/A</param>
-        /// <returns>N/A</returns>
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        /// This method always throws
-        /// <see cref="NotSupportedException"/>
-        /// </summary>
-        /// <param name="value">N/A</param>
-        public override void SetLength(long value)
-        {
-            throw new NotSupportedException();
-        }
-
-
-        void IDisposable.Dispose()
-        {
-            Close();
-        }
-
-        /// <summary>
-        /// Closes the stream.
-        /// </summary>
-        public override void Close()
-        {
-            base.Close();
-            if (!_leaveOpen)
-                _innerStream.Close();
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/ComHelper.cs b/EPPlus/Packaging/DotNetZip/ComHelper.cs
deleted file mode 100644
index fe2dfdb..0000000
--- a/EPPlus/Packaging/DotNetZip/ComHelper.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-// ComHelper.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-June-13 17:04:06>
-//
-// ------------------------------------------------------------------
-//
-// This module defines a COM Helper class.
-//
-// Created: Tue, 08 Sep 2009  22:03
-//
-
-using Interop=System.Runtime.InteropServices;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    /// This class exposes a set of COM-accessible wrappers for static
-    /// methods available on the ZipFile class.  You don't need this
-    /// class unless you are using DotNetZip from a COM environment.
-    /// </summary>
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000F")]
-    [System.Runtime.InteropServices.ComVisible(true)]
-#if !NETCF
-    [System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
-#endif
-
-    internal class ComHelper
-    {
-        /// <summary>
-        ///  A wrapper for <see cref="ZipFile.IsZipFile(string)">ZipFile.IsZipFile(string)</see>
-        /// </summary>
-        /// <param name="filename">The filename to of the zip file to check.</param>
-        /// <returns>true if the file contains a valid zip file.</returns>
-        public bool IsZipFile(string filename)
-        {
-            return ZipFile.IsZipFile(filename);
-        }
-
-        /// <summary>
-        ///  A wrapper for <see cref="ZipFile.IsZipFile(string, bool)">ZipFile.IsZipFile(string, bool)</see>
-        /// </summary>
-        /// <remarks>
-        /// We cannot use "overloaded" Method names in COM interop.
-        /// So, here, we use a unique name.
-        /// </remarks>
-        /// <param name="filename">The filename to of the zip file to check.</param>
-        /// <returns>true if the file contains a valid zip file.</returns>
-        public bool IsZipFileWithExtract(string filename)
-        {
-            return ZipFile.IsZipFile(filename, true);
-        }
-
-#if !NETCF
-        /// <summary>
-        ///  A wrapper for <see cref="ZipFile.CheckZip(string)">ZipFile.CheckZip(string)</see>
-        /// </summary>
-        /// <param name="filename">The filename to of the zip file to check.</param>
-        ///
-        /// <returns>true if the named zip file checks OK. Otherwise, false. </returns>
-        public bool CheckZip(string filename)
-        {
-            return ZipFile.CheckZip(filename);
-        }
-
-        /// <summary>
-        ///  A COM-friendly wrapper for the static method <see cref="ZipFile.CheckZipPassword(string,string)"/>.
-        /// </summary>
-        ///
-        /// <param name="filename">The filename to of the zip file to check.</param>
-        ///
-        /// <param name="password">The password to check.</param>
-        ///
-        /// <returns>true if the named zip file checks OK. Otherwise, false. </returns>
-        public bool CheckZipPassword(string filename, string password)
-        {
-            return ZipFile.CheckZipPassword(filename, password);
-        }
-
-        /// <summary>
-        ///  A wrapper for <see cref="ZipFile.FixZipDirectory(string)">ZipFile.FixZipDirectory(string)</see>
-        /// </summary>
-        /// <param name="filename">The filename to of the zip file to fix.</param>
-        public void FixZipDirectory(string filename)
-        {
-            ZipFile.FixZipDirectory(filename);
-        }
-#endif
-
-        /// <summary>
-        ///  A wrapper for <see cref="ZipFile.LibraryVersion">ZipFile.LibraryVersion</see>
-        /// </summary>
-        /// <returns>
-        ///  the version number on the DotNetZip assembly, formatted as a string.
-        /// </returns>
-        public string GetZipLibraryVersion()
-        {
-            return ZipFile.LibraryVersion.ToString();
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/EncryptionAlgorithm.cs b/EPPlus/Packaging/DotNetZip/EncryptionAlgorithm.cs
deleted file mode 100644
index 1247432..0000000
--- a/EPPlus/Packaging/DotNetZip/EncryptionAlgorithm.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-// EncryptionAlgorithm.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: <2009-October-21 17:24:45>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the EncryptionAgorithm enum
-//
-// 
-// ------------------------------------------------------------------
-
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    /// An enum that provides the various encryption algorithms supported by this
-    /// library.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///
-    /// <para>
-    ///   <c>PkzipWeak</c> implies the use of Zip 2.0 encryption, which is known to be
-    ///   weak and subvertible.
-    /// </para>
-    ///
-    /// <para>
-    ///   A note on interoperability: Values of <c>PkzipWeak</c> and <c>None</c> are
-    ///   specified in <see
-    ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's zip
-    ///   specification</see>, and are considered to be "standard".  Zip archives
-    ///   produced using these options will be interoperable with many other zip tools
-    ///   and libraries, including Windows Explorer.
-    /// </para>
-    ///
-    /// <para>
-    ///   Values of <c>WinZipAes128</c> and <c>WinZipAes256</c> are not part of the Zip
-    ///   specification, but rather imply the use of a vendor-specific extension from
-    ///   WinZip. If you want to produce interoperable Zip archives, do not use these
-    ///   values.  For example, if you produce a zip archive using WinZipAes256, you
-    ///   will be able to open it in Windows Explorer on Windows XP and Vista, but you
-    ///   will not be able to extract entries; trying this will lead to an "unspecified
-    ///   error". For this reason, some people have said that a zip archive that uses
-    ///   WinZip's AES encryption is not actually a zip archive at all.  A zip archive
-    ///   produced this way will be readable with the WinZip tool (Version 11 and
-    ///   beyond).
-    /// </para>
-    ///
-    /// <para>
-    ///   There are other third-party tools and libraries, both commercial and
-    ///   otherwise, that support WinZip's AES encryption. These will be able to read
-    ///   AES-encrypted zip archives produced by DotNetZip, and conversely applications
-    ///   that use DotNetZip to read zip archives will be able to read AES-encrypted
-    ///   archives produced by those tools or libraries.  Consult the documentation for
-    ///   those other tools and libraries to find out if WinZip's AES encryption is
-    ///   supported.
-    /// </para>
-    ///
-    /// <para>
-    ///   In case you care: According to <see
-    ///   href="http://www.winzip.com/aes_info.htm">the WinZip specification</see>, the
-    ///   actual AES key used is derived from the <see cref="ZipEntry.Password"/> via an
-    ///   algorithm that complies with <see
-    ///   href="http://www.ietf.org/rfc/rfc2898.txt">RFC 2898</see>, using an iteration
-    ///   count of 1000.  The algorithm is sometimes referred to as PBKDF2, which stands
-    ///   for "Password Based Key Derivation Function #2".
-    /// </para>
-    ///
-    /// <para>
-    ///   A word about password strength and length: The AES encryption technology is
-    ///   very good, but any system is only as secure as the weakest link.  If you want
-    ///   to secure your data, be sure to use a password that is hard to guess.  To make
-    ///   it harder to guess (increase its "entropy"), you should make it longer.  If
-    ///   you use normal characters from an ASCII keyboard, a password of length 20 will
-    ///   be strong enough that it will be impossible to guess.  For more information on
-    ///   that, I'd encourage you to read <see
-    ///   href="http://www.redkestrel.co.uk/Articles/RandomPasswordStrength.html">this
-    ///   article.</see>
-    /// </para>
-    ///
-    /// <para>
-    ///   The WinZip AES algorithms are not supported with the version of DotNetZip that
-    ///   runs on the .NET Compact Framework.  This is because .NET CF lacks the
-    ///   HMACSHA1 class that is required for producing the archive.
-    /// </para>
-    /// </remarks>
-    internal enum EncryptionAlgorithm
-    {
-        /// <summary>
-        /// No encryption at all.
-        /// </summary>
-        None = 0,
-
-        /// <summary>
-        /// Traditional or Classic pkzip encryption.
-        /// </summary>
-        PkzipWeak,
-
-#if AESCRYPTO
-        /// <summary>
-        /// WinZip AES encryption (128 key bits).
-        /// </summary>
-        WinZipAes128,
-
-        /// <summary>
-        /// WinZip AES encryption (256 key bits).
-        /// </summary>
-        WinZipAes256,
-#endif
-
-        /// <summary>
-        /// An encryption algorithm that is not supported by DotNetZip.
-        /// </summary>
-        Unsupported = 4,
-
-
-        // others... not implemented (yet?)
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/Events.cs b/EPPlus/Packaging/DotNetZip/Events.cs
deleted file mode 100644
index 7ba296c..0000000
--- a/EPPlus/Packaging/DotNetZip/Events.cs
+++ /dev/null
@@ -1,684 +0,0 @@
-// Events.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006, 2007, 2008, 2009 Dino Chiesa and Microsoft Corporation.
-// 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-August-06 12:26:24>
-//
-// ------------------------------------------------------------------
-//
-// This module defines events used by the ZipFile class.
-//
-//
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    ///   Delegate in which the application writes the <c>ZipEntry</c> content for the named entry.
-    /// </summary>
-    ///
-    /// <param name="entryName">The name of the entry that must be written.</param>
-    /// <param name="stream">The stream to which the entry data should be written.</param>
-    ///
-    /// <remarks>
-    ///   When you add an entry and specify a <c>WriteDelegate</c>, via <see
-    ///   cref="Ionic.Zip.ZipFile.AddEntry(string, WriteDelegate)"/>, the application
-    ///   code provides the logic that writes the entry data directly into the zip file.
-    /// </remarks>
-    ///
-    /// <example>
-    ///
-    /// This example shows how to define a WriteDelegate that obtains a DataSet, and then
-    /// writes the XML for the DataSet into the zip archive.  There's no need to
-    /// save the XML to a disk file first.
-    ///
-    /// <code lang="C#">
-    /// private void WriteEntry (String filename, Stream output)
-    /// {
-    ///     DataSet ds1 = ObtainDataSet();
-    ///     ds1.WriteXml(output);
-    /// }
-    ///
-    /// private void Run()
-    /// {
-    ///     using (var zip = new ZipFile())
-    ///     {
-    ///         zip.AddEntry(zipEntryName, WriteEntry);
-    ///         zip.Save(zipFileName);
-    ///     }
-    /// }
-    /// </code>
-    ///
-    /// <code lang="vb">
-    /// Private Sub WriteEntry (ByVal filename As String, ByVal output As Stream)
-    ///     DataSet ds1 = ObtainDataSet()
-    ///     ds1.WriteXml(stream)
-    /// End Sub
-    ///
-    /// Public Sub Run()
-    ///     Using zip = New ZipFile
-    ///         zip.AddEntry(zipEntryName, New WriteDelegate(AddressOf WriteEntry))
-    ///         zip.Save(zipFileName)
-    ///     End Using
-    /// End Sub
-    /// </code>
-    /// </example>
-    /// <seealso cref="Ionic.Zip.ZipFile.AddEntry(string, WriteDelegate)"/>
-    public delegate void WriteDelegate(string entryName, System.IO.Stream stream);
-
-
-    /// <summary>
-    ///   Delegate in which the application opens the stream, just-in-time, for the named entry.
-    /// </summary>
-    ///
-    /// <param name="entryName">
-    /// The name of the ZipEntry that the application should open the stream for.
-    /// </param>
-    ///
-    /// <remarks>
-    ///   When you add an entry via <see cref="Ionic.Zip.ZipFile.AddEntry(string,
-    ///   OpenDelegate, CloseDelegate)"/>, the application code provides the logic that
-    ///   opens and closes the stream for the given ZipEntry.
-    /// </remarks>
-    ///
-    /// <seealso cref="Ionic.Zip.ZipFile.AddEntry(string, OpenDelegate, CloseDelegate)"/>
-    public delegate System.IO.Stream OpenDelegate(string entryName);
-
-    /// <summary>
-    ///   Delegate in which the application closes the stream, just-in-time, for the named entry.
-    /// </summary>
-    ///
-    /// <param name="entryName">
-    /// The name of the ZipEntry that the application should close the stream for.
-    /// </param>
-    ///
-    /// <param name="stream">The stream to be closed.</param>
-    ///
-    /// <remarks>
-    ///   When you add an entry via <see cref="Ionic.Zip.ZipFile.AddEntry(string,
-    ///   OpenDelegate, CloseDelegate)"/>, the application code provides the logic that
-    ///   opens and closes the stream for the given ZipEntry.
-    /// </remarks>
-    ///
-    /// <seealso cref="Ionic.Zip.ZipFile.AddEntry(string, OpenDelegate, CloseDelegate)"/>
-    public delegate void CloseDelegate(string entryName, System.IO.Stream stream);
-
-    /// <summary>
-    ///   Delegate for the callback by which the application tells the
-    ///   library the CompressionLevel to use for a file.
-    /// </summary>
-    ///
-    /// <remarks>
-    /// <para>
-    ///   Using this callback, the application can, for example, specify that
-    ///   previously-compressed files (.mp3, .png, .docx, etc) should use a
-    ///   <c>CompressionLevel</c> of <c>None</c>, or can set the compression level based
-    ///   on any other factor.
-    /// </para>
-    /// </remarks>
-    /// <seealso cref="Ionic.Zip.ZipFile.SetCompression"/>
-    public delegate OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel SetCompressionCallback(string localFileName, string fileNameInArchive);
-
-    /// <summary>
-    ///   In an EventArgs type, indicates which sort of progress event is being
-    ///   reported.
-    /// </summary>
-    /// <remarks>
-    ///   There are events for reading, events for saving, and events for
-    ///   extracting. This enumeration allows a single EventArgs type to be sued to
-    ///   describe one of multiple subevents. For example, a SaveProgress event is
-    ///   invoked before, after, and during the saving of a single entry.  The value
-    ///   of an enum with this type, specifies which event is being triggered.  The
-    ///   same applies to Extraction, Reading and Adding events.
-    /// </remarks>
-    internal enum ZipProgressEventType
-    {
-        /// <summary>
-        /// Indicates that a Add() operation has started.
-        /// </summary>
-        Adding_Started,
-
-        /// <summary>
-        /// Indicates that an individual entry in the archive has been added.
-        /// </summary>
-        Adding_AfterAddEntry,
-
-        /// <summary>
-        /// Indicates that a Add() operation has completed.
-        /// </summary>
-        Adding_Completed,
-
-        /// <summary>
-        /// Indicates that a Read() operation has started.
-        /// </summary>
-        Reading_Started,
-
-        /// <summary>
-        /// Indicates that an individual entry in the archive is about to be read.
-        /// </summary>
-        Reading_BeforeReadEntry,
-
-        /// <summary>
-        /// Indicates that an individual entry in the archive has just been read.
-        /// </summary>
-        Reading_AfterReadEntry,
-
-        /// <summary>
-        /// Indicates that a Read() operation has completed.
-        /// </summary>
-        Reading_Completed,
-
-        /// <summary>
-        /// The given event reports the number of bytes read so far
-        /// during a Read() operation.
-        /// </summary>
-        Reading_ArchiveBytesRead,
-
-        /// <summary>
-        /// Indicates that a Save() operation has started.
-        /// </summary>
-        Saving_Started,
-
-        /// <summary>
-        /// Indicates that an individual entry in the archive is about to be written.
-        /// </summary>
-        Saving_BeforeWriteEntry,
-
-        /// <summary>
-        /// Indicates that an individual entry in the archive has just been saved.
-        /// </summary>
-        Saving_AfterWriteEntry,
-
-        /// <summary>
-        /// Indicates that a Save() operation has completed.
-        /// </summary>
-        Saving_Completed,
-
-        /// <summary>
-        /// Indicates that the zip archive has been created in a
-        /// temporary location during a Save() operation.
-        /// </summary>
-        Saving_AfterSaveTempArchive,
-
-        /// <summary>
-        /// Indicates that the temporary file is about to be renamed to the final archive
-        /// name during a Save() operation.
-        /// </summary>
-        Saving_BeforeRenameTempArchive,
-
-        /// <summary>
-        /// Indicates that the temporary file is has just been renamed to the final archive
-        /// name during a Save() operation.
-        /// </summary>
-        Saving_AfterRenameTempArchive,
-
-        /// <summary>
-        /// Indicates that the self-extracting archive has been compiled
-        /// during a Save() operation.
-        /// </summary>
-        Saving_AfterCompileSelfExtractor,
-
-        /// <summary>
-        /// The given event is reporting the number of source bytes that have run through the compressor so far
-        /// during a Save() operation.
-        /// </summary>
-        Saving_EntryBytesRead,
-
-        /// <summary>
-        /// Indicates that an entry is about to be extracted.
-        /// </summary>
-        Extracting_BeforeExtractEntry,
-
-        /// <summary>
-        /// Indicates that an entry has just been extracted.
-        /// </summary>
-        Extracting_AfterExtractEntry,
-
-        /// <summary>
-        ///   Indicates that extraction of an entry would overwrite an existing
-        ///   filesystem file. You must use
-        ///   <see cref="ExtractExistingFileAction.InvokeExtractProgressEvent">
-        ///   ExtractExistingFileAction.InvokeExtractProgressEvent</see> in the call
-        ///   to <c>ZipEntry.Extract()</c> in order to receive this event.
-        /// </summary>
-        Extracting_ExtractEntryWouldOverwrite,
-
-        /// <summary>
-        ///   The given event is reporting the number of bytes written so far for
-        ///   the current entry during an Extract() operation.
-        /// </summary>
-        Extracting_EntryBytesWritten,
-
-        /// <summary>
-        /// Indicates that an ExtractAll operation is about to begin.
-        /// </summary>
-        Extracting_BeforeExtractAll,
-
-        /// <summary>
-        /// Indicates that an ExtractAll operation has completed.
-        /// </summary>
-        Extracting_AfterExtractAll,
-
-        /// <summary>
-        /// Indicates that an error has occurred while saving a zip file.
-        /// This generally means the file cannot be opened, because it has been
-        /// removed, or because it is locked by another process.  It can also
-        /// mean that the file cannot be Read, because of a range lock conflict.
-        /// </summary>
-        Error_Saving,
-    }
-
-
-    /// <summary>
-    /// Provides information about the progress of a save, read, or extract operation.
-    /// This is a base class; you will probably use one of the classes derived from this one.
-    /// </summary>
-    internal class ZipProgressEventArgs : EventArgs
-    {
-        private int _entriesTotal;
-        private bool _cancel;
-        private ZipEntry _latestEntry;
-        private ZipProgressEventType _flavor;
-        private String _archiveName;
-        private Int64 _bytesTransferred;
-        private Int64 _totalBytesToTransfer;
-
-
-        internal ZipProgressEventArgs() { }
-
-        internal ZipProgressEventArgs(string archiveName, ZipProgressEventType flavor)
-        {
-            this._archiveName = archiveName;
-            this._flavor = flavor;
-        }
-
-        /// <summary>
-        /// The total number of entries to be saved or extracted.
-        /// </summary>
-        public int EntriesTotal
-        {
-            get { return _entriesTotal; }
-            set { _entriesTotal = value; }
-        }
-
-        /// <summary>
-        /// The name of the last entry saved or extracted.
-        /// </summary>
-        public ZipEntry CurrentEntry
-        {
-            get { return _latestEntry; }
-            set { _latestEntry = value; }
-        }
-
-        /// <summary>
-        /// In an event handler, set this to cancel the save or extract
-        /// operation that is in progress.
-        /// </summary>
-        public bool Cancel
-        {
-            get { return _cancel; }
-            set { _cancel = _cancel || value; }
-        }
-
-        /// <summary>
-        /// The type of event being reported.
-        /// </summary>
-        public ZipProgressEventType EventType
-        {
-            get { return _flavor; }
-            set { _flavor = value; }
-        }
-
-        /// <summary>
-        /// Returns the archive name associated to this event.
-        /// </summary>
-        public String ArchiveName
-        {
-            get { return _archiveName; }
-            set { _archiveName = value; }
-        }
-
-
-        /// <summary>
-        /// The number of bytes read or written so far for this entry.
-        /// </summary>
-        public Int64 BytesTransferred
-        {
-            get { return _bytesTransferred; }
-            set { _bytesTransferred = value; }
-        }
-
-
-
-        /// <summary>
-        /// Total number of bytes that will be read or written for this entry.
-        /// This number will be -1 if the value cannot be determined.
-        /// </summary>
-        public Int64 TotalBytesToTransfer
-        {
-            get { return _totalBytesToTransfer; }
-            set { _totalBytesToTransfer = value; }
-        }
-    }
-
-
-
-    /// <summary>
-    /// Provides information about the progress of a Read operation.
-    /// </summary>
-    internal class ReadProgressEventArgs : ZipProgressEventArgs
-    {
-
-        internal ReadProgressEventArgs() { }
-
-        private ReadProgressEventArgs(string archiveName, ZipProgressEventType flavor)
-            : base(archiveName, flavor)
-        { }
-
-        internal static ReadProgressEventArgs Before(string archiveName, int entriesTotal)
-        {
-            var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_BeforeReadEntry);
-            x.EntriesTotal = entriesTotal;
-            return x;
-        }
-
-        internal static ReadProgressEventArgs After(string archiveName, ZipEntry entry, int entriesTotal)
-        {
-            var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_AfterReadEntry);
-            x.EntriesTotal = entriesTotal;
-            x.CurrentEntry = entry;
-            return x;
-        }
-
-        internal static ReadProgressEventArgs Started(string archiveName)
-        {
-            var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_Started);
-            return x;
-        }
-
-        internal static ReadProgressEventArgs ByteUpdate(string archiveName, ZipEntry entry, Int64 bytesXferred, Int64 totalBytes)
-        {
-            var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_ArchiveBytesRead);
-            x.CurrentEntry = entry;
-            x.BytesTransferred = bytesXferred;
-            x.TotalBytesToTransfer = totalBytes;
-            return x;
-        }
-
-        internal static ReadProgressEventArgs Completed(string archiveName)
-        {
-            var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_Completed);
-            return x;
-        }
-
-    }
-
-
-    /// <summary>
-    /// Provides information about the progress of a Add operation.
-    /// </summary>
-    internal class AddProgressEventArgs : ZipProgressEventArgs
-    {
-        internal AddProgressEventArgs() { }
-
-        private AddProgressEventArgs(string archiveName, ZipProgressEventType flavor)
-            : base(archiveName, flavor)
-        { }
-
-        internal static AddProgressEventArgs AfterEntry(string archiveName, ZipEntry entry, int entriesTotal)
-        {
-            var x = new AddProgressEventArgs(archiveName, ZipProgressEventType.Adding_AfterAddEntry);
-            x.EntriesTotal = entriesTotal;
-            x.CurrentEntry = entry;
-            return x;
-        }
-
-        internal static AddProgressEventArgs Started(string archiveName)
-        {
-            var x = new AddProgressEventArgs(archiveName, ZipProgressEventType.Adding_Started);
-            return x;
-        }
-
-        internal static AddProgressEventArgs Completed(string archiveName)
-        {
-            var x = new AddProgressEventArgs(archiveName, ZipProgressEventType.Adding_Completed);
-            return x;
-        }
-
-    }
-
-    /// <summary>
-    /// Provides information about the progress of a save operation.
-    /// </summary>
-    internal class SaveProgressEventArgs : ZipProgressEventArgs
-    {
-        private int _entriesSaved;
-
-        /// <summary>
-        /// Constructor for the SaveProgressEventArgs.
-        /// </summary>
-        /// <param name="archiveName">the name of the zip archive.</param>
-        /// <param name="before">whether this is before saving the entry, or after</param>
-        /// <param name="entriesTotal">The total number of entries in the zip archive.</param>
-        /// <param name="entriesSaved">Number of entries that have been saved.</param>
-        /// <param name="entry">The entry involved in the event.</param>
-        internal SaveProgressEventArgs(string archiveName, bool before, int entriesTotal, int entriesSaved, ZipEntry entry)
-            : base(archiveName, (before) ? ZipProgressEventType.Saving_BeforeWriteEntry : ZipProgressEventType.Saving_AfterWriteEntry)
-        {
-            this.EntriesTotal = entriesTotal;
-            this.CurrentEntry = entry;
-            this._entriesSaved = entriesSaved;
-        }
-
-        internal SaveProgressEventArgs() { }
-
-        internal SaveProgressEventArgs(string archiveName, ZipProgressEventType flavor)
-            : base(archiveName, flavor)
-        { }
-
-
-        internal static SaveProgressEventArgs ByteUpdate(string archiveName, ZipEntry entry, Int64 bytesXferred, Int64 totalBytes)
-        {
-            var x = new SaveProgressEventArgs(archiveName, ZipProgressEventType.Saving_EntryBytesRead);
-            x.ArchiveName = archiveName;
-            x.CurrentEntry = entry;
-            x.BytesTransferred = bytesXferred;
-            x.TotalBytesToTransfer = totalBytes;
-            return x;
-        }
-
-        internal static SaveProgressEventArgs Started(string archiveName)
-        {
-            var x = new SaveProgressEventArgs(archiveName, ZipProgressEventType.Saving_Started);
-            return x;
-        }
-
-        internal static SaveProgressEventArgs Completed(string archiveName)
-        {
-            var x = new SaveProgressEventArgs(archiveName, ZipProgressEventType.Saving_Completed);
-            return x;
-        }
-
-        /// <summary>
-        /// Number of entries saved so far.
-        /// </summary>
-        public int EntriesSaved
-        {
-            get { return _entriesSaved; }
-        }
-    }
-
-
-    /// <summary>
-    /// Provides information about the progress of the extract operation.
-    /// </summary>
-    internal class ExtractProgressEventArgs : ZipProgressEventArgs
-    {
-        private int _entriesExtracted;
-        private string _target;
-
-        /// <summary>
-        /// Constructor for the ExtractProgressEventArgs.
-        /// </summary>
-        /// <param name="archiveName">the name of the zip archive.</param>
-        /// <param name="before">whether this is before saving the entry, or after</param>
-        /// <param name="entriesTotal">The total number of entries in the zip archive.</param>
-        /// <param name="entriesExtracted">Number of entries that have been extracted.</param>
-        /// <param name="entry">The entry involved in the event.</param>
-        /// <param name="extractLocation">The location to which entries are extracted.</param>
-        internal ExtractProgressEventArgs(string archiveName, bool before, int entriesTotal, int entriesExtracted, ZipEntry entry, string extractLocation)
-            : base(archiveName, (before) ? ZipProgressEventType.Extracting_BeforeExtractEntry : ZipProgressEventType.Extracting_AfterExtractEntry)
-        {
-            this.EntriesTotal = entriesTotal;
-            this.CurrentEntry = entry;
-            this._entriesExtracted = entriesExtracted;
-            this._target = extractLocation;
-        }
-
-        internal ExtractProgressEventArgs(string archiveName, ZipProgressEventType flavor)
-            : base(archiveName, flavor)
-        { }
-
-        internal ExtractProgressEventArgs()
-        { }
-
-
-        internal static ExtractProgressEventArgs BeforeExtractEntry(string archiveName, ZipEntry entry, string extractLocation)
-        {
-            var x = new ExtractProgressEventArgs
-                {
-                    ArchiveName = archiveName,
-                    EventType = ZipProgressEventType.Extracting_BeforeExtractEntry,
-                    CurrentEntry = entry,
-                    _target = extractLocation,
-                };
-            return x;
-        }
-
-        internal static ExtractProgressEventArgs ExtractExisting(string archiveName, ZipEntry entry, string extractLocation)
-        {
-            var x = new ExtractProgressEventArgs
-                {
-                    ArchiveName = archiveName,
-                    EventType = ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite,
-                    CurrentEntry = entry,
-                    _target = extractLocation,
-                };
-            return x;
-        }
-
-        internal static ExtractProgressEventArgs AfterExtractEntry(string archiveName, ZipEntry entry, string extractLocation)
-        {
-            var x = new ExtractProgressEventArgs
-                {
-                    ArchiveName = archiveName,
-                    EventType = ZipProgressEventType.Extracting_AfterExtractEntry,
-                    CurrentEntry = entry,
-                    _target = extractLocation,
-                };
-            return x;
-        }
-
-        internal static ExtractProgressEventArgs ExtractAllStarted(string archiveName, string extractLocation)
-        {
-            var x = new ExtractProgressEventArgs(archiveName, ZipProgressEventType.Extracting_BeforeExtractAll);
-            x._target = extractLocation;
-            return x;
-        }
-
-        internal static ExtractProgressEventArgs ExtractAllCompleted(string archiveName, string extractLocation)
-        {
-            var x = new ExtractProgressEventArgs(archiveName, ZipProgressEventType.Extracting_AfterExtractAll);
-            x._target = extractLocation;
-            return x;
-        }
-
-
-        internal static ExtractProgressEventArgs ByteUpdate(string archiveName, ZipEntry entry, Int64 bytesWritten, Int64 totalBytes)
-        {
-            var x = new ExtractProgressEventArgs(archiveName, ZipProgressEventType.Extracting_EntryBytesWritten);
-            x.ArchiveName = archiveName;
-            x.CurrentEntry = entry;
-            x.BytesTransferred = bytesWritten;
-            x.TotalBytesToTransfer = totalBytes;
-            return x;
-        }
-
-
-
-        /// <summary>
-        /// Number of entries extracted so far.  This is set only if the
-        /// EventType is Extracting_BeforeExtractEntry or Extracting_AfterExtractEntry, and
-        /// the Extract() is occurring witin the scope of a call to ExtractAll().
-        /// </summary>
-        public int EntriesExtracted
-        {
-            get { return _entriesExtracted; }
-        }
-
-        /// <summary>
-        /// Returns the extraction target location, a filesystem path.
-        /// </summary>
-        public String ExtractLocation
-        {
-            get { return _target; }
-        }
-
-    }
-
-
-
-    /// <summary>
-    /// Provides information about the an error that occurred while zipping.
-    /// </summary>
-    internal class ZipErrorEventArgs : ZipProgressEventArgs
-    {
-        private Exception _exc;
-        private ZipErrorEventArgs() { }
-        internal static ZipErrorEventArgs Saving(string archiveName, ZipEntry entry, Exception exception)
-        {
-            var x = new ZipErrorEventArgs
-                {
-                    EventType = ZipProgressEventType.Error_Saving,
-                    ArchiveName = archiveName,
-                    CurrentEntry = entry,
-                    _exc = exception
-                };
-            return x;
-        }
-
-        /// <summary>
-        /// Returns the exception that occurred, if any.
-        /// </summary>
-        public Exception @Exception
-        {
-            get { return _exc; }
-        }
-
-        /// <summary>
-        /// Returns the name of the file that caused the exception, if any.
-        /// </summary>
-        public String FileName
-        {
-            get { return CurrentEntry.LocalFileName; }
-        }
-    }
-
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/Exceptions.cs b/EPPlus/Packaging/DotNetZip/Exceptions.cs
deleted file mode 100644
index a5a2c81..0000000
--- a/EPPlus/Packaging/DotNetZip/Exceptions.cs
+++ /dev/null
@@ -1,300 +0,0 @@
-// Exceptions.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008, 2009 Dino Chiesa and Microsoft Corporation.
-// 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-12 12:19:10>
-//
-// ------------------------------------------------------------------
-//
-// This module defines exceptions used in the class library.
-//
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-#if !NETCF
-using System.Runtime.Serialization;
-#endif
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    ///// <summary>
-    ///// Base exception type for all custom exceptions in the Zip library. It acts as a marker class.
-    ///// </summary>
-    //[AttributeUsage(AttributeTargets.Class)]
-    //public class ZipExceptionAttribute : Attribute { }
-
-
-
-    /// <summary>
-    /// Issued when an <c>ZipEntry.ExtractWithPassword()</c> method is invoked
-    /// with an incorrect password.
-    /// </summary>
-#if !SILVERLIGHT
-    [Serializable]
-#endif
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000B")]
-    public class BadPasswordException : ZipException
-    {
-        /// <summary>
-        /// Default ctor.
-        /// </summary>
-        public BadPasswordException() { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        public BadPasswordException(String message)
-            : base(message)
-        { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        /// <param name="innerException">The innerException for this exception.</param>
-        public BadPasswordException(String message, Exception innerException)
-            : base(message, innerException)
-        {
-        }
-
-
-#if ! (NETCF || SILVERLIGHT)
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="info">The serialization info for the exception.</param>
-        /// <param name="context">The streaming context from which to deserialize.</param>
-        protected BadPasswordException(SerializationInfo info, StreamingContext context)
-            : base(info, context)
-          {  }
-#endif
-
-    }
-
-    /// <summary>
-    /// Indicates that a read was attempted on a stream, and bad or incomplete data was
-    /// received.
-    /// </summary>
-#if !SILVERLIGHT
-    [Serializable]
-#endif
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000A")]
-    public class BadReadException : ZipException
-    {
-        /// <summary>
-        /// Default ctor.
-        /// </summary>
-        public BadReadException() { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        public BadReadException(String message)
-            : base(message)
-        { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        /// <param name="innerException">The innerException for this exception.</param>
-        public BadReadException(String message, Exception innerException)
-            : base(message, innerException)
-        {
-        }
-
-#if ! (NETCF || SILVERLIGHT)
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="info">The serialization info for the exception.</param>
-        /// <param name="context">The streaming context from which to deserialize.</param>
-        protected BadReadException(SerializationInfo info, StreamingContext context)
-            : base(info, context)
-          {  }
-#endif
-
-    }
-
-
-
-    /// <summary>
-    /// Issued when an CRC check fails upon extracting an entry from a zip archive.
-    /// </summary>
-#if !SILVERLIGHT
-    [Serializable]
-#endif
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00009")]
-    public class BadCrcException : ZipException
-    {
-        /// <summary>
-        /// Default ctor.
-        /// </summary>
-        public BadCrcException() { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        public BadCrcException(String message)
-            : base(message)
-        { }
-
-
-#if ! (NETCF || SILVERLIGHT)
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="info">The serialization info for the exception.</param>
-        /// <param name="context">The streaming context from which to deserialize.</param>
-        protected BadCrcException(SerializationInfo info, StreamingContext context)
-            : base(info, context)
-          {  }
-#endif
-
-    }
-
-
-    /// <summary>
-    /// Issued when errors occur saving a self-extracting archive.
-    /// </summary>
-#if !SILVERLIGHT
-    [Serializable]
-#endif
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00008")]
-    public class SfxGenerationException : ZipException
-    {
-        /// <summary>
-        /// Default ctor.
-        /// </summary>
-        public SfxGenerationException() { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        public SfxGenerationException(String message)
-            : base(message)
-        { }
-
-#if ! (NETCF || SILVERLIGHT)
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="info">The serialization info for the exception.</param>
-        /// <param name="context">The streaming context from which to deserialize.</param>
-        protected SfxGenerationException(SerializationInfo info, StreamingContext context)
-            : base(info, context)
-          {  }
-#endif
-
-    }
-
-
-    /// <summary>
-    /// Indicates that an operation was attempted on a ZipFile which was not possible
-    /// given the state of the instance. For example, if you call <c>Save()</c> on a ZipFile
-    /// which has no filename set, you can get this exception.
-    /// </summary>
-#if !SILVERLIGHT
-    [Serializable]
-#endif
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00007")]
-    public class BadStateException : ZipException
-    {
-        /// <summary>
-        /// Default ctor.
-        /// </summary>
-        public BadStateException() { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        public BadStateException(String message)
-            : base(message)
-        { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        /// <param name="innerException">The innerException for this exception.</param>
-        public BadStateException(String message, Exception innerException)
-            : base(message, innerException)
-        {}
-
-#if ! (NETCF || SILVERLIGHT)
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="info">The serialization info for the exception.</param>
-        /// <param name="context">The streaming context from which to deserialize.</param>
-        protected BadStateException(SerializationInfo info, StreamingContext context)
-            : base(info, context)
-          {  }
-#endif
-
-    }
-
-    /// <summary>
-    /// Base class for all exceptions defined by and throw by the Zip library.
-    /// </summary>
-#if !SILVERLIGHT
-    [Serializable]
-#endif
-    [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00006")]
-    public class ZipException : Exception
-    {
-        /// <summary>
-        /// Default ctor.
-        /// </summary>
-        public ZipException() { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        public ZipException(String message) : base(message) { }
-
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="message">The message in the exception.</param>
-        /// <param name="innerException">The innerException for this exception.</param>
-        public ZipException(String message, Exception innerException)
-            : base(message, innerException)
-        { }
-
-#if ! (NETCF || SILVERLIGHT)
-        /// <summary>
-        /// Come on, you know how exceptions work. Why are you looking at this documentation?
-        /// </summary>
-        /// <param name="info">The serialization info for the exception.</param>
-        /// <param name="context">The streaming context from which to deserialize.</param>
-        protected ZipException(SerializationInfo info, StreamingContext context)
-            : base(info, context)
-        { }
-#endif
-
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ExtractExistingFileAction.cs b/EPPlus/Packaging/DotNetZip/ExtractExistingFileAction.cs
deleted file mode 100644
index 3b4af1a..0000000
--- a/EPPlus/Packaging/DotNetZip/ExtractExistingFileAction.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// ExtractExistingFileAction.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: <2009-August-25 08:44:37>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ExtractExistingFileAction enum
-//
-// 
-// ------------------------------------------------------------------
-
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    /// <summary>
-    /// An enum for the options when extracting an entry would overwrite an existing file. 
-    /// </summary>
-    /// 
-    /// <remarks>
-    ///   <para>
-    ///     This enum describes the actions that the library can take when an
-    ///     <c>Extract()</c> or <c>ExtractWithPassword()</c> method is called to extract an
-    ///     entry to a filesystem, and the extraction would overwrite an existing filesystem
-    ///     file.
-    ///   </para>
-    /// </remarks>
-    ///
-    internal enum ExtractExistingFileAction
-    {
-        /// <summary>
-        /// Throw an exception when extraction would overwrite an existing file. (For
-        /// COM clients, this is a 0 (zero).)
-        /// </summary>
-        Throw,
-
-        /// <summary>
-        /// When extraction would overwrite an existing file, overwrite the file silently.
-        /// The overwrite will happen even if the target file is marked as read-only.
-        /// (For COM clients, this is a 1.)
-        /// </summary>
-        OverwriteSilently,
-
-        /// <summary>
-        /// When extraction would overwrite an existing file, don't overwrite the file, silently. 
-        /// (For COM clients, this is a 2.)
-        /// </summary>
-        DoNotOverwrite,
-
-        /// <summary>
-        /// When extraction would overwrite an existing file, invoke the ExtractProgress
-        /// event, using an event type of <see
-        /// cref="ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite"/>.  In
-        /// this way, the application can decide, just-in-time, whether to overwrite the
-        /// file. For example, a GUI application may wish to pop up a dialog to allow
-        /// the user to choose. You may want to examine the <see
-        /// cref="ExtractProgressEventArgs.ExtractLocation"/> property before making
-        /// the decision. If, after your processing in the Extract progress event, you
-        /// want to NOT extract the file, set <see cref="ZipEntry.ExtractExistingFile"/>
-        /// on the <c>ZipProgressEventArgs.CurrentEntry</c> to <c>DoNotOverwrite</c>.
-        /// If you do want to extract the file, set <c>ZipEntry.ExtractExistingFile</c>
-        /// to <c>OverwriteSilently</c>.  If you want to cancel the Extraction, set
-        /// <c>ZipProgressEventArgs.Cancel</c> to true.  Cancelling differs from using
-        /// DoNotOverwrite in that a cancel will not extract any further entries, if
-        /// there are any.  (For COM clients, the value of this enum is a 3.)
-        /// </summary>
-        InvokeExtractProgressEvent,
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/FileSelector.cs b/EPPlus/Packaging/DotNetZip/FileSelector.cs
deleted file mode 100644
index 85d5fcc..0000000
--- a/EPPlus/Packaging/DotNetZip/FileSelector.cs
+++ /dev/null
@@ -1,1609 +0,0 @@
-//#define SelectorTrace
-
-// FileSelector.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008-2011 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: <2011-August-05 11:03:11>
-//
-// ------------------------------------------------------------------
-//
-// This module implements a "file selector" that finds files based on a
-// set of inclusion criteria, including filename, size, file time, and
-// potentially file attributes.  The criteria are given in a string with
-// a simple expression language. Examples:
-//
-// find all .txt files:
-//     name = *.txt
-//
-// shorthand for the above
-//     *.txt
-//
-// all files modified after January 1st, 2009
-//     mtime > 2009-01-01
-//
-// All .txt files modified after the first of the year
-//     name = *.txt  AND  mtime > 2009-01-01
-//
-// All .txt files modified after the first of the year, or any file with the archive bit set
-//     (name = *.txt  AND  mtime > 2009-01-01) or (attribtues = A)
-//
-// All .txt files or any file greater than 1mb in size
-//     (name = *.txt  or  size > 1mb)
-//
-// and so on.
-// ------------------------------------------------------------------
-
-
-using System;
-using System.Globalization;
-using System.IO;
-using System.Text;
-using System.Reflection;
-using System.ComponentModel;
-using System.Text.RegularExpressions;
-using System.Collections.Generic;
-#if SILVERLIGHT
-using System.Linq;
-#endif
-
-namespace OfficeOpenXml.Packaging.Ionic
-{
-
-    /// <summary>
-    /// Enumerates the options for a logical conjunction. This enum is intended for use
-    /// internally by the FileSelector class.
-    /// </summary>
-    internal enum LogicalConjunction
-    {
-        NONE,
-        AND,
-        OR,
-        XOR,
-    }
-
-    internal enum WhichTime
-    {
-        atime,
-        mtime,
-        ctime,
-    }
-
-
-    internal enum ComparisonOperator
-    {
-        [Description(">")]
-        GreaterThan,
-        [Description(">=")]
-        GreaterThanOrEqualTo,
-        [Description("<")]
-        LesserThan,
-        [Description("<=")]
-        LesserThanOrEqualTo,
-        [Description("=")]
-        EqualTo,
-        [Description("!=")]
-        NotEqualTo
-    }
-
-
-    internal abstract partial class SelectionCriterion
-    {
-        internal virtual bool Verbose
-        {
-            get;set;
-        }
-        internal abstract bool Evaluate(string filename);
-
-        [System.Diagnostics.Conditional("SelectorTrace")]
-        protected static void CriterionTrace(string format, params object[] args)
-        {
-            //System.Console.WriteLine("  " + format, args);
-        }
-    }
-
-
-    internal partial class SizeCriterion : SelectionCriterion
-    {
-        internal ComparisonOperator Operator;
-        internal Int64 Size;
-
-        public override String ToString()
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append("size ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(Size.ToString());
-            return sb.ToString();
-        }
-
-        internal override bool Evaluate(string filename)
-        {
-            System.IO.FileInfo fi = new System.IO.FileInfo(filename);
-            CriterionTrace("SizeCriterion::Evaluate('{0}' [{1}])",
-                           filename, this.ToString());
-            return _Evaluate(fi.Length);
-        }
-
-        private bool _Evaluate(Int64 Length)
-        {
-            bool result = false;
-            switch (Operator)
-            {
-                case ComparisonOperator.GreaterThanOrEqualTo:
-                    result = Length >= Size;
-                    break;
-                case ComparisonOperator.GreaterThan:
-                    result = Length > Size;
-                    break;
-                case ComparisonOperator.LesserThanOrEqualTo:
-                    result = Length <= Size;
-                    break;
-                case ComparisonOperator.LesserThan:
-                    result = Length < Size;
-                    break;
-                case ComparisonOperator.EqualTo:
-                    result = Length == Size;
-                    break;
-                case ComparisonOperator.NotEqualTo:
-                    result = Length != Size;
-                    break;
-                default:
-                    throw new ArgumentException("Operator");
-            }
-            return result;
-        }
-
-    }
-
-
-
-    internal partial class TimeCriterion : SelectionCriterion
-    {
-        internal ComparisonOperator Operator;
-        internal WhichTime Which;
-        internal DateTime Time;
-
-        public override String ToString()
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append(Which.ToString()).Append(" ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(Time.ToString("yyyy-MM-dd-HH:mm:ss"));
-            return sb.ToString();
-        }
-
-        internal override bool Evaluate(string filename)
-        {
-            DateTime x;
-            switch (Which)
-            {
-                case WhichTime.atime:
-                    x = System.IO.File.GetLastAccessTime(filename).ToUniversalTime();
-                    break;
-                case WhichTime.mtime:
-                    x = System.IO.File.GetLastWriteTime(filename).ToUniversalTime();
-                    break;
-                case WhichTime.ctime:
-                    x = System.IO.File.GetCreationTime(filename).ToUniversalTime();
-                    break;
-                default:
-                    throw new ArgumentException("Operator");
-            }
-            CriterionTrace("TimeCriterion({0},{1})= {2}", filename, Which.ToString(), x);
-            return _Evaluate(x);
-        }
-
-
-        private bool _Evaluate(DateTime x)
-        {
-            bool result = false;
-            switch (Operator)
-            {
-                case ComparisonOperator.GreaterThanOrEqualTo:
-                    result = (x >= Time);
-                    break;
-                case ComparisonOperator.GreaterThan:
-                    result = (x > Time);
-                    break;
-                case ComparisonOperator.LesserThanOrEqualTo:
-                    result = (x <= Time);
-                    break;
-                case ComparisonOperator.LesserThan:
-                    result = (x < Time);
-                    break;
-                case ComparisonOperator.EqualTo:
-                    result = (x == Time);
-                    break;
-                case ComparisonOperator.NotEqualTo:
-                    result = (x != Time);
-                    break;
-                default:
-                    throw new ArgumentException("Operator");
-            }
-
-            CriterionTrace("TimeCriterion: {0}", result);
-            return result;
-        }
-    }
-
-
-
-    internal partial class NameCriterion : SelectionCriterion
-    {
-        private Regex _re;
-        private String _regexString;
-        internal ComparisonOperator Operator;
-        private string _MatchingFileSpec;
-        internal virtual string MatchingFileSpec
-        {
-            set
-            {
-                // workitem 8245
-                if (Directory.Exists(value))
-                {
-                    _MatchingFileSpec = ".\\" + value + "\\*.*";
-                }
-                else
-                {
-                    _MatchingFileSpec = value;
-                }
-
-                _regexString = "^" +
-                Regex.Escape(_MatchingFileSpec)
-                    .Replace(@"\\\*\.\*", @"\\([^\.]+|.*\.[^\\\.]*)")
-                    .Replace(@"\.\*", @"\.[^\\\.]*")
-                    .Replace(@"\*", @".*")
-                    //.Replace(@"\*", @"[^\\\.]*") // ill-conceived
-                    .Replace(@"\?", @"[^\\\.]")
-                    + "$";
-
-                CriterionTrace("NameCriterion regexString({0})", _regexString);
-
-                _re = new Regex(_regexString, RegexOptions.IgnoreCase);
-            }
-        }
-
-
-        public override String ToString()
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append("name ").Append(EnumUtil.GetDescription(Operator))
-                .Append(" '")
-                .Append(_MatchingFileSpec)
-                .Append("'");
-            return sb.ToString();
-        }
-
-
-        internal override bool Evaluate(string filename)
-        {
-            CriterionTrace("NameCriterion::Evaluate('{0}' pattern[{1}])",
-                           filename, _MatchingFileSpec);
-            return _Evaluate(filename);
-        }
-
-        private bool _Evaluate(string fullpath)
-        {
-            CriterionTrace("NameCriterion::Evaluate({0})", fullpath);
-            // No slash in the pattern implicitly means recurse, which means compare to
-            // filename only, not full path.
-            String f = (_MatchingFileSpec.IndexOf('\\') == -1)
-                ? System.IO.Path.GetFileName(fullpath)
-                : fullpath; // compare to fullpath
-
-            bool result = _re.IsMatch(f);
-
-            if (Operator != ComparisonOperator.EqualTo)
-                result = !result;
-            return result;
-        }
-    }
-
-
-    internal partial class TypeCriterion : SelectionCriterion
-    {
-        private char ObjectType;  // 'D' = Directory, 'F' = File
-        internal ComparisonOperator Operator;
-        internal string AttributeString
-        {
-            get
-            {
-                return ObjectType.ToString();
-            }
-            set
-            {
-                if (value.Length != 1 ||
-                    (value[0]!='D' && value[0]!='F'))
-                    throw new ArgumentException("Specify a single character: either D or F");
-                ObjectType = value[0];
-            }
-        }
-
-        public override String ToString()
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append("type ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(AttributeString);
-            return sb.ToString();
-        }
-
-        internal override bool Evaluate(string filename)
-        {
-            CriterionTrace("TypeCriterion::Evaluate({0})", filename);
-
-            bool result = (ObjectType == 'D')
-                ? Directory.Exists(filename)
-                : File.Exists(filename);
-
-            if (Operator != ComparisonOperator.EqualTo)
-                result = !result;
-            return result;
-        }
-    }
-
-
-#if !SILVERLIGHT
-    internal partial class AttributesCriterion : SelectionCriterion
-    {
-        private FileAttributes _Attributes;
-        internal ComparisonOperator Operator;
-        internal string AttributeString
-        {
-            get
-            {
-                string result = "";
-                if ((_Attributes & FileAttributes.Hidden) != 0)
-                    result += "H";
-                if ((_Attributes & FileAttributes.System) != 0)
-                    result += "S";
-                if ((_Attributes & FileAttributes.ReadOnly) != 0)
-                    result += "R";
-                if ((_Attributes & FileAttributes.Archive) != 0)
-                    result += "A";
-                if ((_Attributes & FileAttributes.ReparsePoint) != 0)
-                    result += "L";
-                if ((_Attributes & FileAttributes.NotContentIndexed) != 0)
-                    result += "I";
-                return result;
-            }
-
-            set
-            {
-                _Attributes = FileAttributes.Normal;
-                foreach (char c in value.ToUpper(CultureInfo.InvariantCulture))
-                {
-                    switch (c)
-                    {
-                        case 'H':
-                            if ((_Attributes & FileAttributes.Hidden) != 0)
-                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
-                            _Attributes |= FileAttributes.Hidden;
-                            break;
-
-                        case 'R':
-                            if ((_Attributes & FileAttributes.ReadOnly) != 0)
-                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
-                            _Attributes |= FileAttributes.ReadOnly;
-                            break;
-
-                        case 'S':
-                            if ((_Attributes & FileAttributes.System) != 0)
-                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
-                            _Attributes |= FileAttributes.System;
-                            break;
-
-                        case 'A':
-                            if ((_Attributes & FileAttributes.Archive) != 0)
-                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
-                            _Attributes |= FileAttributes.Archive;
-                            break;
-
-                        case 'I':
-                            if ((_Attributes & FileAttributes.NotContentIndexed) != 0)
-                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
-                            _Attributes |= FileAttributes.NotContentIndexed;
-                            break;
-
-                        case 'L':
-                            if ((_Attributes & FileAttributes.ReparsePoint) != 0)
-                                throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
-                            _Attributes |= FileAttributes.ReparsePoint;
-                            break;
-
-                        default:
-                            throw new ArgumentException(value);
-                    }
-                }
-            }
-        }
-
-
-        public override String ToString()
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append("attributes ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(AttributeString);
-            return sb.ToString();
-        }
-
-        private bool _EvaluateOne(FileAttributes fileAttrs, FileAttributes criterionAttrs)
-        {
-            bool result = false;
-            if ((_Attributes & criterionAttrs) == criterionAttrs)
-                result = ((fileAttrs & criterionAttrs) == criterionAttrs);
-            else
-                result = true;
-            return result;
-        }
-
-
-
-        internal override bool Evaluate(string filename)
-        {
-            // workitem 10191
-            if (Directory.Exists(filename))
-            {
-                // Directories don't have file attributes, so the result
-                // of an evaluation is always NO. This gets negated if
-                // the operator is NotEqualTo.
-                return (Operator != ComparisonOperator.EqualTo);
-            }
-#if NETCF
-            FileAttributes fileAttrs = NetCfFile.GetAttributes(filename);
-#else
-            FileAttributes fileAttrs = System.IO.File.GetAttributes(filename);
-#endif
-
-            return _Evaluate(fileAttrs);
-        }
-
-        private bool _Evaluate(FileAttributes fileAttrs)
-        {
-            bool result = _EvaluateOne(fileAttrs, FileAttributes.Hidden);
-            if (result)
-                result = _EvaluateOne(fileAttrs, FileAttributes.System);
-            if (result)
-                result = _EvaluateOne(fileAttrs, FileAttributes.ReadOnly);
-            if (result)
-                result = _EvaluateOne(fileAttrs, FileAttributes.Archive);
-            if (result)
-                result = _EvaluateOne(fileAttrs, FileAttributes.NotContentIndexed);
-            if (result)
-                result = _EvaluateOne(fileAttrs, FileAttributes.ReparsePoint);
-
-            if (Operator != ComparisonOperator.EqualTo)
-                result = !result;
-
-            return result;
-        }
-    }
-#endif
-
-
-    internal partial class CompoundCriterion : SelectionCriterion
-    {
-        internal LogicalConjunction Conjunction;
-        internal SelectionCriterion Left;
-
-        private SelectionCriterion _Right;
-        internal SelectionCriterion Right
-        {
-            get { return _Right; }
-            set
-            {
-                _Right = value;
-                if (value == null)
-                    Conjunction = LogicalConjunction.NONE;
-                else if (Conjunction == LogicalConjunction.NONE)
-                    Conjunction = LogicalConjunction.AND;
-            }
-        }
-
-
-        internal override bool Evaluate(string filename)
-        {
-            bool result = Left.Evaluate(filename);
-            switch (Conjunction)
-            {
-                case LogicalConjunction.AND:
-                    if (result)
-                        result = Right.Evaluate(filename);
-                    break;
-                case LogicalConjunction.OR:
-                    if (!result)
-                        result = Right.Evaluate(filename);
-                    break;
-                case LogicalConjunction.XOR:
-                    result ^= Right.Evaluate(filename);
-                    break;
-                default:
-                    throw new ArgumentException("Conjunction");
-            }
-            return result;
-        }
-
-
-        public override String ToString()
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append("(")
-            .Append((Left != null) ? Left.ToString() : "null")
-            .Append(" ")
-            .Append(Conjunction.ToString())
-            .Append(" ")
-            .Append((Right != null) ? Right.ToString() : "null")
-            .Append(")");
-            return sb.ToString();
-        }
-    }
-
-
-
-    /// <summary>
-    ///   FileSelector encapsulates logic that selects files from a source - a zip file
-    ///   or the filesystem - based on a set of criteria.  This class is used internally
-    ///   by the DotNetZip library, in particular for the AddSelectedFiles() methods.
-    ///   This class can also be used independently of the zip capability in DotNetZip.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///
-    /// <para>
-    ///   The FileSelector class is used internally by the ZipFile class for selecting
-    ///   files for inclusion into the ZipFile, when the <see
-    ///   cref="Ionic.Zip.ZipFile.AddSelectedFiles(String,String)"/> method, or one of
-    ///   its overloads, is called.  It's also used for the <see
-    ///   cref="Ionic.Zip.ZipFile.ExtractSelectedEntries(String)"/> methods.  Typically, an
-    ///   application that creates or manipulates Zip archives will not directly
-    ///   interact with the FileSelector class.
-    /// </para>
-    ///
-    /// <para>
-    ///   Some applications may wish to use the FileSelector class directly, to
-    ///   select files from disk volumes based on a set of criteria, without creating or
-    ///   querying Zip archives.  The file selection criteria include: a pattern to
-    ///   match the filename; the last modified, created, or last accessed time of the
-    ///   file; the size of the file; and the attributes of the file.
-    /// </para>
-    ///
-    /// <para>
-    ///   Consult the documentation for <see cref="SelectionCriteria"/>
-    ///   for more information on specifying the selection criteria.
-    /// </para>
-    ///
-    /// </remarks>
-    internal partial class FileSelector
-    {
-        internal SelectionCriterion _Criterion;
-
-#if NOTUSED
-        /// <summary>
-        ///   The default constructor.
-        /// </summary>
-        /// <remarks>
-        ///   Typically, applications won't use this constructor.  Instead they'll
-        ///   call the constructor that accepts a selectionCriteria string.  If you
-        ///   use this constructor, you'll want to set the SelectionCriteria
-        ///   property on the instance before calling SelectFiles().
-        /// </remarks>
-        protected FileSelector() { }
-#endif
-        /// <summary>
-        ///   Constructor that allows the caller to specify file selection criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This constructor allows the caller to specify a set of criteria for
-        ///   selection of files.
-        /// </para>
-        ///
-        /// <para>
-        ///   See <see cref="FileSelector.SelectionCriteria"/> for a description of
-        ///   the syntax of the selectionCriteria string.
-        /// </para>
-        ///
-        /// <para>
-        ///   By default the FileSelector will traverse NTFS Reparse Points.  To
-        ///   change this, use <see cref="FileSelector(String,
-        ///   bool)">FileSelector(String, bool)</see>.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="selectionCriteria">The criteria for file selection.</param>
-        public FileSelector(String selectionCriteria)
-        : this(selectionCriteria, true)
-        {
-        }
-
-        /// <summary>
-        ///   Constructor that allows the caller to specify file selection criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This constructor allows the caller to specify a set of criteria for
-        ///   selection of files.
-        /// </para>
-        ///
-        /// <para>
-        ///   See <see cref="FileSelector.SelectionCriteria"/> for a description of
-        ///   the syntax of the selectionCriteria string.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="selectionCriteria">The criteria for file selection.</param>
-        /// <param name="traverseDirectoryReparsePoints">
-        /// whether to traverse NTFS reparse points (junctions).
-        /// </param>
-        public FileSelector(String selectionCriteria, bool traverseDirectoryReparsePoints)
-        {
-            if (!String.IsNullOrEmpty(selectionCriteria))
-                _Criterion = _ParseCriterion(selectionCriteria);
-            TraverseReparsePoints = traverseDirectoryReparsePoints;
-        }
-
-
-
-        /// <summary>
-        ///   The string specifying which files to include when retrieving.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Specify the criteria in statements of 3 elements: a noun, an operator,
-        ///   and a value.  Consider the string "name != *.doc" .  The noun is
-        ///   "name".  The operator is "!=", implying "Not Equal".  The value is
-        ///   "*.doc".  That criterion, in English, says "all files with a name that
-        ///   does not end in the .doc extension."
-        /// </para>
-        ///
-        /// <para>
-        ///   Supported nouns include "name" (or "filename") for the filename;
-        ///   "atime", "mtime", and "ctime" for last access time, last modfied time,
-        ///   and created time of the file, respectively; "attributes" (or "attrs")
-        ///   for the file attributes; "size" (or "length") for the file length
-        ///   (uncompressed); and "type" for the type of object, either a file or a
-        ///   directory.  The "attributes", "type", and "name" nouns all support =
-        ///   and != as operators.  The "size", "atime", "mtime", and "ctime" nouns
-        ///   support = and !=, and &gt;, &gt;=, &lt;, &lt;= as well.  The times are
-        ///   taken to be expressed in local time.
-        /// </para>
-        ///
-        /// <para>
-        ///   Specify values for the file attributes as a string with one or more of
-        ///   the characters H,R,S,A,I,L in any order, implying file attributes of
-        ///   Hidden, ReadOnly, System, Archive, NotContextIndexed, and ReparsePoint
-        ///   (symbolic link) respectively.
-        /// </para>
-        ///
-        /// <para>
-        ///   To specify a time, use YYYY-MM-DD-HH:mm:ss or YYYY/MM/DD-HH:mm:ss as
-        ///   the format.  If you omit the HH:mm:ss portion, it is assumed to be
-        ///   00:00:00 (midnight).
-        /// </para>
-        ///
-        /// <para>
-        ///   The value for a size criterion is expressed in integer quantities of
-        ///   bytes, kilobytes (use k or kb after the number), megabytes (m or mb),
-        ///   or gigabytes (g or gb).
-        /// </para>
-        ///
-        /// <para>
-        ///   The value for a name is a pattern to match against the filename,
-        ///   potentially including wildcards.  The pattern follows CMD.exe glob
-        ///   rules: * implies one or more of any character, while ?  implies one
-        ///   character.  If the name pattern contains any slashes, it is matched to
-        ///   the entire filename, including the path; otherwise, it is matched
-        ///   against only the filename without the path.  This means a pattern of
-        ///   "*\*.*" matches all files one directory level deep, while a pattern of
-        ///   "*.*" matches all files in all directories.
-        /// </para>
-        ///
-        /// <para>
-        ///   To specify a name pattern that includes spaces, use single quotes
-        ///   around the pattern.  A pattern of "'* *.*'" will match all files that
-        ///   have spaces in the filename.  The full criteria string for that would
-        ///   be "name = '* *.*'" .
-        /// </para>
-        ///
-        /// <para>
-        ///   The value for a type criterion is either F (implying a file) or D
-        ///   (implying a directory).
-        /// </para>
-        ///
-        /// <para>
-        ///   Some examples:
-        /// </para>
-        ///
-        /// <list type="table">
-        ///   <listheader>
-        ///     <term>criteria</term>
-        ///     <description>Files retrieved</description>
-        ///   </listheader>
-        ///
-        ///   <item>
-        ///     <term>name != *.xls </term>
-        ///     <description>any file with an extension that is not .xls
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>name = *.mp3 </term>
-        ///     <description>any file with a .mp3 extension.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>*.mp3</term>
-        ///     <description>(same as above) any file with a .mp3 extension.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>attributes = A </term>
-        ///     <description>all files whose attributes include the Archive bit.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>attributes != H </term>
-        ///     <description>all files whose attributes do not include the Hidden bit.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>mtime > 2009-01-01</term>
-        ///     <description>all files with a last modified time after January 1st, 2009.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>ctime > 2009/01/01-03:00:00</term>
-        ///     <description>all files with a created time after 3am (local time),
-        ///     on January 1st, 2009.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>size > 2gb</term>
-        ///     <description>all files whose uncompressed size is greater than 2gb.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>type = D</term>
-        ///     <description>all directories in the filesystem. </description>
-        ///   </item>
-        ///
-        /// </list>
-        ///
-        /// <para>
-        ///   You can combine criteria with the conjunctions AND, OR, and XOR. Using
-        ///   a string like "name = *.txt AND size &gt;= 100k" for the
-        ///   selectionCriteria retrieves entries whose names end in .txt, and whose
-        ///   uncompressed size is greater than or equal to 100 kilobytes.
-        /// </para>
-        ///
-        /// <para>
-        ///   For more complex combinations of criteria, you can use parenthesis to
-        ///   group clauses in the boolean logic.  Absent parenthesis, the
-        ///   precedence of the criterion atoms is determined by order of
-        ///   appearance.  Unlike the C# language, the AND conjunction does not take
-        ///   precendence over the logical OR.  This is important only in strings
-        ///   that contain 3 or more criterion atoms.  In other words, "name = *.txt
-        ///   and size &gt; 1000 or attributes = H" implies "((name = *.txt AND size
-        ///   &gt; 1000) OR attributes = H)" while "attributes = H OR name = *.txt
-        ///   and size &gt; 1000" evaluates to "((attributes = H OR name = *.txt)
-        ///   AND size &gt; 1000)".  When in doubt, use parenthesis.
-        /// </para>
-        ///
-        /// <para>
-        ///   Using time properties requires some extra care. If you want to
-        ///   retrieve all entries that were last updated on 2009 February 14,
-        ///   specify "mtime &gt;= 2009-02-14 AND mtime &lt; 2009-02-15".  Read this
-        ///   to say: all files updated after 12:00am on February 14th, until
-        ///   12:00am on February 15th.  You can use the same bracketing approach to
-        ///   specify any time period - a year, a month, a week, and so on.
-        /// </para>
-        ///
-        /// <para>
-        ///   The syntax allows one special case: if you provide a string with no
-        ///   spaces, it is treated as a pattern to match for the filename.
-        ///   Therefore a string like "*.xls" will be equivalent to specifying "name
-        ///   = *.xls".  This "shorthand" notation does not work with compound
-        ///   criteria.
-        /// </para>
-        ///
-        /// <para>
-        ///   There is no logic in this class that insures that the inclusion
-        ///   criteria are internally consistent.  For example, it's possible to
-        ///   specify criteria that says the file must have a size of less than 100
-        ///   bytes, as well as a size that is greater than 1000 bytes.  Obviously
-        ///   no file will ever satisfy such criteria, but this class does not check
-        ///   for or detect such inconsistencies.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="System.Exception">
-        ///   Thrown in the setter if the value has an invalid syntax.
-        /// </exception>
-        public String SelectionCriteria
-        {
-            get
-            {
-                if (_Criterion == null) return null;
-                return _Criterion.ToString();
-            }
-            set
-            {
-                if (value == null) _Criterion = null;
-                else if (value.Trim() == "") _Criterion = null;
-                else
-                    _Criterion = _ParseCriterion(value);
-            }
-        }
-
-        /// <summary>
-        ///  Indicates whether searches will traverse NTFS reparse points, like Junctions.
-        /// </summary>
-        public bool TraverseReparsePoints
-        {
-            get; set;
-        }
-
-
-        private enum ParseState
-        {
-            Start,
-            OpenParen,
-            CriterionDone,
-            ConjunctionPending,
-            Whitespace,
-        }
-
-
-        private static class RegexAssertions
-        {
-            public static readonly String PrecededByOddNumberOfSingleQuotes = "(?<=(?:[^']*'[^']*')*'[^']*)";
-            public static readonly String FollowedByOddNumberOfSingleQuotesAndLineEnd = "(?=[^']*'(?:[^']*'[^']*')*[^']*$)";
-
-            public static readonly String PrecededByEvenNumberOfSingleQuotes = "(?<=(?:[^']*'[^']*')*[^']*)";
-            public static readonly String FollowedByEvenNumberOfSingleQuotesAndLineEnd = "(?=(?:[^']*'[^']*')*[^']*$)";
-        }
-
-
-        private static string NormalizeCriteriaExpression(string source)
-        {
-            // The goal here is to normalize the criterion expression. At output, in
-            // the transformed criterion string, every significant syntactic element
-            // - a property element, grouping paren for the boolean logic, operator
-            // ( = < > != ), conjunction, or property value - will be separated from
-            // its neighbors by at least one space. Thus,
-            //
-            // before                         after
-            // -------------------------------------------------------------------
-            // name=*.txt                     name = *.txt
-            // (size>100)AND(name=*.txt)      ( size > 100 ) AND ( name = *.txt )
-            //
-            // This is relatively straightforward using regular expression
-            // replacement. This method applies a distinct regex pattern and
-            // corresponding replacement string for each one of a number of cases:
-            // an open paren followed by a word; a word followed by a close-paren; a
-            // pair of open parens; a close paren followed by a word (which should
-            // then be followed by an open paren). And so on. These patterns and
-            // replacements are all stored in prPairs. By applying each of these
-            // regex replacements in turn, we get the transformed string. Easy.
-            //
-            // The resulting "normalized" criterion string, is then used as the
-            // subject that gets parsed, by splitting the string into tokens that
-            // are separated by spaces.  Here, there's a twist. The spaces within
-            // single-quote delimiters do not delimit distinct tokens.  So, this
-            // normalization method temporarily replaces those spaces with
-            // ASCII 6 (0x06), a control character which is not a legal
-            // character in a filename. The parsing logic that happens later will
-            // revert that change, restoring the original value of the filename
-            // specification.
-            //
-            // To illustrate, for a "before" string of [(size>100)AND(name='Name
-            // (with Parens).txt')] , the "after" string is [( size > 100 ) AND
-            // ( name = 'Name\u0006(with\u0006Parens).txt' )].
-            //
-
-            string[][] prPairs =
-                {
-                    // A. opening double parens - insert a space between them
-                    new string[] { @"([^']*)\(\(([^']+)", "$1( ($2" },
-
-                    // B. closing double parens - insert a space between
-                    new string[] { @"(.)\)\)", "$1) )" },
-
-                    // C. single open paren with a following word - insert a space between
-                    new string[] { @"\((\S)", "( $1" },
-
-                    // D. single close paren with a preceding word - insert a space between the two
-                    new string[] { @"(\S)\)", "$1 )" },
-
-                    // E. close paren at line start?, insert a space before the close paren
-                    // this seems like a degenerate case.  I don't recall why it's here.
-                    new string[] { @"^\)", " )" },
-
-                    // F. a word (likely a conjunction) followed by an open paren - insert a space between
-                    new string[] { @"(\S)\(", "$1 (" },
-
-                    // G. single close paren followed by word - insert a paren after close paren
-                    new string[] { @"\)(\S)", ") $1" },
-
-                    // H. insert space between = and a following single quote
-                    //new string[] { @"(=|!=)('[^']*')", "$1 $2" },
-                    new string[] { @"(=)('[^']*')", "$1 $2" },
-
-                    // I. insert space between property names and the following operator
-                    //new string[] { @"([^ ])([><(?:!=)=])", "$1 $2" },
-                    new string[] { @"([^ !><])(>|<|!=|=)", "$1 $2" },
-
-                    // J. insert spaces between operators and the following values
-                    //new string[] { @"([><(?:!=)=])([^ ])", "$1 $2" },
-                    new string[] { @"(>|<|!=|=)([^ =])", "$1 $2" },
-
-                    // K. replace fwd slash with backslash
-                    new string[] { @"/", "\\" },
-                };
-
-            string interim = source;
-
-            for (int i=0; i < prPairs.Length; i++)
-            {
-                //char caseIdx = (char)('A' + i);
-                string pattern = RegexAssertions.PrecededByEvenNumberOfSingleQuotes +
-                    prPairs[i][0] +
-                    RegexAssertions.FollowedByEvenNumberOfSingleQuotesAndLineEnd;
-
-                interim = Regex.Replace(interim, pattern, prPairs[i][1]);
-            }
-
-            // match a fwd slash, followed by an odd number of single quotes.
-            // This matches fwd slashes only inside a pair of single quote delimiters,
-            // eg, a filename.  This must be done as well as the case above, to handle
-            // filenames specified inside quotes as well as filenames without quotes.
-            var regexPattern = @"/" +
-                                RegexAssertions.FollowedByOddNumberOfSingleQuotesAndLineEnd;
-            // replace with backslash
-            interim = Regex.Replace(interim, regexPattern, "\\");
-
-            // match a space, followed by an odd number of single quotes.
-            // This matches spaces only inside a pair of single quote delimiters.
-            regexPattern = " " +
-                RegexAssertions.FollowedByOddNumberOfSingleQuotesAndLineEnd;
-
-            // Replace all spaces that appear inside single quotes, with
-            // ascii 6.  This allows a split on spaces to get tokens in
-            // the expression. The split will not split any filename or
-            // wildcard that appears within single quotes. After tokenizing, we
-            // need to replace ascii 6 with ascii 32 to revert the
-            // spaces within quotes.
-            return Regex.Replace(interim, regexPattern, "\u0006");
-        }
-
-
-        private static SelectionCriterion _ParseCriterion(String s)
-        {
-            if (s == null) return null;
-
-            // inject spaces after open paren and before close paren, etc
-            s = NormalizeCriteriaExpression(s);
-
-            // no spaces in the criteria is shorthand for filename glob
-            if (s.IndexOf(" ") == -1)
-                s = "name = " + s;
-
-            // split the expression into tokens
-            string[] tokens = s.Trim().Split(' ', '\t');
-
-            if (tokens.Length < 3) throw new ArgumentException(s);
-
-            SelectionCriterion current = null;
-
-            LogicalConjunction pendingConjunction = LogicalConjunction.NONE;
-
-            ParseState state;
-            var stateStack = new System.Collections.Generic.Stack<ParseState>();
-            var critStack = new System.Collections.Generic.Stack<SelectionCriterion>();
-            stateStack.Push(ParseState.Start);
-
-            for (int i = 0; i < tokens.Length; i++)
-            {
-                string tok1 = tokens[i].ToLower(CultureInfo.InvariantCulture);
-                switch (tok1)
-                {
-                    case "and":
-                    case "xor":
-                    case "or":
-                        state = stateStack.Peek();
-                        if (state != ParseState.CriterionDone)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        if (tokens.Length <= i + 3)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        pendingConjunction = (LogicalConjunction)Enum.Parse(typeof(LogicalConjunction), tokens[i].ToUpper(CultureInfo.InvariantCulture), true);
-                        current = new CompoundCriterion { Left = current, Right = null, Conjunction = pendingConjunction };
-                        stateStack.Push(state);
-                        stateStack.Push(ParseState.ConjunctionPending);
-                        critStack.Push(current);
-                        break;
-
-                    case "(":
-                        state = stateStack.Peek();
-                        if (state != ParseState.Start && state != ParseState.ConjunctionPending && state != ParseState.OpenParen)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        if (tokens.Length <= i + 4)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        stateStack.Push(ParseState.OpenParen);
-                        break;
-
-                    case ")":
-                        state = stateStack.Pop();
-                        if (stateStack.Peek() != ParseState.OpenParen)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        stateStack.Pop();
-                        stateStack.Push(ParseState.CriterionDone);
-                        break;
-
-                    case "atime":
-                    case "ctime":
-                    case "mtime":
-                        if (tokens.Length <= i + 2)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        DateTime t;
-                        try
-                        {
-                            t = DateTime.ParseExact(tokens[i + 2], "yyyy-MM-dd-HH:mm:ss", null);
-                        }
-                        catch (FormatException)
-                        {
-                            try
-                            {
-                                t = DateTime.ParseExact(tokens[i + 2], "yyyy/MM/dd-HH:mm:ss", null);
-                            }
-                            catch (FormatException)
-                            {
-                                try
-                                {
-                                    t = DateTime.ParseExact(tokens[i + 2], "yyyy/MM/dd", null);
-                                }
-                                catch (FormatException)
-                                {
-                                    try
-                                    {
-                                        t = DateTime.ParseExact(tokens[i + 2], "MM/dd/yyyy", null);
-                                    }
-                                    catch (FormatException)
-                                    {
-                                        t = DateTime.ParseExact(tokens[i + 2], "yyyy-MM-dd", null);
-                                    }
-                                }
-                            }
-                        }
-                        t= DateTime.SpecifyKind(t, DateTimeKind.Local).ToUniversalTime();
-                        current = new TimeCriterion
-                        {
-                            Which = (WhichTime)Enum.Parse(typeof(WhichTime), tokens[i], true),
-                            Operator = (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]),
-                            Time = t
-                        };
-                        i += 2;
-                        stateStack.Push(ParseState.CriterionDone);
-                        break;
-
-
-                    case "length":
-                    case "size":
-                        if (tokens.Length <= i + 2)
-                            throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                        Int64 sz = 0;
-                        string v = tokens[i + 2];
-                        if (v.EndsWith("K", StringComparison.InvariantCultureIgnoreCase))
-                            sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024;
-                        else if (v.EndsWith("KB", StringComparison.InvariantCultureIgnoreCase))
-                            sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024;
-                        else if (v.EndsWith("M", StringComparison.InvariantCultureIgnoreCase))
-                            sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024 * 1024;
-                        else if (v.EndsWith("MB", StringComparison.InvariantCultureIgnoreCase))
-                            sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024 * 1024;
-                        else if (v.EndsWith("G", StringComparison.InvariantCultureIgnoreCase))
-                            sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024 * 1024 * 1024;
-                        else if (v.EndsWith("GB", StringComparison.InvariantCultureIgnoreCase))
-                            sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024 * 1024 * 1024;
-                        else sz = Int64.Parse(tokens[i + 2]);
-
-                        current = new SizeCriterion
-                        {
-                            Size = sz,
-                            Operator = (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1])
-                        };
-                        i += 2;
-                        stateStack.Push(ParseState.CriterionDone);
-                        break;
-
-                    case "filename":
-                    case "name":
-                        {
-                            if (tokens.Length <= i + 2)
-                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                            ComparisonOperator c =
-                                (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]);
-
-                            if (c != ComparisonOperator.NotEqualTo && c != ComparisonOperator.EqualTo)
-                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                            string m = tokens[i + 2];
-
-                            // handle single-quoted filespecs (used to include
-                            // spaces in filename patterns)
-                            if (m.StartsWith("'") && m.EndsWith("'"))
-                            {
-                                // trim off leading and trailing single quotes and
-                                // revert the control characters to spaces.
-                                m = m.Substring(1, m.Length - 2)
-                                    .Replace("\u0006", " ");
-                            }
-
-                            // if (m.StartsWith("'"))
-                            //     m = m.Replace("\u0006", " ");
-
-                            current = new NameCriterion
-                            {
-                                MatchingFileSpec = m,
-                                Operator = c
-                            };
-                            i += 2;
-                            stateStack.Push(ParseState.CriterionDone);
-                        }
-                        break;
-
-#if !SILVERLIGHT
-                    case "attrs":
-                    case "attributes":
-#endif
-                    case "type":
-                        {
-                            if (tokens.Length <= i + 2)
-                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-                            ComparisonOperator c =
-                                (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]);
-
-                            if (c != ComparisonOperator.NotEqualTo && c != ComparisonOperator.EqualTo)
-                                throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-#if SILVERLIGHT
-                            current = (SelectionCriterion) new TypeCriterion
-                                    {
-                                        AttributeString = tokens[i + 2],
-                                        Operator = c
-                                    };
-#else
-                            current = (tok1 == "type")
-                                ? (SelectionCriterion) new TypeCriterion
-                                    {
-                                        AttributeString = tokens[i + 2],
-                                        Operator = c
-                                    }
-                                : (SelectionCriterion) new AttributesCriterion
-                                    {
-                                        AttributeString = tokens[i + 2],
-                                        Operator = c
-                                    };
-#endif
-                            i += 2;
-                            stateStack.Push(ParseState.CriterionDone);
-                        }
-                        break;
-
-                    case "":
-                        // NOP
-                        stateStack.Push(ParseState.Whitespace);
-                        break;
-
-                    default:
-                        throw new ArgumentException("'" + tokens[i] + "'");
-                }
-
-                state = stateStack.Peek();
-                if (state == ParseState.CriterionDone)
-                {
-                    stateStack.Pop();
-                    if (stateStack.Peek() == ParseState.ConjunctionPending)
-                    {
-                        while (stateStack.Peek() == ParseState.ConjunctionPending)
-                        {
-                            var cc = critStack.Pop() as CompoundCriterion;
-                            cc.Right = current;
-                            current = cc; // mark the parent as current (walk up the tree)
-                            stateStack.Pop();   // the conjunction is no longer pending
-
-                            state = stateStack.Pop();
-                            if (state != ParseState.CriterionDone)
-                                throw new ArgumentException("??");
-                        }
-                    }
-                    else stateStack.Push(ParseState.CriterionDone);  // not sure?
-                }
-
-                if (state == ParseState.Whitespace)
-                    stateStack.Pop();
-            }
-
-            return current;
-        }
-
-
-        /// <summary>
-        /// Returns a string representation of the FileSelector object.
-        /// </summary>
-        /// <returns>The string representation of the boolean logic statement of the file
-        /// selection criteria for this instance. </returns>
-        public override String ToString()
-        {
-            return "FileSelector("+_Criterion.ToString()+")";
-        }
-
-
-        private bool Evaluate(string filename)
-        {
-            // dinoch - Thu, 11 Feb 2010  18:34
-            SelectorTrace("Evaluate({0})", filename);
-            bool result = _Criterion.Evaluate(filename);
-            return result;
-        }
-
-        [System.Diagnostics.Conditional("SelectorTrace")]
-        private void SelectorTrace(string format, params object[] args)
-        {
-            if (_Criterion != null && _Criterion.Verbose)
-                System.Console.WriteLine(format, args);
-        }
-
-        /// <summary>
-        ///   Returns the names of the files in the specified directory
-        ///   that fit the selection criteria specified in the FileSelector.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This is equivalent to calling <see cref="SelectFiles(String, bool)"/>
-        ///   with recurseDirectories = false.
-        /// </remarks>
-        ///
-        /// <param name="directory">
-        ///   The name of the directory over which to apply the FileSelector
-        ///   criteria.
-        /// </param>
-        ///
-        /// <returns>
-        ///   A collection of strings containing fully-qualified pathnames of files
-        ///   that match the criteria specified in the FileSelector instance.
-        /// </returns>
-        public System.Collections.Generic.ICollection<String> SelectFiles(String directory)
-        {
-            return SelectFiles(directory, false);
-        }
-
-
-        /// <summary>
-        ///   Returns the names of the files in the specified directory that fit the
-        ///   selection criteria specified in the FileSelector, optionally recursing
-        ///   through subdirectories.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This method applies the file selection criteria contained in the
-        ///   FileSelector to the files contained in the given directory, and
-        ///   returns the names of files that conform to the criteria.
-        /// </remarks>
-        ///
-        /// <param name="directory">
-        ///   The name of the directory over which to apply the FileSelector
-        ///   criteria.
-        /// </param>
-        ///
-        /// <param name="recurseDirectories">
-        ///   Whether to recurse through subdirectories when applying the file
-        ///   selection criteria.
-        /// </param>
-        ///
-        /// <returns>
-        ///   A collection of strings containing fully-qualified pathnames of files
-        ///   that match the criteria specified in the FileSelector instance.
-        /// </returns>
-        public System.Collections.ObjectModel.ReadOnlyCollection<String>
-            SelectFiles(String directory,
-                        bool recurseDirectories)
-        {
-            if (_Criterion == null)
-                throw new ArgumentException("SelectionCriteria has not been set");
-
-            var list = new List<String>();
-            try
-            {
-                if (Directory.Exists(directory))
-                {
-                    String[] filenames = Directory.GetFiles(directory);
-
-                    // add the files:
-                    foreach (String filename in filenames)
-                    {
-                        if (Evaluate(filename))
-                            list.Add(filename);
-                    }
-
-                    if (recurseDirectories)
-                    {
-                        // add the subdirectories:
-                        String[] dirnames = Directory.GetDirectories(directory);
-                        foreach (String dir in dirnames)
-                        {
-                            if (this.TraverseReparsePoints
-#if !SILVERLIGHT
-                                || ((File.GetAttributes(dir) & FileAttributes.ReparsePoint) == 0)
-#endif
-                                )
-                            {
-                                // workitem 10191
-                                if (Evaluate(dir)) list.Add(dir);
-                                list.AddRange(this.SelectFiles(dir, recurseDirectories));
-                            }
-                        }
-                    }
-                }
-            }
-            // can get System.UnauthorizedAccessException here
-            catch (System.UnauthorizedAccessException)
-            {
-            }
-            catch (System.IO.IOException)
-            {
-            }
-
-            return list.AsReadOnly();
-        }
-    }
-
-
-
-    /// <summary>
-    /// Summary description for EnumUtil.
-    /// </summary>
-    internal sealed class EnumUtil
-    {
-        private EnumUtil() { }
-        /// <summary>
-        ///   Returns the value of the DescriptionAttribute if the specified Enum
-        ///   value has one.  If not, returns the ToString() representation of the
-        ///   Enum value.
-        /// </summary>
-        /// <param name="value">The Enum to get the description for</param>
-        /// <returns></returns>
-        internal static string GetDescription(System.Enum value)
-        {
-            FieldInfo fi = value.GetType().GetField(value.ToString());
-            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
-            if (attributes.Length > 0)
-                return attributes[0].Description;
-            else
-                return value.ToString();
-        }
-
-        /// <summary>
-        ///   Converts the string representation of the name or numeric value of one
-        ///   or more enumerated constants to an equivalent enumerated object.
-        ///   Note: use the DescriptionAttribute on enum values to enable this.
-        /// </summary>
-        /// <param name="enumType">The System.Type of the enumeration.</param>
-        /// <param name="stringRepresentation">
-        ///   A string containing the name or value to convert.
-        /// </param>
-        /// <returns></returns>
-        internal static object Parse(Type enumType, string stringRepresentation)
-        {
-            return Parse(enumType, stringRepresentation, false);
-        }
-
-
-#if SILVERLIGHT
-       public static System.Enum[] GetEnumValues(Type type)
-        {
-            if (!type.IsEnum)
-                throw new ArgumentException("not an enum");
-
-            return (
-              from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
-              where field.IsLiteral
-              select (System.Enum)field.GetValue(null)
-            ).ToArray();
-        }
-
-        public static string[] GetEnumStrings<T>()
-        {
-            var type = typeof(T);
-            if (!type.IsEnum)
-                throw new ArgumentException("not an enum");
-
-            return (
-              from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
-              where field.IsLiteral
-              select field.Name
-            ).ToArray();
-        }
-#endif
-
-        /// <summary>
-        ///   Converts the string representation of the name or numeric value of one
-        ///   or more enumerated constants to an equivalent enumerated object.  A
-        ///   parameter specified whether the operation is case-sensitive.  Note:
-        ///   use the DescriptionAttribute on enum values to enable this.
-        /// </summary>
-        /// <param name="enumType">The System.Type of the enumeration.</param>
-        /// <param name="stringRepresentation">
-        ///   A string containing the name or value to convert.
-        /// </param>
-        /// <param name="ignoreCase">
-        ///   Whether the operation is case-sensitive or not.</param>
-        /// <returns></returns>
-        internal static object Parse(Type enumType, string stringRepresentation, bool ignoreCase)
-        {
-            if (ignoreCase)
-                stringRepresentation = stringRepresentation.ToLower(CultureInfo.InvariantCulture);
-
-#if SILVERLIGHT
-            foreach (System.Enum enumVal in GetEnumValues(enumType))
-#else
-            foreach (System.Enum enumVal in System.Enum.GetValues(enumType))
-#endif
-            {
-                string description = GetDescription(enumVal);
-                if (ignoreCase)
-                    description = description.ToLower(CultureInfo.InvariantCulture);
-                if (description == stringRepresentation)
-                    return enumVal;
-            }
-
-            return System.Enum.Parse(enumType, stringRepresentation, ignoreCase);
-        }
-    }
-
-
-#if DEMO
-    internal class DemonstrateFileSelector
-    {
-        private string _directory;
-        private bool _recurse;
-        private bool _traverse;
-        private bool _verbose;
-        private string _selectionCriteria;
-        private FileSelector f;
-
-        public DemonstrateFileSelector()
-        {
-            this._directory = ".";
-            this._recurse = true;
-        }
-
-        public DemonstrateFileSelector(string[] args) : this()
-        {
-            for (int i = 0; i < args.Length; i++)
-            {
-                switch(args[i])
-                {
-                case"-?":
-                    Usage();
-                    Environment.Exit(0);
-                    break;
-                case "-d":
-                    i++;
-                    if (args.Length <= i)
-                        throw new ArgumentException("-directory");
-                    this._directory = args[i];
-                    break;
-                case "-norecurse":
-                    this._recurse = false;
-                    break;
-
-                case "-j-":
-                    this._traverse = false;
-                    break;
-
-                case "-j+":
-                    this._traverse = true;
-                    break;
-
-                case "-v":
-                    this._verbose = true;
-                    break;
-
-                default:
-                    if (this._selectionCriteria != null)
-                        throw new ArgumentException(args[i]);
-                    this._selectionCriteria = args[i];
-                    break;
-                }
-
-                if (this._selectionCriteria != null)
-                    this.f = new FileSelector(this._selectionCriteria);
-            }
-        }
-
-
-        public static void Main(string[] args)
-        {
-            try
-            {
-                Console.WriteLine();
-                new DemonstrateFileSelector(args).Run();
-            }
-            catch (Exception exc1)
-            {
-                Console.WriteLine("Exception: {0}", exc1.ToString());
-                Usage();
-            }
-        }
-
-
-        public void Run()
-        {
-            if (this.f == null)
-                this.f = new FileSelector("name = *.jpg AND (size > 1000 OR atime < 2009-02-14-01:00:00)");
-
-            this.f.TraverseReparsePoints = _traverse;
-            this.f.Verbose = this._verbose;
-            Console.WriteLine();
-            Console.WriteLine(new String(':', 88));
-            Console.WriteLine("Selecting files:\n" + this.f.ToString());
-            var files = this.f.SelectFiles(this._directory, this._recurse);
-            if (files.Count == 0)
-            {
-                Console.WriteLine("no files.");
-            }
-            else
-            {
-                Console.WriteLine("files: {0}", files.Count);
-                foreach (string file in files)
-                {
-                    Console.WriteLine("  " + file);
-                }
-            }
-        }
-
-        public static void Usage()
-        {
-            Console.WriteLine("FileSelector: select files based on selection criteria.\n");
-            Console.WriteLine("Usage:\n  FileSelector <selectionCriteria>  [options]\n" +
-                              "\n" +
-                              "  -d <dir>   directory to select from (Default .)\n" +
-                              " -norecurse  don't recurse into subdirs\n" +
-                              " -j-         don't traverse junctions\n" +
-                              " -v          verbose output\n");
-        }
-    }
-
-#endif
-
-
-
-}
-
-
diff --git a/EPPlus/Packaging/DotNetZip/OffsetStream.cs b/EPPlus/Packaging/DotNetZip/OffsetStream.cs
deleted file mode 100644
index c1156d0..0000000
--- a/EPPlus/Packaging/DotNetZip/OffsetStream.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-// OffsetStream.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: <2009-August-27 12:50:35>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for handling reading of zip archives embedded 
-// into larger streams.  The initial position of the stream serves as
-// the base offset for all future Seek() operations.
-// 
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal class OffsetStream : System.IO.Stream, System.IDisposable
-    {
-        private Int64 _originalPosition;
-        private Stream _innerStream;
-
-        public OffsetStream(Stream s)
-            : base()
-        {
-            _originalPosition = s.Position;
-            _innerStream = s;
-        }
-
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            return _innerStream.Read(buffer, offset, count);
-        }
-
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override bool CanRead
-        {
-            get { return _innerStream.CanRead; }
-        }
-
-        public override bool CanSeek
-        {
-            get { return _innerStream.CanSeek; }
-        }
-
-        public override bool CanWrite
-        {
-            get { return false; }
-        }
-
-        public override void Flush()
-        {
-            _innerStream.Flush();
-        }
-
-        public override long Length
-        {
-            get
-            {
-                return _innerStream.Length;
-            }
-        }
-
-        public override long Position
-        {
-            get { return _innerStream.Position - _originalPosition; }
-            set { _innerStream.Position = _originalPosition + value; }
-        }
-
-
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            return _innerStream.Seek(_originalPosition + offset, origin) - _originalPosition;
-        }
-
-
-        public override void SetLength(long value)
-        {
-            throw new NotImplementedException();
-        }
-
-        void IDisposable.Dispose()
-        {
-            Close();
-        }
-
-        public override void Close()
-        {
-            base.Close();
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Shared.cs b/EPPlus/Packaging/DotNetZip/Shared.cs
deleted file mode 100644
index ca8f18c..0000000
--- a/EPPlus/Packaging/DotNetZip/Shared.cs
+++ /dev/null
@@ -1,901 +0,0 @@
-// Shared.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006-2011 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: <2011-August-02 19:41:01>
-//
-// ------------------------------------------------------------------
-//
-// This module defines some shared utility classes and methods.
-//
-// Created: Tue, 27 Mar 2007  15:30
-//
-
-using System;
-using System.IO;
-using System.Security.Permissions;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    /// Collects general purpose utility methods.
-    /// </summary>
-    internal static class SharedUtilities
-    {
-        /// private null constructor
-        //private SharedUtilities() { }
-
-        // workitem 8423
-        public static Int64 GetFileLength(string fileName)
-        {
-            if (!File.Exists(fileName))
-                throw new System.IO.FileNotFoundException(fileName);
-
-            long fileLength = 0L;
-            FileShare fs = FileShare.ReadWrite;
-#if !NETCF
-            // FileShare.Delete is not defined for the Compact Framework
-            fs |= FileShare.Delete;
-#endif
-            using (var s = File.Open(fileName, FileMode.Open, FileAccess.Read, fs))
-            {
-                fileLength = s.Length;
-            }
-            return fileLength;
-        }
-
-
-        [System.Diagnostics.Conditional("NETCF")]
-        public static void Workaround_Ladybug318918(Stream s)
-        {
-            // This is a workaround for this issue:
-            // https://connect.microsoft.com/VisualStudio/feedback/details/318918
-            // It's required only on NETCF.
-            s.Flush();
-        }
-
-
-#if LEGACY
-        /// <summary>
-        /// Round the given DateTime value to an even second value.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// Round up in the case of an odd second value.  The rounding does not consider
-        /// fractional seconds.
-        /// </para>
-        /// <para>
-        /// This is useful because the Zip spec allows storage of time only to the nearest
-        /// even second.  So if you want to compare the time of an entry in the archive with
-        /// it's actual time in the filesystem, you need to round the actual filesystem
-        /// time, or use a 2-second threshold for the comparison.
-        /// </para>
-        /// <para>
-        /// This is most nautrally an extension method for the DateTime class but this
-        /// library is built for .NET 2.0, not for .NET 3.5; This means extension methods
-        /// are a no-no.
-        /// </para>
-        /// </remarks>
-        /// <param name="source">The DateTime value to round</param>
-        /// <returns>The ruonded DateTime value</returns>
-        public static DateTime RoundToEvenSecond(DateTime source)
-        {
-            // round to nearest second:
-            if ((source.Second % 2) == 1)
-                source += new TimeSpan(0, 0, 1);
-
-            DateTime dtRounded = new DateTime(source.Year, source.Month, source.Day, source.Hour, source.Minute, source.Second);
-            //if (source.Millisecond >= 500) dtRounded = dtRounded.AddSeconds(1);
-            return dtRounded;
-        }
-#endif
-
-#if YOU_LIKE_REDUNDANT_CODE
-        internal static string NormalizePath(string path)
-        {
-            // remove leading single dot slash
-            if (path.StartsWith(".\\")) path = path.Substring(2);
-
-            // remove intervening dot-slash
-            path = path.Replace("\\.\\", "\\");
-
-            // remove double dot when preceded by a directory name
-            var re = new System.Text.RegularExpressions.Regex(@"^(.*\\)?([^\\\.]+\\\.\.\\)(.+)$");
-            path = re.Replace(path, "$1$3");
-            return path;
-        }
-#endif
-
-        private static System.Text.RegularExpressions.Regex doubleDotRegex1 =
-            new System.Text.RegularExpressions.Regex(@"^(.*/)?([^/\\.]+/\\.\\./)(.+)$");
-
-        private static string SimplifyFwdSlashPath(string path)
-        {
-            if (path.StartsWith("./")) path = path.Substring(2);
-            path = path.Replace("/./", "/");
-
-            // Replace foo/anything/../bar with foo/bar
-            path = doubleDotRegex1.Replace(path, "$1$3");
-            return path;
-        }
-
-
-        /// <summary>
-        /// Utility routine for transforming path names from filesystem format (on Windows that means backslashes) to
-        /// a format suitable for use within zipfiles. This means trimming the volume letter and colon (if any) And
-        /// swapping backslashes for forward slashes.
-        /// </summary>
-        /// <param name="pathName">source path.</param>
-        /// <returns>transformed path</returns>
-        public static string NormalizePathForUseInZipFile(string pathName)
-        {
-            // boundary case
-            if (String.IsNullOrEmpty(pathName)) return pathName;
-
-            // trim volume if necessary
-            if ((pathName.Length >= 2)  && ((pathName[1] == ':') && (pathName[2] == '\\')))
-                pathName =  pathName.Substring(3);
-
-            // swap slashes
-            pathName = pathName.Replace('\\', '/');
-
-            // trim all leading slashes
-            while (pathName.StartsWith("/")) pathName = pathName.Substring(1);
-
-            return SimplifyFwdSlashPath(pathName);
-        }
-
-
-        static System.Text.Encoding ibm437 = System.Text.Encoding.ASCII;
-        static System.Text.Encoding utf8 = System.Text.Encoding.GetEncoding("UTF-8");
-
-        internal static byte[] StringToByteArray(string value, System.Text.Encoding encoding)
-        {
-            byte[] a = encoding.GetBytes(value);
-            return a;
-        }
-        internal static byte[] StringToByteArray(string value)
-        {
-            return StringToByteArray(value, ibm437);
-        }
-
-        //internal static byte[] Utf8StringToByteArray(string value)
-        //{
-        //    return StringToByteArray(value, utf8);
-        //}
-
-        //internal static string StringFromBuffer(byte[] buf, int maxlength)
-        //{
-        //    return StringFromBuffer(buf, maxlength, ibm437);
-        //}
-
-        internal static string Utf8StringFromBuffer(byte[] buf)
-        {
-            return StringFromBuffer(buf, utf8);
-        }
-
-        internal static string StringFromBuffer(byte[] buf, System.Text.Encoding encoding)
-        {
-            // this form of the GetString() method is required for .NET CF compatibility
-            string s = encoding.GetString(buf, 0, buf.Length);
-            return s;
-        }
-
-
-        internal static int ReadSignature(System.IO.Stream s)
-        {
-            int x = 0;
-            try { x = _ReadFourBytes(s, "n/a"); }
-            catch (BadReadException) { }
-            return x;
-        }
-
-
-        internal static int ReadEntrySignature(System.IO.Stream s)
-        {
-            // handle the case of ill-formatted zip archives - includes a data descriptor
-            // when none is expected.
-            int x = 0;
-            try
-            {
-                x = _ReadFourBytes(s, "n/a");
-                if (x == ZipConstants.ZipEntryDataDescriptorSignature)
-                {
-                    // advance past data descriptor - 12 bytes if not zip64
-                    s.Seek(12, SeekOrigin.Current);
-                    // workitem 10178
-                    Workaround_Ladybug318918(s);
-                    x = _ReadFourBytes(s, "n/a");
-                    if (x != ZipConstants.ZipEntrySignature)
-                    {
-                        // Maybe zip64 was in use for the prior entry.
-                        // Therefore, skip another 8 bytes.
-                        s.Seek(8, SeekOrigin.Current);
-                        // workitem 10178
-                        Workaround_Ladybug318918(s);
-                        x = _ReadFourBytes(s, "n/a");
-                        if (x != ZipConstants.ZipEntrySignature)
-                        {
-                            // seek back to the first spot
-                            s.Seek(-24, SeekOrigin.Current);
-                            // workitem 10178
-                            Workaround_Ladybug318918(s);
-                            x = _ReadFourBytes(s, "n/a");
-                        }
-                    }
-                }
-            }
-            catch (BadReadException) { }
-            return x;
-        }
-
-
-        internal static int ReadInt(System.IO.Stream s)
-        {
-            return _ReadFourBytes(s, "Could not read block - no data!  (position 0x{0:X8})");
-        }
-
-        private static int _ReadFourBytes(System.IO.Stream s, string message)
-        {
-            int n = 0;
-            byte[] block = new byte[4];
-#if NETCF
-            // workitem 9181
-            // Reading here in NETCF sometimes reads "backwards". Seems to happen for
-            // larger files.  Not sure why. Maybe an error in caching.  If the data is:
-            //
-            // 00100210: 9efa 0f00 7072 6f6a 6563 742e 6963 7750  ....project.icwP
-            // 00100220: 4b05 0600 0000 0006 0006 0091 0100 008e  K...............
-            // 00100230: 0010 0000 00                             .....
-            //
-            // ...and the stream Position is 10021F, then a Read of 4 bytes is returning
-            // 50776369, instead of 06054b50. This seems to happen the 2nd time Read()
-            // is called from that Position..
-            //
-            // submitted to connect.microsoft.com
-            // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=318918#tabs
-            //
-            for (int i = 0; i < block.Length; i++)
-            {
-                n+= s.Read(block, i, 1);
-            }
-#else
-            n = s.Read(block, 0, block.Length);
-#endif
-            if (n != block.Length) throw new BadReadException(String.Format(message, s.Position));
-            int data = unchecked((((block[3] * 256 + block[2]) * 256) + block[1]) * 256 + block[0]);
-            return data;
-        }
-
-
-
-        /// <summary>
-        ///   Finds a signature in the zip stream. This is useful for finding
-        ///   the end of a zip entry, for example, or the beginning of the next ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     Scans through 64k at a time.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     If the method fails to find the requested signature, the stream Position
-        ///     after completion of this method is unchanged. If the method succeeds in
-        ///     finding the requested signature, the stream position after completion is
-        ///     direct AFTER the signature found in the stream.
-        ///   </para>
-        /// </remarks>
-        ///
-        /// <param name="stream">The stream to search</param>
-        /// <param name="SignatureToFind">The 4-byte signature to find</param>
-        /// <returns>The number of bytes read</returns>
-        internal static long FindSignature(System.IO.Stream stream, int SignatureToFind)
-        {
-            long startingPosition = stream.Position;
-
-            int BATCH_SIZE = 65536; //  8192;
-            byte[] targetBytes = new byte[4];
-            targetBytes[0] = (byte)(SignatureToFind >> 24);
-            targetBytes[1] = (byte)((SignatureToFind & 0x00FF0000) >> 16);
-            targetBytes[2] = (byte)((SignatureToFind & 0x0000FF00) >> 8);
-            targetBytes[3] = (byte)(SignatureToFind & 0x000000FF);
-            byte[] batch = new byte[BATCH_SIZE];
-            int n = 0;
-            bool success = false;
-            do
-            {
-                n = stream.Read(batch, 0, batch.Length);
-                if (n != 0)
-                {
-                    for (int i = 0; i < n; i++)
-                    {
-                        if (batch[i] == targetBytes[3])
-                        {
-                            long curPosition = stream.Position;
-                            stream.Seek(i - n, System.IO.SeekOrigin.Current);
-                            // workitem 10178
-                            Workaround_Ladybug318918(stream);
-
-                            // workitem 7711
-                            int sig = ReadSignature(stream);
-
-                            success = (sig == SignatureToFind);
-                            if (!success)
-                            {
-                                stream.Seek(curPosition, System.IO.SeekOrigin.Begin);
-                                // workitem 10178
-                                Workaround_Ladybug318918(stream);
-                            }
-                            else
-                                break; // out of for loop
-                        }
-                    }
-                }
-                else break;
-                if (success) break;
-
-            } while (true);
-
-            if (!success)
-            {
-                stream.Seek(startingPosition, System.IO.SeekOrigin.Begin);
-                // workitem 10178
-                Workaround_Ladybug318918(stream);
-                return -1;  // or throw?
-            }
-
-            // subtract 4 for the signature.
-            long bytesRead = (stream.Position - startingPosition) - 4;
-
-            return bytesRead;
-        }
-
-
-        // If I have a time in the .NET environment, and I want to use it for
-        // SetWastWriteTime() etc, then I need to adjust it for Win32.
-        internal static DateTime AdjustTime_Reverse(DateTime time)
-        {
-            if (time.Kind == DateTimeKind.Utc) return time;
-            DateTime adjusted = time;
-            if (DateTime.Now.IsDaylightSavingTime() && !time.IsDaylightSavingTime())
-                adjusted = time - new System.TimeSpan(1, 0, 0);
-
-            else if (!DateTime.Now.IsDaylightSavingTime() && time.IsDaylightSavingTime())
-                adjusted = time + new System.TimeSpan(1, 0, 0);
-
-            return adjusted;
-        }
-
-#if NECESSARY
-        // If I read a time from a file with GetLastWriteTime() (etc), I need
-        // to adjust it for display in the .NET environment.
-        internal static DateTime AdjustTime_Forward(DateTime time)
-        {
-            if (time.Kind == DateTimeKind.Utc) return time;
-            DateTime adjusted = time;
-            if (DateTime.Now.IsDaylightSavingTime() && !time.IsDaylightSavingTime())
-                adjusted = time + new System.TimeSpan(1, 0, 0);
-
-            else if (!DateTime.Now.IsDaylightSavingTime() && time.IsDaylightSavingTime())
-                adjusted = time - new System.TimeSpan(1, 0, 0);
-
-            return adjusted;
-        }
-#endif
-
-
-        internal static DateTime PackedToDateTime(Int32 packedDateTime)
-        {
-            // workitem 7074 & workitem 7170
-            if (packedDateTime == 0xFFFF || packedDateTime == 0)
-                return new System.DateTime(1995, 1, 1, 0, 0, 0, 0);  // return a fixed date when none is supplied.
-
-            Int16 packedTime = unchecked((Int16)(packedDateTime & 0x0000ffff));
-            Int16 packedDate = unchecked((Int16)((packedDateTime & 0xffff0000) >> 16));
-
-            int year = 1980 + ((packedDate & 0xFE00) >> 9);
-            int month = (packedDate & 0x01E0) >> 5;
-            int day = packedDate & 0x001F;
-
-            int hour = (packedTime & 0xF800) >> 11;
-            int minute = (packedTime & 0x07E0) >> 5;
-            //int second = packedTime & 0x001F;
-            int second = (packedTime & 0x001F) * 2;
-
-            // validation and error checking.
-            // this is not foolproof but will catch most errors.
-            if (second >= 60) { minute++; second = 0; }
-            if (minute >= 60) { hour++; minute = 0; }
-            if (hour >= 24) { day++; hour = 0; }
-
-            DateTime d = System.DateTime.Now;
-            bool success= false;
-            try
-            {
-                d = new System.DateTime(year, month, day, hour, minute, second, 0);
-                success= true;
-            }
-            catch (System.ArgumentOutOfRangeException)
-            {
-                if (year == 1980 && (month == 0 || day == 0))
-                {
-                    try
-                    {
-                        d = new System.DateTime(1980, 1, 1, hour, minute, second, 0);
-                success= true;
-                    }
-                    catch (System.ArgumentOutOfRangeException)
-                    {
-                        try
-                        {
-                            d = new System.DateTime(1980, 1, 1, 0, 0, 0, 0);
-                success= true;
-                        }
-                        catch (System.ArgumentOutOfRangeException) { }
-
-                    }
-                }
-                // workitem 8814
-                // my god, I can't believe how many different ways applications
-                // can mess up a simple date format.
-                else
-                {
-                    try
-                    {
-                        while (year < 1980) year++;
-                        while (year > 2030) year--;
-                        while (month < 1) month++;
-                        while (month > 12) month--;
-                        while (day < 1) day++;
-                        while (day > 28) day--;
-                        while (minute < 0) minute++;
-                        while (minute > 59) minute--;
-                        while (second < 0) second++;
-                        while (second > 59) second--;
-                        d = new System.DateTime(year, month, day, hour, minute, second, 0);
-                        success= true;
-                    }
-                    catch (System.ArgumentOutOfRangeException) { }
-                }
-            }
-            if (!success)
-            {
-                string msg = String.Format("y({0}) m({1}) d({2}) h({3}) m({4}) s({5})", year, month, day, hour, minute, second);
-                throw new ZipException(String.Format("Bad date/time format in the zip file. ({0})", msg));
-
-            }
-            // workitem 6191
-            //d = AdjustTime_Reverse(d);
-            d = DateTime.SpecifyKind(d, DateTimeKind.Local);
-            return d;
-        }
-
-
-        internal
-         static Int32 DateTimeToPacked(DateTime time)
-        {
-            // The time is passed in here only for purposes of writing LastModified to the
-            // zip archive. It should always be LocalTime, but we convert anyway.  And,
-            // since the time is being written out, it needs to be adjusted.
-
-            time = time.ToLocalTime();
-            // workitem 7966
-            //time = AdjustTime_Forward(time);
-
-            // see http://www.vsft.com/hal/dostime.htm for the format
-            UInt16 packedDate = (UInt16)((time.Day & 0x0000001F) | ((time.Month << 5) & 0x000001E0) | (((time.Year - 1980) << 9) & 0x0000FE00));
-            UInt16 packedTime = (UInt16)((time.Second / 2 & 0x0000001F) | ((time.Minute << 5) & 0x000007E0) | ((time.Hour << 11) & 0x0000F800));
-
-            Int32 result = (Int32)(((UInt32)(packedDate << 16)) | packedTime);
-            return result;
-        }
-
-
-        /// <summary>
-        ///   Create a pseudo-random filename, suitable for use as a temporary
-        ///   file, and open it.
-        /// </summary>
-        /// <remarks>
-        /// <para>
-        ///   The System.IO.Path.GetRandomFileName() method is not available on
-        ///   the Compact Framework, so this library provides its own substitute
-        ///   on NETCF.
-        /// </para>
-        /// <para>
-        ///   This method produces a filename of the form
-        ///   DotNetZip-xxxxxxxx.tmp, where xxxxxxxx is replaced by randomly
-        ///   chosen characters, and creates that file.
-        /// </para>
-        /// </remarks>
-        public static void CreateAndOpenUniqueTempFile(string dir,
-                                                       out Stream fs,
-                                                       out string filename)
-        {
-            // workitem 9763
-            // http://dotnet.org.za/markn/archive/2006/04/15/51594.aspx
-            // try 3 times:
-            for (int i = 0; i < 3; i++)
-            {
-                try
-                {
-                    filename = Path.Combine(dir, InternalGetTempFileName());
-                    fs = new FileStream(filename, FileMode.CreateNew);
-                    return;
-                }
-                catch (IOException)
-                {
-                    if (i == 2) throw;
-                }
-            }
-            throw new IOException();
-        }
-
-#if NETCF || SILVERLIGHT
-        public static string InternalGetTempFileName()
-        {
-            return "DotNetZip-" + GenerateRandomStringImpl(8,0) + ".tmp";
-        }
-
-        internal static string GenerateRandomStringImpl(int length, int delta)
-        {
-            bool WantMixedCase = (delta == 0);
-            System.Random rnd = new System.Random();
-
-            string result = "";
-            char[] a = new char[length];
-
-            for (int i = 0; i < length; i++)
-            {
-               // delta == 65 means uppercase
-               // delta == 97 means lowercase
-                if (WantMixedCase)
-                    delta = (rnd.Next(2) == 0) ? 65 : 97;
-                a[i] = (char)(rnd.Next(26) + delta);
-            }
-
-            result = new System.String(a);
-            return result;
-        }
-#else
-        public static string InternalGetTempFileName()
-        {
-            return "DotNetZip-" + Path.GetRandomFileName().Substring(0, 8) + ".tmp";
-        }
-
-#endif
-
-
-        /// <summary>
-        /// Workitem 7889: handle ERROR_LOCK_VIOLATION during read
-        /// </summary>
-        /// <remarks>
-        /// This could be gracefully handled with an extension attribute, but
-        /// This assembly is built for .NET 2.0, so I cannot use them.
-        /// </remarks>
-        internal static int ReadWithRetry(System.IO.Stream s, byte[] buffer, int offset, int count, string FileName)
-        {
-            int n = 0;
-            bool done = false;
-#if !NETCF && !SILVERLIGHT
-            int retries = 0;
-#endif
-            do
-            {
-                try
-                {
-                    n = s.Read(buffer, offset, count);
-                    done = true;
-                }
-#if NETCF || SILVERLIGHT
-                catch (System.IO.IOException)
-                {
-                    throw;
-                }
-#else
-                catch (System.IO.IOException ioexc1)
-                {
-                    // Check if we can call GetHRForException,
-                    // which makes unmanaged code calls.
-                    var p = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
-                    if (p.IsUnrestricted())
-                    {
-                        uint hresult = _HRForException(ioexc1);
-                        if (hresult != 0x80070021)  // ERROR_LOCK_VIOLATION
-                            throw new System.IO.IOException(String.Format("Cannot read file {0}", FileName), ioexc1);
-                        retries++;
-                        if (retries > 10)
-                            throw new System.IO.IOException(String.Format("Cannot read file {0}, at offset 0x{1:X8} after 10 retries", FileName, offset), ioexc1);
-
-                        // max time waited on last retry = 250 + 10*550 = 5.75s
-                        // aggregate time waited after 10 retries: 250 + 55*550 = 30.5s
-                        System.Threading.Thread.Sleep(250 + retries * 550);
-                    }
-                    else
-                    {
-                        // The permission.Demand() failed. Therefore, we cannot call
-                        // GetHRForException, and cannot do the subtle handling of
-                        // ERROR_LOCK_VIOLATION.  Just bail.
-                        throw;
-                    }
-                }
-#endif
-            }
-            while (!done);
-
-            return n;
-        }
-
-
-#if !NETCF
-        // workitem 8009
-        //
-        // This method must remain separate.
-        //
-        // Marshal.GetHRForException() is needed to do special exception handling for
-        // the read.  But, that method requires UnmanagedCode permissions, and is marked
-        // with LinkDemand for UnmanagedCode.  In an ASP.NET medium trust environment,
-        // where UnmanagedCode is restricted, will generate a SecurityException at the
-        // time of JIT of the method that calls a method that is marked with LinkDemand
-        // for UnmanagedCode. The SecurityException, if it is restricted, will occur
-        // when this method is JITed.
-        //
-        // The Marshal.GetHRForException() is factored out of ReadWithRetry in order to
-        // avoid the SecurityException at JIT compile time. Because _HRForException is
-        // called only when the UnmanagedCode is allowed.  This means .NET never
-        // JIT-compiles this method when UnmanagedCode is disallowed, and thus never
-        // generates the JIT-compile time exception.
-        //
-#endif
-        private static uint _HRForException(System.Exception ex1)
-        {
-            return unchecked((uint)System.Runtime.InteropServices.Marshal.GetHRForException(ex1));
-        }
-
-    }
-
-
-
-    /// <summary>
-    ///   A decorator stream. It wraps another stream, and performs bookkeeping
-    ///   to keep track of the stream Position.
-    /// </summary>
-    /// <remarks>
-    ///   <para>
-    ///     In some cases, it is not possible to get the Position of a stream, let's
-    ///     say, on a write-only output stream like ASP.NET's
-    ///     <c>Response.OutputStream</c>, or on a different write-only stream
-    ///     provided as the destination for the zip by the application.  In this
-    ///     case, programmers can use this counting stream to count the bytes read
-    ///     or written.
-    ///   </para>
-    ///   <para>
-    ///     Consider the scenario of an application that saves a self-extracting
-    ///     archive (SFX), that uses a custom SFX stub.
-    ///   </para>
-    ///   <para>
-    ///     Saving to a filesystem file, the application would open the
-    ///     filesystem file (getting a <c>FileStream</c>), save the custom sfx stub
-    ///     into it, and then call <c>ZipFile.Save()</c>, specifying the same
-    ///     FileStream. <c>ZipFile.Save()</c> does the right thing for the zipentry
-    ///     offsets, by inquiring the Position of the <c>FileStream</c> before writing
-    ///     any data, and then adding that initial offset into any ZipEntry
-    ///     offsets in the zip directory. Everything works fine.
-    ///   </para>
-    ///   <para>
-    ///     Now suppose the application is an ASPNET application and it saves
-    ///     directly to <c>Response.OutputStream</c>. It's not possible for DotNetZip to
-    ///     inquire the <c>Position</c>, so the offsets for the SFX will be wrong.
-    ///   </para>
-    ///   <para>
-    ///     The workaround is for the application to use this class to wrap
-    ///     <c>HttpResponse.OutputStream</c>, then write the SFX stub and the ZipFile
-    ///     into that wrapper stream. Because <c>ZipFile.Save()</c> can inquire the
-    ///     <c>Position</c>, it will then do the right thing with the offsets.
-    ///   </para>
-    /// </remarks>
-    internal class CountingStream : System.IO.Stream
-    {
-        // workitem 12374: this class is now public
-        private System.IO.Stream _s;
-        private Int64 _bytesWritten;
-        private Int64 _bytesRead;
-        private Int64 _initialOffset;
-
-        /// <summary>
-        /// The constructor.
-        /// </summary>
-        /// <param name="stream">The underlying stream</param>
-        public CountingStream(System.IO.Stream stream)
-            : base()
-        {
-            _s = stream;
-            try
-            {
-                _initialOffset = _s.Position;
-            }
-            catch
-            {
-                _initialOffset = 0L;
-            }
-        }
-
-        /// <summary>
-        ///   Gets the wrapped stream.
-        /// </summary>
-        public Stream WrappedStream
-        {
-            get
-            {
-                return _s;
-            }
-        }
-
-        /// <summary>
-        ///   The count of bytes written out to the stream.
-        /// </summary>
-        public Int64 BytesWritten
-        {
-            get { return _bytesWritten; }
-        }
-
-        /// <summary>
-        ///   the count of bytes that have been read from the stream.
-        /// </summary>
-        public Int64 BytesRead
-        {
-            get { return _bytesRead; }
-        }
-
-        /// <summary>
-        ///    Adjust the byte count on the stream.
-        /// </summary>
-        ///
-        /// <param name='delta'>
-        ///   the number of bytes to subtract from the count.
-        /// </param>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     Subtract delta from the count of bytes written to the stream.
-        ///     This is necessary when seeking back, and writing additional data,
-        ///     as happens in some cases when saving Zip files.
-        ///   </para>
-        /// </remarks>
-        public void Adjust(Int64 delta)
-        {
-            _bytesWritten -= delta;
-            if (_bytesWritten < 0)
-                throw new InvalidOperationException();
-            if (_s as CountingStream != null)
-                ((CountingStream)_s).Adjust(delta);
-        }
-
-        /// <summary>
-        ///   The read method.
-        /// </summary>
-        /// <param name="buffer">The buffer to hold the data read from the stream.</param>
-        /// <param name="offset">the offset within the buffer to copy the first byte read.</param>
-        /// <param name="count">the number of bytes to read.</param>
-        /// <returns>the number of bytes read, after decryption and decompression.</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            int n = _s.Read(buffer, offset, count);
-            _bytesRead += n;
-            return n;
-        }
-
-        /// <summary>
-        ///   Write data into the stream.
-        /// </summary>
-        /// <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 (count == 0) return;
-            _s.Write(buffer, offset, count);
-            _bytesWritten += count;
-        }
-
-        /// <summary>
-        ///   Whether the stream can be read.
-        /// </summary>
-        public override bool CanRead
-        {
-            get { return _s.CanRead; }
-        }
-
-        /// <summary>
-        ///   Whether it is possible to call Seek() on the stream.
-        /// </summary>
-        public override bool CanSeek
-        {
-            get { return _s.CanSeek; }
-        }
-
-        /// <summary>
-        ///   Whether it is possible to call Write() on the stream.
-        /// </summary>
-        public override bool CanWrite
-        {
-            get { return _s.CanWrite; }
-        }
-
-        /// <summary>
-        ///   Flushes the underlying stream.
-        /// </summary>
-        public override void Flush()
-        {
-            _s.Flush();
-        }
-
-        /// <summary>
-        ///   The length of the underlying stream.
-        /// </summary>
-        public override long Length
-        {
-            get { return _s.Length; }   // bytesWritten??
-        }
-
-        /// <summary>
-        ///   Returns the sum of number of bytes written, plus the initial
-        ///   offset before writing.
-        /// </summary>
-        public long ComputedPosition
-        {
-            get { return _initialOffset + _bytesWritten; }
-        }
-
-
-        /// <summary>
-        ///   The Position of the stream.
-        /// </summary>
-        public override long Position
-        {
-            get { return _s.Position; }
-            set
-            {
-                _s.Seek(value, System.IO.SeekOrigin.Begin);
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_s);
-            }
-        }
-
-        /// <summary>
-        ///   Seek in the stream.
-        /// </summary>
-        /// <param name="offset">the offset point to seek to</param>
-        /// <param name="origin">the reference point from which to seek</param>
-        /// <returns>The new position</returns>
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            return _s.Seek(offset, origin);
-        }
-
-        /// <summary>
-        ///   Set the length of the underlying stream.  Be careful with this!
-        /// </summary>
-        ///
-        /// <param name='value'>the length to set on the underlying stream.</param>
-        public override void SetLength(long value)
-        {
-            _s.SetLength(value);
-        }
-    }
-
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/WinZipAes.cs b/EPPlus/Packaging/DotNetZip/WinZipAes.cs
deleted file mode 100644
index f45eea4..0000000
--- a/EPPlus/Packaging/DotNetZip/WinZipAes.cs
+++ /dev/null
@@ -1,941 +0,0 @@
-//#define Trace
-
-// WinZipAes.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-12 13:42:06>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the classes for dealing with WinZip's AES encryption,
-// according to the specifications for the format available on WinZip's website.
-//
-// Created: January 2009
-//
-// ------------------------------------------------------------------
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Security.Cryptography;
-
-#if AESCRYPTO
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    ///   This is a helper class supporting WinZip AES encryption.
-    ///   This class is intended for use only by the DotNetZip library.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///   Most uses of the DotNetZip library will not involve direct calls into
-    ///   the WinZipAesCrypto class.  Instead, the WinZipAesCrypto class is
-    ///   instantiated and used by the ZipEntry() class when WinZip AES
-    ///   encryption or decryption on an entry is employed.
-    /// </remarks>
-    internal class WinZipAesCrypto
-    {
-        internal byte[] _Salt;
-        internal byte[] _providedPv;
-        internal byte[] _generatedPv;
-        internal int _KeyStrengthInBits;
-        private byte[] _MacInitializationVector;
-        private byte[] _StoredMac;
-        private byte[] _keyBytes;
-        private Int16 PasswordVerificationStored;
-        private Int16 PasswordVerificationGenerated;
-        private int Rfc2898KeygenIterations = 1000;
-        private string _Password;
-        private bool _cryptoGenerated ;
-
-        private WinZipAesCrypto(string password, int KeyStrengthInBits)
-        {
-            _Password = password;
-            _KeyStrengthInBits = KeyStrengthInBits;
-        }
-
-        public static WinZipAesCrypto Generate(string password, int KeyStrengthInBits)
-        {
-            WinZipAesCrypto c = new WinZipAesCrypto(password, KeyStrengthInBits);
-
-            int saltSizeInBytes = c._KeyStrengthInBytes / 2;
-            c._Salt = new byte[saltSizeInBytes];
-            Random rnd = new Random();
-            rnd.NextBytes(c._Salt);
-            return c;
-        }
-
-
-
-        public static WinZipAesCrypto ReadFromStream(string password, int KeyStrengthInBits, Stream s)
-        {
-            // from http://www.winzip.com/aes_info.htm
-            //
-            // Size(bytes)   Content
-            // -----------------------------------
-            // Variable      Salt value
-            // 2             Password verification value
-            // Variable      Encrypted file data
-            // 10            Authentication code
-            //
-            // ZipEntry.CompressedSize represents the size of all of those elements.
-
-            // salt size varies with key length:
-            //    128 bit key => 8 bytes salt
-            //    192 bits => 12 bytes salt
-            //    256 bits => 16 bytes salt
-
-            WinZipAesCrypto c = new WinZipAesCrypto(password, KeyStrengthInBits);
-
-            int saltSizeInBytes = c._KeyStrengthInBytes / 2;
-            c._Salt = new byte[saltSizeInBytes];
-            c._providedPv = new byte[2];
-
-            s.Read(c._Salt, 0, c._Salt.Length);
-            s.Read(c._providedPv, 0, c._providedPv.Length);
-
-            c.PasswordVerificationStored = (Int16)(c._providedPv[0] + c._providedPv[1] * 256);
-            if (password != null)
-            {
-                c.PasswordVerificationGenerated = (Int16)(c.GeneratedPV[0] + c.GeneratedPV[1] * 256);
-                if (c.PasswordVerificationGenerated != c.PasswordVerificationStored)
-                    throw new BadPasswordException("bad password");
-            }
-
-            return c;
-        }
-
-        public byte[] GeneratedPV
-        {
-            get
-            {
-                if (!_cryptoGenerated) _GenerateCryptoBytes();
-                return _generatedPv;
-            }
-        }
-
-
-        public byte[] Salt
-        {
-            get
-            {
-                return _Salt;
-            }
-        }
-
-
-        private int _KeyStrengthInBytes
-        {
-            get
-            {
-                return _KeyStrengthInBits / 8;
-
-            }
-        }
-
-        public int SizeOfEncryptionMetadata
-        {
-            get
-            {
-                // 10 bytes after, (n-10) before the compressed data
-                return _KeyStrengthInBytes / 2 + 10 + 2;
-            }
-        }
-
-        public string Password
-        {
-            set
-            {
-                _Password = value;
-                if (_Password != null)
-                {
-                    PasswordVerificationGenerated = (Int16)(GeneratedPV[0] + GeneratedPV[1] * 256);
-                    if (PasswordVerificationGenerated != PasswordVerificationStored)
-                        throw new Ionic.Zip.BadPasswordException();
-                }
-            }
-            private get
-            {
-                return _Password;
-            }
-        }
-
-
-        private void _GenerateCryptoBytes()
-        {
-            //Console.WriteLine(" provided password: '{0}'", _Password);
-
-            System.Security.Cryptography.Rfc2898DeriveBytes rfc2898 =
-                new System.Security.Cryptography.Rfc2898DeriveBytes(_Password, Salt, Rfc2898KeygenIterations);
-
-            _keyBytes = rfc2898.GetBytes(_KeyStrengthInBytes); // 16 or 24 or 32 ???
-            _MacInitializationVector = rfc2898.GetBytes(_KeyStrengthInBytes);
-            _generatedPv = rfc2898.GetBytes(2);
-
-            _cryptoGenerated = true;
-        }
-
-
-        public byte[] KeyBytes
-        {
-            get
-            {
-                if (!_cryptoGenerated) _GenerateCryptoBytes();
-                return _keyBytes;
-            }
-        }
-
-
-        public byte[] MacIv
-        {
-            get
-            {
-                if (!_cryptoGenerated) _GenerateCryptoBytes();
-                return _MacInitializationVector;
-            }
-        }
-
-        public byte[] CalculatedMac;
-
-
-        public void ReadAndVerifyMac(System.IO.Stream s)
-        {
-            bool invalid = false;
-
-            // read integrityCheckVector.
-            // caller must ensure that the file pointer is in the right spot!
-            _StoredMac = new byte[10];  // aka "authentication code"
-            s.Read(_StoredMac, 0, _StoredMac.Length);
-
-            if (_StoredMac.Length != CalculatedMac.Length)
-                invalid = true;
-
-            if (!invalid)
-            {
-                for (int i = 0; i < _StoredMac.Length; i++)
-                {
-                    if (_StoredMac[i] != CalculatedMac[i])
-                        invalid = true;
-                }
-            }
-
-            if (invalid)
-                throw new Ionic.Zip.BadStateException("The MAC does not match.");
-        }
-
-    }
-
-
-    #region DONT_COMPILE_BUT_KEEP_FOR_POTENTIAL_FUTURE_USE
-#if NO
-    internal class Util
-    {
-        private static void _Format(System.Text.StringBuilder sb1,
-                                    byte[] b,
-                                    int offset,
-                                    int length)
-        {
-
-            System.Text.StringBuilder sb2 = new System.Text.StringBuilder();
-            sb1.Append("0000    ");
-            int i;
-            for (i = 0; i < length; i++)
-            {
-                int x = offset+i;
-                if (i != 0 && i % 16 == 0)
-                {
-                    sb1.Append("    ")
-                        .Append(sb2)
-                        .Append("\n")
-                        .Append(String.Format("{0:X4}    ", i));
-                    sb2.Remove(0,sb2.Length);
-                }
-                sb1.Append(System.String.Format("{0:X2} ", b[x]));
-                if (b[x] >=32 && b[x] <= 126)
-                    sb2.Append((char)b[x]);
-                else
-                    sb2.Append(".");
-            }
-            if (sb2.Length > 0)
-            {
-                sb1.Append(new String(' ', ((16 - i%16) * 3) + 4))
-                    .Append(sb2);
-            }
-        }
-
-
-
-        internal static string FormatByteArray(byte[] b, int limit)
-        {
-            System.Text.StringBuilder sb1 = new System.Text.StringBuilder();
-
-            if ((limit * 2 > b.Length) || limit == 0)
-            {
-                _Format(sb1, b, 0, b.Length);
-            }
-            else
-            {
-                // first N bytes of the buffer
-                _Format(sb1, b, 0, limit);
-
-                if (b.Length > limit * 2)
-                    sb1.Append(String.Format("\n   ...({0} other bytes here)....\n", b.Length - limit * 2));
-
-                // last N bytes of the buffer
-                _Format(sb1, b, b.Length - limit, limit);
-            }
-
-            return sb1.ToString();
-        }
-
-
-        internal static string FormatByteArray(byte[] b)
-        {
-            return FormatByteArray(b, 0);
-        }
-    }
-
-#endif
-    #endregion
-
-
-
-
-    /// <summary>
-    ///   A stream that encrypts as it writes, or decrypts as it reads.  The
-    ///   Crypto is AES in CTR (counter) mode, which is compatible with the AES
-    ///   encryption employed by WinZip 12.0.
-    /// </summary>
-    /// <remarks>
-    ///   <para>
-    ///     The AES/CTR encryption protocol used by WinZip works like this:
-    ///
-    ///       - start with a counter, initialized to zero.
-    ///
-    ///       - to encrypt, take the data by 16-byte blocks. For each block:
-    ///         - apply the transform to the counter
-    ///         - increement the counter
-    ///         - XOR the result of the transform with the plaintext to
-    ///           get the ciphertext.
-    ///         - compute the mac on the encrypted bytes
-    ///       - when finished with all blocks, store the computed MAC.
-    ///
-    ///       - to decrypt, take the data by 16-byte blocks. For each block:
-    ///         - compute the mac on the encrypted bytes,
-    ///         - apply the transform to the counter
-    ///         - increement the counter
-    ///         - XOR the result of the transform with the ciphertext to
-    ///           get the plaintext.
-    ///       - when finished with all blocks, compare the computed MAC against
-    ///         the stored MAC
-    ///
-    ///   </para>
-    /// </remarks>
-    //
-    internal class WinZipAesCipherStream : Stream
-    {
-        private WinZipAesCrypto _params;
-        private System.IO.Stream _s;
-        private CryptoMode _mode;
-        private int _nonce;
-        private bool _finalBlock;
-
-        internal HMACSHA1 _mac;
-
-        // Use RijndaelManaged from .NET 2.0.
-        // AesManaged came in .NET 3.5, but we want to limit
-        // dependency to .NET 2.0.  AES is just a restricted form
-        // of Rijndael (fixed block size of 128, some crypto modes not supported).
-
-        internal RijndaelManaged _aesCipher;
-        internal ICryptoTransform _xform;
-
-        private const int BLOCK_SIZE_IN_BYTES = 16;
-
-        private byte[] counter = new byte[BLOCK_SIZE_IN_BYTES];
-        private byte[] counterOut = new byte[BLOCK_SIZE_IN_BYTES];
-
-        // I've had a problem when wrapping a WinZipAesCipherStream inside
-        // a DeflateStream. Calling Read() on the DeflateStream results in
-        // a Read() on the WinZipAesCipherStream, but the buffer is larger
-        // than the total size of the encrypted data, and larger than the
-        // initial Read() on the DeflateStream!  When the encrypted
-        // bytestream is embedded within a larger stream (As in a zip
-        // archive), the Read() doesn't fail with EOF.  This causes bad
-        // data to be returned, and it messes up the MAC.
-
-        // This field is used to provide a hard-stop to the size of
-        // data that can be read from the stream.  In Read(), if the buffer or
-        // read request goes beyond the stop, we truncate it.
-
-        private long _length;
-        private long _totalBytesXferred;
-        private byte[] _PendingWriteBlock;
-        private int _pendingCount;
-        private byte[] _iobuf;
-
-        /// <summary>
-        /// The constructor.
-        /// </summary>
-        /// <param name="s">The underlying stream</param>
-        /// <param name="mode">To either encrypt or decrypt.</param>
-        /// <param name="cryptoParams">The pre-initialized WinZipAesCrypto object.</param>
-        /// <param name="length">The maximum number of bytes to read from the stream.</param>
-        internal WinZipAesCipherStream(System.IO.Stream s, WinZipAesCrypto cryptoParams, long length, CryptoMode mode)
-            : this(s, cryptoParams, mode)
-        {
-            // don't read beyond this limit!
-            _length = length;
-            //Console.WriteLine("max length of AES stream: {0}", _length);
-        }
-
-
-#if WANT_TRACE
-            Stream untransformed;
-        String traceFileUntransformed;
-        Stream transformed;
-        String traceFileTransformed;
-#endif
-
-
-        internal WinZipAesCipherStream(System.IO.Stream s, WinZipAesCrypto cryptoParams, CryptoMode mode)
-            : base()
-        {
-            TraceOutput("-------------------------------------------------------");
-            TraceOutput("Create {0:X8}", this.GetHashCode());
-
-            _params = cryptoParams;
-            _s = s;
-            _mode = mode;
-            _nonce = 1;
-
-            if (_params == null)
-                throw new BadPasswordException("Supply a password to use AES encryption.");
-
-            int keySizeInBits = _params.KeyBytes.Length * 8;
-            if (keySizeInBits != 256 && keySizeInBits != 128 && keySizeInBits != 192)
-                throw new ArgumentOutOfRangeException("keysize",
-                                                      "size of key must be 128, 192, or 256");
-
-            _mac = new HMACSHA1(_params.MacIv);
-
-            _aesCipher = new System.Security.Cryptography.RijndaelManaged();
-            _aesCipher.BlockSize = 128;
-            _aesCipher.KeySize = keySizeInBits;  // 128, 192, 256
-            _aesCipher.Mode = CipherMode.ECB;
-            _aesCipher.Padding = PaddingMode.None;
-
-            byte[] iv = new byte[BLOCK_SIZE_IN_BYTES]; // all zeroes
-
-            // Create an ENCRYPTOR, regardless whether doing decryption or encryption.
-            // It is reflexive.
-            _xform = _aesCipher.CreateEncryptor(_params.KeyBytes, iv);
-
-            if (_mode == CryptoMode.Encrypt)
-            {
-                _iobuf = new byte[2048];
-                _PendingWriteBlock = new byte[BLOCK_SIZE_IN_BYTES];
-            }
-
-
-#if WANT_TRACE
-                traceFileUntransformed = "unpack\\WinZipAesCipherStream.trace.untransformed.out";
-            traceFileTransformed = "unpack\\WinZipAesCipherStream.trace.transformed.out";
-
-            untransformed = System.IO.File.Create(traceFileUntransformed);
-            transformed = System.IO.File.Create(traceFileTransformed);
-#endif
-        }
-
-        private void XorInPlace(byte[] buffer, int offset, int count)
-        {
-            for (int i = 0; i < count; i++)
-            {
-                buffer[offset + i] = (byte)(counterOut[i] ^ buffer[offset + i]);
-            }
-        }
-
-        private void WriteTransformOneBlock(byte[] buffer, int offset)
-        {
-            System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4);
-            _xform.TransformBlock(counter,
-                                  0,
-                                  BLOCK_SIZE_IN_BYTES,
-                                  counterOut,
-                                  0);
-            XorInPlace(buffer, offset, BLOCK_SIZE_IN_BYTES);
-            _mac.TransformBlock(buffer, offset, BLOCK_SIZE_IN_BYTES, null, 0);
-        }
-
-
-        private void WriteTransformBlocks(byte[] buffer, int offset, int count)
-        {
-            int posn = offset;
-            int last = count + offset;
-
-            while (posn < buffer.Length && posn < last)
-            {
-                WriteTransformOneBlock (buffer, posn);
-                posn += BLOCK_SIZE_IN_BYTES;
-            }
-        }
-
-
-        private void WriteTransformFinalBlock()
-        {
-            if (_pendingCount == 0)
-                throw new InvalidOperationException("No bytes available.");
-
-            if (_finalBlock)
-                throw new InvalidOperationException("The final block has already been transformed.");
-
-            System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4);
-            counterOut = _xform.TransformFinalBlock(counter,
-                                                    0,
-                                                    BLOCK_SIZE_IN_BYTES);
-            XorInPlace(_PendingWriteBlock, 0, _pendingCount);
-            _mac.TransformFinalBlock(_PendingWriteBlock, 0, _pendingCount);
-            _finalBlock = true;
-        }
-
-
-
-
-
-        private int ReadTransformOneBlock(byte[] buffer, int offset, int last)
-        {
-            if (_finalBlock)
-                throw new NotSupportedException();
-
-            int bytesRemaining = last - offset;
-            int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES)
-                ? BLOCK_SIZE_IN_BYTES
-                : bytesRemaining;
-
-            // update the counter
-            System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4);
-
-            // Determine if this is the final block
-            if ((bytesToRead == bytesRemaining) &&
-                (_length > 0) &&
-                (_totalBytesXferred + last == _length))
-            {
-                _mac.TransformFinalBlock(buffer, offset, bytesToRead);
-                counterOut = _xform.TransformFinalBlock(counter,
-                                                        0,
-                                                        BLOCK_SIZE_IN_BYTES);
-                _finalBlock = true;
-            }
-            else
-            {
-                _mac.TransformBlock(buffer, offset, bytesToRead, null, 0);
-                _xform.TransformBlock(counter,
-                                      0, // offset
-                                      BLOCK_SIZE_IN_BYTES,
-                                      counterOut,
-                                      0);  // offset
-            }
-
-            XorInPlace(buffer, offset, bytesToRead);
-            return bytesToRead;
-        }
-
-
-
-        private void ReadTransformBlocks(byte[] buffer, int offset, int count)
-        {
-            int posn = offset;
-            int last = count + offset;
-
-            while (posn < buffer.Length && posn < last )
-            {
-                int n = ReadTransformOneBlock (buffer, posn, last);
-                posn += n;
-            }
-        }
-
-
-
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            if (_mode == CryptoMode.Encrypt)
-                throw new NotSupportedException();
-
-            if (buffer == null)
-                throw new ArgumentNullException("buffer");
-
-            if (offset < 0)
-                throw new ArgumentOutOfRangeException("offset",
-                                                      "Must not be less than zero.");
-            if (count < 0)
-                throw new ArgumentOutOfRangeException("count",
-                                                      "Must not be less than zero.");
-
-            if (buffer.Length < offset + count)
-                throw new ArgumentException("The buffer is too small");
-
-            // When I wrap a WinZipAesStream in a DeflateStream, the
-            // DeflateStream asks its captive to read 4k blocks, even if the
-            // encrypted bytestream is smaller than that.  This is a way to
-            // limit the number of bytes read.
-
-            int bytesToRead = count;
-
-            if (_totalBytesXferred >= _length)
-            {
-                return 0; // EOF
-            }
-
-            long bytesRemaining = _length - _totalBytesXferred;
-            if (bytesRemaining < count) bytesToRead = (int)bytesRemaining;
-
-            int n = _s.Read(buffer, offset, bytesToRead);
-
-
-#if WANT_TRACE
-                untransformed.Write(buffer, offset, bytesToRead);
-#endif
-
-            ReadTransformBlocks(buffer, offset, bytesToRead);
-
-#if WANT_TRACE
-                transformed.Write(buffer, offset, bytesToRead);
-#endif
-            _totalBytesXferred += n;
-            return n;
-        }
-
-
-
-        /// <summary>
-        /// Returns the final HMAC-SHA1-80 for the data that was encrypted.
-        /// </summary>
-        public byte[] FinalAuthentication
-        {
-            get
-            {
-                if (!_finalBlock)
-                {
-                    // special-case zero-byte files
-                    if ( _totalBytesXferred != 0)
-                        throw new BadStateException("The final hash has not been computed.");
-
-                    // Must call ComputeHash on an empty byte array when no data
-                    // has run through the MAC.
-
-                    byte[] b = {  };
-                    _mac.ComputeHash(b);
-                    // fall through
-                }
-                byte[] macBytes10 = new byte[10];
-                System.Array.Copy(_mac.Hash, 0, macBytes10, 0, 10);
-                return macBytes10;
-            }
-        }
-
-
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            if (_finalBlock)
-                throw new InvalidOperationException("The final block has already been transformed.");
-
-            if (_mode == CryptoMode.Decrypt)
-                throw new NotSupportedException();
-
-            if (buffer == null)
-                throw new ArgumentNullException("buffer");
-
-            if (offset < 0)
-                throw new ArgumentOutOfRangeException("offset",
-                                                      "Must not be less than zero.");
-            if (count < 0)
-                throw new ArgumentOutOfRangeException("count",
-                                                      "Must not be less than zero.");
-            if (buffer.Length < offset + count)
-                throw new ArgumentException("The offset and count are too large");
-
-            if (count == 0)
-                return;
-
-            TraceOutput("Write off({0}) count({1})", offset, count);
-
-#if WANT_TRACE
-            untransformed.Write(buffer, offset, count);
-#endif
-
-            // For proper AES encryption, an AES encryptor application calls
-            // TransformBlock repeatedly for all 16-byte blocks except the
-            // last. For the last block, it then calls TransformFinalBlock().
-            //
-            // This class is a stream that encrypts via Write().  But, it's not
-            // possible to recognize which are the "last" bytes from within the call
-            // to Write(). The caller can call Write() several times in succession,
-            // with varying buffers. This class only "knows" that the last bytes
-            // have been written when the app calls Close().
-            //
-            // Therefore, this class buffers writes: After completion every Write(),
-            // a 16-byte "pending" block (_PendingWriteBlock) must hold between 1
-            // and 16 bytes, which will be used in TransformFinalBlock if the app
-            // calls Close() immediately thereafter. Also, every write must
-            // transform any pending bytes, before transforming the data passed in
-            // to the current call.
-            //
-            // In operation, after the first call to Write() and before the call to
-            // Close(), one full or partial block of bytes is always available,
-            // pending.  At time of Close(), this class calls
-            // WriteTransformFinalBlock() to flush the pending bytes.
-            //
-            // This approach works whether the caller writes in odd-sized batches,
-            // for example 5000 bytes, or in batches that are neat multiples of the
-            // blocksize (16).
-            //
-            // Logicaly, what we do is this:
-            //
-            //  1. if there are fewer than 16 bytes (pending + current), then
-            //     just copy them into th pending buffer and return.
-            //
-            //  2. there are more than 16 bytes to write. So, take the leading slice
-            //     of bytes from the current buffer, enough to fill the pending
-            //     buffer. Transform the pending block, and write it out.
-            //
-            //  3. Take the trailing slice of bytes (a full block or a partial block),
-            //     and copy it to the pending block for next time.
-            //
-            //  4. transform and write all the other blocks, the middle slice.
-            //
-
-            // There are 16 or fewer bytes, so just buffer the bytes.
-            if (count + _pendingCount <= BLOCK_SIZE_IN_BYTES)
-            {
-                Buffer.BlockCopy(buffer,
-                                 offset,
-                                 _PendingWriteBlock,
-                                 _pendingCount,
-                                 count);
-                _pendingCount += count;
-
-                // At this point, _PendingWriteBlock contains up to
-                // BLOCK_SIZE_IN_BYTES bytes, and _pendingCount ranges from 0 to
-                // BLOCK_SIZE_IN_BYTES. We don't want to xform+write them yet,
-                // because this may have been the last block.  The last block gets
-                // written at Close().
-                return;
-            }
-
-            // We know there are at least 17 bytes, counting those in the current
-            // buffer, along with the (possibly empty) pending block.
-
-            int bytesRemaining = count;
-            int curOffset = offset;
-
-            // workitem 12815
-            //
-            // xform chunkwise ... Cannot transform in place using the original
-            // buffer because that is user-maintained.
-
-            if (_pendingCount != 0)
-            {
-                // We have more than one block of data to write, therefore it is safe
-                // to xform+write.
-                int fillCount = BLOCK_SIZE_IN_BYTES - _pendingCount;
-
-                // fillCount is possibly zero here. That happens when the pending
-                // buffer held 16 bytes (one complete block) before this call to
-                // Write.
-                if (fillCount > 0)
-                {
-                    Buffer.BlockCopy(buffer,
-                                     offset,
-                                     _PendingWriteBlock,
-                                     _pendingCount,
-                                     fillCount);
-
-                    // adjust counts:
-                    bytesRemaining -= fillCount;
-                    curOffset += fillCount;
-                }
-
-                // xform and write:
-                WriteTransformOneBlock(_PendingWriteBlock, 0);
-                _s.Write(_PendingWriteBlock, 0, BLOCK_SIZE_IN_BYTES);
-                _totalBytesXferred += BLOCK_SIZE_IN_BYTES;
-                _pendingCount = 0;
-            }
-
-            // At this point _PendingWriteBlock is empty, and bytesRemaining is
-            // always greater than 0.
-
-            // Now, xform N blocks, where N = floor((bytesRemaining-1)/16).  If
-            // writing 32 bytes, then xform 1 block, and stage the remaining 16.  If
-            // writing 10037 bytes, xform 627 blocks of 16 bytes, then stage the
-            // remaining 5 bytes.
-
-            int blocksToXform = (bytesRemaining-1)/BLOCK_SIZE_IN_BYTES;
-            _pendingCount = bytesRemaining - (blocksToXform * BLOCK_SIZE_IN_BYTES);
-
-            // _pendingCount is ALWAYS between 1 and 16.
-            // Put the last _pendingCount bytes into the pending block.
-            Buffer.BlockCopy(buffer,
-                             curOffset + bytesRemaining - _pendingCount,
-                             _PendingWriteBlock,
-                             0,
-                             _pendingCount);
-            bytesRemaining -= _pendingCount;
-            _totalBytesXferred += bytesRemaining; // will be true after the loop
-
-            // now, transform all the full blocks preceding that.
-            // bytesRemaining is always a multiple of 16 .
-            if (blocksToXform > 0)
-            {
-                do
-                {
-                    int c = _iobuf.Length;
-                    if (c > bytesRemaining) c = bytesRemaining;
-                    Buffer.BlockCopy(buffer,
-                                     curOffset,
-                                     _iobuf,
-                                     0,
-                                     c);
-
-                    WriteTransformBlocks(_iobuf, 0, c);
-                    _s.Write(_iobuf, 0, c);
-                    bytesRemaining -= c;
-                    curOffset += c;
-                } while(bytesRemaining > 0);
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Close the stream.
-        /// </summary>
-        public override void Close()
-        {
-            TraceOutput("Close {0:X8}", this.GetHashCode());
-
-            // In the degenerate case, no bytes have been written to the
-            // stream at all.  Need to check here, and NOT emit the
-            // final block if Write has not been called.
-            if (_pendingCount > 0)
-            {
-                WriteTransformFinalBlock();
-                _s.Write(_PendingWriteBlock, 0, _pendingCount);
-                _totalBytesXferred += _pendingCount;
-                _pendingCount = 0;
-            }
-            _s.Close();
-
-#if WANT_TRACE
-            untransformed.Close();
-            transformed.Close();
-            Console.WriteLine("\nuntransformed bytestream is in  {0}", traceFileUntransformed);
-            Console.WriteLine("\ntransformed bytestream is in  {0}", traceFileTransformed);
-#endif
-            TraceOutput("-------------------------------------------------------");
-        }
-
-
-        /// <summary>
-        /// Returns true if the stream can be read.
-        /// </summary>
-        public override bool CanRead
-        {
-            get
-            {
-                if (_mode != CryptoMode.Decrypt) return false;
-                return true;
-            }
-        }
-
-
-        /// <summary>
-        /// Always returns false.
-        /// </summary>
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-        /// <summary>
-        /// Returns true if the CryptoMode is Encrypt.
-        /// </summary>
-        public override bool CanWrite
-        {
-            get { return (_mode == CryptoMode.Encrypt); }
-        }
-
-        /// <summary>
-        /// Flush the content in the stream.
-        /// </summary>
-        public override void Flush()
-        {
-            _s.Flush();
-        }
-
-        /// <summary>
-        /// Getting this property throws a NotImplementedException.
-        /// </summary>
-        public override long Length
-        {
-            get { throw new NotImplementedException(); }
-        }
-
-        /// <summary>
-        /// Getting or Setting this property throws a NotImplementedException.
-        /// </summary>
-        public override long Position
-        {
-            get { throw new NotImplementedException(); }
-            set { throw new NotImplementedException(); }
-        }
-
-        /// <summary>
-        /// This method throws a NotImplementedException.
-        /// </summary>
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotImplementedException();
-        }
-
-        /// <summary>
-        /// This method throws a NotImplementedException.
-        /// </summary>
-        public override void SetLength(long value)
-        {
-            throw new NotImplementedException();
-        }
-
-
-
-        [System.Diagnostics.ConditionalAttribute("Trace")]
-        private void TraceOutput(string format, params object[] varParams)
-        {
-            lock(_outputLock)
-            {
-                int tid = System.Threading.Thread.CurrentThread.GetHashCode();
-                Console.ForegroundColor = (ConsoleColor) (tid % 8 + 8);
-                Console.Write("{0:000} WZACS ", tid);
-                Console.WriteLine(format, varParams);
-                Console.ResetColor();
-            }
-        }
-
-        private object _outputLock = new Object();
-    }
-}
-#endif
diff --git a/EPPlus/Packaging/DotNetZip/ZipConstants.cs b/EPPlus/Packaging/DotNetZip/ZipConstants.cs
deleted file mode 100644
index 5852a29..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipConstants.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// ZipConstants.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006, 2007, 2008, 2009 Dino Chiesa and Microsoft Corporation.  
-// 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: <2009-August-27 23:22:32>
-//
-// ------------------------------------------------------------------
-//
-// This module defines a few constants that are used in the project. 
-//
-// ------------------------------------------------------------------
-
-using System;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-  static class ZipConstants
-  {      
-    public const UInt32 PackedToRemovableMedia = 0x30304b50;
-    public const UInt32 Zip64EndOfCentralDirectoryRecordSignature = 0x06064b50;
-    public const UInt32 Zip64EndOfCentralDirectoryLocatorSignature = 0x07064b50;
-    public const UInt32 EndOfCentralDirectorySignature = 0x06054b50;
-    public const int ZipEntrySignature                 = 0x04034b50;
-    public const int ZipEntryDataDescriptorSignature   = 0x08074b50;
-    public const int SplitArchiveSignature             = 0x08074b50;
-    public const int ZipDirEntrySignature              = 0x02014b50;
-
-      
-    // These are dictated by the Zip Spec.See APPNOTE.txt
-    public const int AesKeySize = 192;  // 128, 192, 256
-    public const int AesBlockSize = 128;  // ???
-
-    public const UInt16 AesAlgId128 = 0x660E; 
-    public const UInt16 AesAlgId192 = 0x660F; 
-    public const UInt16 AesAlgId256 = 0x6610; 
-
-  }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipCrypto.cs b/EPPlus/Packaging/DotNetZip/ZipCrypto.cs
deleted file mode 100644
index 6e7f625..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipCrypto.cs
+++ /dev/null
@@ -1,455 +0,0 @@
-// ZipCrypto.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008, 2009, 2011 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:30:59>
-//
-// ------------------------------------------------------------------
-//
-// This module provides the implementation for "traditional" Zip encryption.
-//
-// Created Tue Apr 15 17:39:56 2008
-//
-// ------------------------------------------------------------------
-
-using System;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    ///   This class implements the "traditional" or "classic" PKZip encryption,
-    ///   which today is considered to be weak. On the other hand it is
-    ///   ubiquitous. This class is intended for use only by the DotNetZip
-    ///   library.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///   Most uses of the DotNetZip library will not involve direct calls into
-    ///   the ZipCrypto class.  Instead, the ZipCrypto class is instantiated and
-    ///   used by the ZipEntry() class when encryption or decryption on an entry
-    ///   is employed.  If for some reason you really wanted to use a weak
-    ///   encryption algorithm in some other application, you might use this
-    ///   library.  But you would be much better off using one of the built-in
-    ///   strong encryption libraries in the .NET Framework, like the AES
-    ///   algorithm or SHA.
-    /// </remarks>
-    internal class ZipCrypto
-    {
-        /// <summary>
-        ///   The default constructor for ZipCrypto.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This class is intended for internal use by the library only. It's
-        ///   probably not useful to you. Seriously.  Stop reading this
-        ///   documentation.  It's a waste of your time.  Go do something else.
-        ///   Check the football scores. Go get an ice cream with a friend.
-        ///   Seriously.
-        /// </remarks>
-        ///
-        private ZipCrypto() { }
-
-        public static ZipCrypto ForWrite(string password)
-        {
-            ZipCrypto z = new ZipCrypto();
-            if (password == null)
-                throw new BadPasswordException("This entry requires a password.");
-            z.InitCipher(password);
-            return z;
-        }
-
-
-        public static ZipCrypto ForRead(string password, ZipEntry e)
-        {
-            System.IO.Stream s = e._archiveStream;
-            e._WeakEncryptionHeader = new byte[12];
-            byte[] eh = e._WeakEncryptionHeader;
-            ZipCrypto z = new ZipCrypto();
-
-            if (password == null)
-                throw new BadPasswordException("This entry requires a password.");
-
-            z.InitCipher(password);
-
-            ZipEntry.ReadWeakEncryptionHeader(s, eh);
-
-            // Decrypt the header.  This has a side effect of "further initializing the
-            // encryption keys" in the traditional zip encryption.
-            byte[] DecryptedHeader = z.DecryptMessage(eh, eh.Length);
-
-            // CRC check
-            // According to the pkzip spec, the final byte in the decrypted header
-            // is the highest-order byte in the CRC. We check it here.
-            if (DecryptedHeader[11] != (byte)((e._Crc32 >> 24) & 0xff))
-            {
-                // In the case that bit 3 of the general purpose bit flag is set to
-                // indicate the presence of an 'Extended File Header' or a 'data
-                // descriptor' (signature 0x08074b50), the last byte of the decrypted
-                // header is sometimes compared with the high-order byte of the
-                // lastmodified time, rather than the high-order byte of the CRC, to
-                // verify the password.
-                //
-                // This is not documented in the PKWare Appnote.txt.  It was
-                // discovered this by analysis of the Crypt.c source file in the
-                // InfoZip library http://www.info-zip.org/pub/infozip/
-                //
-                // The reason for this is that the CRC for a file cannot be known
-                // until the entire contents of the file have been streamed. This
-                // means a tool would have to read the file content TWICE in its
-                // entirety in order to perform PKZIP encryption - once to compute
-                // the CRC, and again to actually encrypt.
-                //
-                // This is so important for performance that using the timeblob as
-                // the verification should be the standard practice for DotNetZip
-                // when using PKZIP encryption. This implies that bit 3 must be
-                // set. The downside is that some tools still cannot cope with ZIP
-                // files that use bit 3.  Therefore, DotNetZip DOES NOT force bit 3
-                // when PKZIP encryption is in use, and instead, reads the stream
-                // twice.
-                //
-
-                if ((e._BitField & 0x0008) != 0x0008)
-                {
-                    throw new BadPasswordException("The password did not match.");
-                }
-                else if (DecryptedHeader[11] != (byte)((e._TimeBlob >> 8) & 0xff))
-                {
-                    throw new BadPasswordException("The password did not match.");
-                }
-
-                // We have a good password.
-            }
-            else
-            {
-                // A-OK
-            }
-            return z;
-        }
-
-
-
-
-        /// <summary>
-        /// From AppNote.txt:
-        /// unsigned char decrypt_byte()
-        ///     local unsigned short temp
-        ///     temp :=- Key(2) | 2
-        ///     decrypt_byte := (temp * (temp ^ 1)) bitshift-right 8
-        /// end decrypt_byte
-        /// </summary>
-        private byte MagicByte
-        {
-            get
-            {
-                UInt16 t = (UInt16)((UInt16)(_Keys[2] & 0xFFFF) | 2);
-                return (byte)((t * (t ^ 1)) >> 8);
-            }
-        }
-
-        // Decrypting:
-        // From AppNote.txt:
-        // loop for i from 0 to 11
-        //     C := buffer(i) ^ decrypt_byte()
-        //     update_keys(C)
-        //     buffer(i) := C
-        // end loop
-
-
-        /// <summary>
-        ///   Call this method on a cipher text to render the plaintext. You must
-        ///   first initialize the cipher with a call to InitCipher.
-        /// </summary>
-        ///
-        /// <example>
-        ///   <code>
-        ///     var cipher = new ZipCrypto();
-        ///     cipher.InitCipher(Password);
-        ///     // Decrypt the header.  This has a side effect of "further initializing the
-        ///     // encryption keys" in the traditional zip encryption.
-        ///     byte[] DecryptedMessage = cipher.DecryptMessage(EncryptedMessage);
-        ///   </code>
-        /// </example>
-        ///
-        /// <param name="cipherText">The encrypted buffer.</param>
-        /// <param name="length">
-        ///   The number of bytes to encrypt.
-        ///   Should be less than or equal to CipherText.Length.
-        /// </param>
-        ///
-        /// <returns>The plaintext.</returns>
-        public byte[] DecryptMessage(byte[] cipherText, int length)
-        {
-            if (cipherText == null)
-                throw new ArgumentNullException("cipherText");
-
-            if (length > cipherText.Length)
-                throw new ArgumentOutOfRangeException("length",
-                                                      "Bad length during Decryption: the length parameter must be smaller than or equal to the size of the destination array.");
-
-            byte[] plainText = new byte[length];
-            for (int i = 0; i < length; i++)
-            {
-                byte C = (byte)(cipherText[i] ^ MagicByte);
-                UpdateKeys(C);
-                plainText[i] = C;
-            }
-            return plainText;
-        }
-
-        /// <summary>
-        ///   This is the converse of DecryptMessage.  It encrypts the plaintext
-        ///   and produces a ciphertext.
-        /// </summary>
-        ///
-        /// <param name="plainText">The plain text buffer.</param>
-        ///
-        /// <param name="length">
-        ///   The number of bytes to encrypt.
-        ///   Should be less than or equal to plainText.Length.
-        /// </param>
-        ///
-        /// <returns>The ciphertext.</returns>
-        public byte[] EncryptMessage(byte[] plainText, int length)
-        {
-            if (plainText == null)
-                throw new ArgumentNullException("plaintext");
-
-            if (length > plainText.Length)
-                throw new ArgumentOutOfRangeException("length",
-                                                      "Bad length during Encryption: The length parameter must be smaller than or equal to the size of the destination array.");
-
-            byte[] cipherText = new byte[length];
-            for (int i = 0; i < length; i++)
-            {
-                byte C = plainText[i];
-                cipherText[i] = (byte)(plainText[i] ^ MagicByte);
-                UpdateKeys(C);
-            }
-            return cipherText;
-        }
-
-
-        /// <summary>
-        ///   This initializes the cipher with the given password.
-        ///   See AppNote.txt for details.
-        /// </summary>
-        ///
-        /// <param name="passphrase">
-        ///   The passphrase for encrypting or decrypting with this cipher.
-        /// </param>
-        ///
-        /// <remarks>
-        /// <code>
-        /// Step 1 - Initializing the encryption keys
-        /// -----------------------------------------
-        /// Start with these keys:
-        /// Key(0) := 305419896 (0x12345678)
-        /// Key(1) := 591751049 (0x23456789)
-        /// Key(2) := 878082192 (0x34567890)
-        ///
-        /// Then, initialize the keys with a password:
-        ///
-        /// loop for i from 0 to length(password)-1
-        ///     update_keys(password(i))
-        /// end loop
-        ///
-        /// Where update_keys() is defined as:
-        ///
-        /// update_keys(char):
-        ///   Key(0) := crc32(key(0),char)
-        ///   Key(1) := Key(1) + (Key(0) bitwiseAND 000000ffH)
-        ///   Key(1) := Key(1) * 134775813 + 1
-        ///   Key(2) := crc32(key(2),key(1) rightshift 24)
-        /// end update_keys
-        ///
-        /// Where crc32(old_crc,char) is a routine that given a CRC value and a
-        /// character, returns an updated CRC value after applying the CRC-32
-        /// algorithm described elsewhere in this document.
-        ///
-        /// </code>
-        ///
-        /// <para>
-        ///   After the keys are initialized, then you can use the cipher to
-        ///   encrypt the plaintext.
-        /// </para>
-        ///
-        /// <para>
-        ///   Essentially we encrypt the password with the keys, then discard the
-        ///   ciphertext for the password. This initializes the keys for later use.
-        /// </para>
-        ///
-        /// </remarks>
-        public void InitCipher(string passphrase)
-        {
-            byte[] p = SharedUtilities.StringToByteArray(passphrase);
-            for (int i = 0; i < passphrase.Length; i++)
-                UpdateKeys(p[i]);
-        }
-
-
-        private void UpdateKeys(byte byteValue)
-        {
-            _Keys[0] = (UInt32)crc32.ComputeCrc32((int)_Keys[0], byteValue);
-            _Keys[1] = _Keys[1] + (byte)_Keys[0];
-            _Keys[1] = _Keys[1] * 0x08088405 + 1;
-            _Keys[2] = (UInt32)crc32.ComputeCrc32((int)_Keys[2], (byte)(_Keys[1] >> 24));
-        }
-
-        ///// <summary>
-        ///// The byte array representing the seed keys used.
-        ///// Get this after calling InitCipher.  The 12 bytes represents
-        ///// what the zip spec calls the "EncryptionHeader".
-        ///// </summary>
-        //public byte[] KeyHeader
-        //{
-        //    get
-        //    {
-        //        byte[] result = new byte[12];
-        //        result[0] = (byte)(_Keys[0] & 0xff);
-        //        result[1] = (byte)((_Keys[0] >> 8) & 0xff);
-        //        result[2] = (byte)((_Keys[0] >> 16) & 0xff);
-        //        result[3] = (byte)((_Keys[0] >> 24) & 0xff);
-        //        result[4] = (byte)(_Keys[1] & 0xff);
-        //        result[5] = (byte)((_Keys[1] >> 8) & 0xff);
-        //        result[6] = (byte)((_Keys[1] >> 16) & 0xff);
-        //        result[7] = (byte)((_Keys[1] >> 24) & 0xff);
-        //        result[8] = (byte)(_Keys[2] & 0xff);
-        //        result[9] = (byte)((_Keys[2] >> 8) & 0xff);
-        //        result[10] = (byte)((_Keys[2] >> 16) & 0xff);
-        //        result[11] = (byte)((_Keys[2] >> 24) & 0xff);
-        //        return result;
-        //    }
-        //}
-
-        // private fields for the crypto stuff:
-        private UInt32[] _Keys = { 0x12345678, 0x23456789, 0x34567890 };
-        private Ionic.Crc.CRC32 crc32 = new Ionic.Crc.CRC32();
-
-    }
-
-    internal enum CryptoMode
-    {
-        Encrypt,
-        Decrypt
-    }
-
-    /// <summary>
-    ///   A Stream for reading and concurrently decrypting data from a zip file,
-    ///   or for writing and concurrently encrypting data to a zip file.
-    /// </summary>
-    internal class ZipCipherStream : System.IO.Stream
-    {
-        private ZipCrypto _cipher;
-        private System.IO.Stream _s;
-        private CryptoMode _mode;
-
-        /// <summary>  The constructor. </summary>
-        /// <param name="s">The underlying stream</param>
-        /// <param name="mode">To either encrypt or decrypt.</param>
-        /// <param name="cipher">The pre-initialized ZipCrypto object.</param>
-        public ZipCipherStream(System.IO.Stream s, ZipCrypto cipher, CryptoMode mode)
-            : base()
-        {
-            _cipher = cipher;
-            _s = s;
-            _mode = mode;
-        }
-
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            if (_mode == CryptoMode.Encrypt)
-                throw new NotSupportedException("This stream does not encrypt via Read()");
-
-            if (buffer == null)
-                throw new ArgumentNullException("buffer");
-
-            byte[] db = new byte[count];
-            int n = _s.Read(db, 0, count);
-            byte[] decrypted = _cipher.DecryptMessage(db, n);
-            for (int i = 0; i < n; i++)
-            {
-                buffer[offset + i] = decrypted[i];
-            }
-            return n;
-        }
-
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            if (_mode == CryptoMode.Decrypt)
-                throw new NotSupportedException("This stream does not Decrypt via Write()");
-
-            if (buffer == null)
-                throw new ArgumentNullException("buffer");
-
-            // workitem 7696
-            if (count == 0) return;
-
-            byte[] plaintext = null;
-            if (offset != 0)
-            {
-                plaintext = new byte[count];
-                for (int i = 0; i < count; i++)
-                {
-                    plaintext[i] = buffer[offset + i];
-                }
-            }
-            else plaintext = buffer;
-
-            byte[] encrypted = _cipher.EncryptMessage(plaintext, count);
-            _s.Write(encrypted, 0, encrypted.Length);
-        }
-
-
-        public override bool CanRead
-        {
-            get { return (_mode == CryptoMode.Decrypt); }
-        }
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-        public override bool CanWrite
-        {
-            get { return (_mode == CryptoMode.Encrypt); }
-        }
-
-        public override void Flush()
-        {
-            //throw new NotSupportedException();
-        }
-
-        public override long Length
-        {
-            get { throw new NotSupportedException(); }
-        }
-
-        public override long Position
-        {
-            get { throw new NotSupportedException(); }
-            set { throw new NotSupportedException(); }
-        }
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotSupportedException();
-        }
-
-        public override void SetLength(long value)
-        {
-            throw new NotSupportedException();
-        }
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipDirEntry.cs b/EPPlus/Packaging/DotNetZip/ZipDirEntry.cs
deleted file mode 100644
index ddc2447..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipDirEntry.cs
+++ /dev/null
@@ -1,381 +0,0 @@
-// ZipDirEntry.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006-2011 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-11 12:03:03>
-//
-// ------------------------------------------------------------------
-//
-// This module defines members of the ZipEntry class for reading the
-// Zip file central directory.
-//
-// Created: Tue, 27 Mar 2007  15:30
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.Collections.Generic;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    partial class ZipEntry
-    {
-        /// <summary>
-        /// True if the referenced entry is a directory.
-        /// </summary>
-        internal bool AttributesIndicateDirectory
-        {
-            get { return ((_InternalFileAttrs == 0) && ((_ExternalFileAttrs & 0x0010) == 0x0010)); }
-        }
-
-
-        internal void ResetDirEntry()
-        {
-            // __FileDataPosition is the position of the file data for an entry.
-            // It is _RelativeOffsetOfLocalHeader + size of local header.
-
-            // We cannot know the __FileDataPosition until we read the local
-            // header.
-
-            // The local header is not necessarily the same length as the record
-            // in the central directory.
-
-            // Set to -1, to indicate we need to read this later.
-            this.__FileDataPosition = -1;
-
-            // set _LengthOfHeader to 0, to indicate we need to read later.
-            this._LengthOfHeader = 0;
-        }
-
-        /// <summary>
-        /// Provides a human-readable string with information about the ZipEntry.
-        /// </summary>
-        public string Info
-        {
-            get
-            {
-                var builder = new System.Text.StringBuilder();
-                builder
-                    .Append(string.Format("          ZipEntry: {0}\n", this.FileName))
-                    .Append(string.Format("   Version Made By: {0}\n", this._VersionMadeBy))
-                    .Append(string.Format(" Needed to extract: {0}\n", this.VersionNeeded));
-
-                if (this._IsDirectory)
-                    builder.Append("        Entry type: directory\n");
-                else
-                {
-                    builder.Append(string.Format("         File type: {0}\n", this._IsText? "text":"binary"))
-                        .Append(string.Format("       Compression: {0}\n", this.CompressionMethod))
-                        .Append(string.Format("        Compressed: 0x{0:X}\n", this.CompressedSize))
-                        .Append(string.Format("      Uncompressed: 0x{0:X}\n", this.UncompressedSize))
-                        .Append(string.Format("             CRC32: 0x{0:X8}\n", this._Crc32));
-                }
-                builder.Append(string.Format("       Disk Number: {0}\n", this._diskNumber));
-                if (this._RelativeOffsetOfLocalHeader > 0xFFFFFFFF)
-                    builder
-                        .Append(string.Format("   Relative Offset: 0x{0:X16}\n", this._RelativeOffsetOfLocalHeader));
-                        else
-                    builder
-                        .Append(string.Format("   Relative Offset: 0x{0:X8}\n", this._RelativeOffsetOfLocalHeader));
-
-                    builder
-                    .Append(string.Format("         Bit Field: 0x{0:X4}\n", this._BitField))
-                    .Append(string.Format("        Encrypted?: {0}\n", this._sourceIsEncrypted))
-                    .Append(string.Format("          Timeblob: 0x{0:X8}\n", this._TimeBlob))
-                        .Append(string.Format("              Time: {0}\n", Ionic.Zip.SharedUtilities.PackedToDateTime(this._TimeBlob)));
-
-                builder.Append(string.Format("         Is Zip64?: {0}\n", this._InputUsesZip64));
-                if (!string.IsNullOrEmpty(this._Comment))
-                {
-                    builder.Append(string.Format("           Comment: {0}\n", this._Comment));
-                }
-                builder.Append("\n");
-                return builder.ToString();
-            }
-        }
-
-
-        // workitem 10330
-        private class CopyHelper
-        {
-            private static System.Text.RegularExpressions.Regex re =
-                new System.Text.RegularExpressions.Regex(" \\(copy (\\d+)\\)$");
-
-            private static int callCount = 0;
-
-            internal static string AppendCopyToFileName(string f)
-            {
-                callCount++;
-                if (callCount > 25)
-                    throw new OverflowException("overflow while creating filename");
-
-                int n = 1;
-                int r = f.LastIndexOf(".");
-
-                if (r == -1)
-                {
-                    // there is no extension
-                    System.Text.RegularExpressions.Match m = re.Match(f);
-                    if (m.Success)
-                    {
-                        n = Int32.Parse(m.Groups[1].Value) + 1;
-                        string copy = String.Format(" (copy {0})", n);
-                        f = f.Substring(0, m.Index) + copy;
-                    }
-                    else
-                    {
-                        string copy = String.Format(" (copy {0})", n);
-                        f = f + copy;
-                    }
-                }
-                else
-                {
-                    //System.Console.WriteLine("HasExtension");
-                    System.Text.RegularExpressions.Match m = re.Match(f.Substring(0, r));
-                    if (m.Success)
-                    {
-                        n = Int32.Parse(m.Groups[1].Value) + 1;
-                        string copy = String.Format(" (copy {0})", n);
-                        f = f.Substring(0, m.Index) + copy + f.Substring(r);
-                    }
-                    else
-                    {
-                        string copy = String.Format(" (copy {0})", n);
-                        f = f.Substring(0, r) + copy + f.Substring(r);
-                    }
-
-                    //System.Console.WriteLine("returning f({0})", f);
-                }
-                return f;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Reads one entry from the zip directory structure in the zip file.
-        /// </summary>
-        ///
-        /// <param name="zf">
-        ///   The zipfile for which a directory entry will be read.  From this param, the
-        ///   method gets the ReadStream and the expected text encoding
-        ///   (ProvisionalAlternateEncoding) which is used if the entry is not marked
-        ///   UTF-8.
-        /// </param>
-        ///
-        /// <param name="previouslySeen">
-        ///   a list of previously seen entry names; used to prevent duplicates.
-        /// </param>
-        ///
-        /// <returns>the entry read from the archive.</returns>
-        internal static ZipEntry ReadDirEntry(ZipFile zf,
-                                              Dictionary<String,Object> previouslySeen)
-        {
-            System.IO.Stream s = zf.ReadStream;
-            System.Text.Encoding expectedEncoding = (zf.AlternateEncodingUsage == ZipOption.Always)
-                ? zf.AlternateEncoding
-                : ZipFile.DefaultEncoding;
-
-            int signature = Ionic.Zip.SharedUtilities.ReadSignature(s);
-            // return null if this is not a local file header signature
-            if (IsNotValidZipDirEntrySig(signature))
-            {
-                s.Seek(-4, System.IO.SeekOrigin.Current);
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-
-                // Getting "not a ZipDirEntry signature" here is not always wrong or an
-                // error.  This can happen when walking through a zipfile.  After the
-                // last ZipDirEntry, we expect to read an
-                // EndOfCentralDirectorySignature.  When we get this is how we know
-                // we've reached the end of the central directory.
-                if (signature != ZipConstants.EndOfCentralDirectorySignature &&
-                    signature != ZipConstants.Zip64EndOfCentralDirectoryRecordSignature &&
-                    signature != ZipConstants.ZipEntrySignature  // workitem 8299
-                    )
-                {
-                    throw new BadReadException(String.Format("  Bad signature (0x{0:X8}) at position 0x{1:X8}", signature, s.Position));
-                }
-                return null;
-            }
-
-            int bytesRead = 42 + 4;
-            byte[] block = new byte[42];
-            int n = s.Read(block, 0, block.Length);
-            if (n != block.Length) return null;
-
-            int i = 0;
-            ZipEntry zde = new ZipEntry();
-            zde.AlternateEncoding = expectedEncoding;
-            zde._Source = ZipEntrySource.ZipFile;
-            zde._container = new ZipContainer(zf);
-
-            unchecked
-            {
-                zde._VersionMadeBy = (short)(block[i++] + block[i++] * 256);
-                zde._VersionNeeded = (short)(block[i++] + block[i++] * 256);
-                zde._BitField = (short)(block[i++] + block[i++] * 256);
-                zde._CompressionMethod = (Int16)(block[i++] + block[i++] * 256);
-                zde._TimeBlob = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
-                zde._LastModified = Ionic.Zip.SharedUtilities.PackedToDateTime(zde._TimeBlob);
-                zde._timestamp |= ZipEntryTimestamp.DOS;
-
-                zde._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
-                zde._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-                zde._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-            }
-
-            // preserve
-            zde._CompressionMethod_FromZipFile = zde._CompressionMethod;
-
-            zde._filenameLength = (short)(block[i++] + block[i++] * 256);
-            zde._extraFieldLength = (short)(block[i++] + block[i++] * 256);
-            zde._commentLength = (short)(block[i++] + block[i++] * 256);
-            zde._diskNumber = (UInt32)(block[i++] + block[i++] * 256);
-
-            zde._InternalFileAttrs = (short)(block[i++] + block[i++] * 256);
-            zde._ExternalFileAttrs = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
-
-            zde._RelativeOffsetOfLocalHeader = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-
-            // workitem 7801
-            zde.IsText = ((zde._InternalFileAttrs & 0x01) == 0x01);
-
-            block = new byte[zde._filenameLength];
-            n = s.Read(block, 0, block.Length);
-            bytesRead += n;
-            if ((zde._BitField & 0x0800) == 0x0800)
-            {
-                // UTF-8 is in use
-                zde._FileNameInArchive = Ionic.Zip.SharedUtilities.Utf8StringFromBuffer(block);
-            }
-            else
-            {
-                zde._FileNameInArchive = Ionic.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding);
-            }
-
-            // workitem 10330
-            // insure unique entry names
-            while (previouslySeen.ContainsKey(zde._FileNameInArchive))
-            {
-                zde._FileNameInArchive = CopyHelper.AppendCopyToFileName(zde._FileNameInArchive);
-                zde._metadataChanged = true;
-            }
-
-            if (zde.AttributesIndicateDirectory)
-                zde.MarkAsDirectory();  // may append a slash to filename if nec.
-            // workitem 6898
-            else if (zde._FileNameInArchive.EndsWith("/")) zde.MarkAsDirectory();
-
-            zde._CompressedFileDataSize = zde._CompressedSize;
-            if ((zde._BitField & 0x01) == 0x01)
-            {
-                // this may change after processing the Extra field
-                zde._Encryption_FromZipFile = zde._Encryption =
-                    EncryptionAlgorithm.PkzipWeak;
-                zde._sourceIsEncrypted = true;
-            }
-
-            if (zde._extraFieldLength > 0)
-            {
-                zde._InputUsesZip64 = (zde._CompressedSize == 0xFFFFFFFF ||
-                      zde._UncompressedSize == 0xFFFFFFFF ||
-                      zde._RelativeOffsetOfLocalHeader == 0xFFFFFFFF);
-
-                // Console.WriteLine("  Input uses Z64?:      {0}", zde._InputUsesZip64);
-
-                bytesRead += zde.ProcessExtraField(s, zde._extraFieldLength);
-                zde._CompressedFileDataSize = zde._CompressedSize;
-            }
-
-            // we've processed the extra field, so we know the encryption method is set now.
-            if (zde._Encryption == EncryptionAlgorithm.PkzipWeak)
-            {
-                // the "encryption header" of 12 bytes precedes the file data
-                zde._CompressedFileDataSize -= 12;
-            }
-#if AESCRYPTO
-            else if (zde.Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                        zde.Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                zde._CompressedFileDataSize = zde.CompressedSize -
-                    (ZipEntry.GetLengthOfCryptoHeaderBytes(zde.Encryption) + 10);
-                zde._LengthOfTrailer = 10;
-            }
-#endif
-
-            // tally the trailing descriptor
-            if ((zde._BitField & 0x0008) == 0x0008)
-            {
-                // sig, CRC, Comp and Uncomp sizes
-                if (zde._InputUsesZip64)
-                    zde._LengthOfTrailer += 24;
-                else
-                    zde._LengthOfTrailer += 16;
-            }
-
-            // workitem 12744
-            zde.AlternateEncoding = ((zde._BitField & 0x0800) == 0x0800)
-                ? System.Text.Encoding.UTF8
-                :expectedEncoding;
-
-            zde.AlternateEncodingUsage = ZipOption.Always;
-
-            if (zde._commentLength > 0)
-            {
-                block = new byte[zde._commentLength];
-                n = s.Read(block, 0, block.Length);
-                bytesRead += n;
-                if ((zde._BitField & 0x0800) == 0x0800)
-                {
-                    // UTF-8 is in use
-                    zde._Comment = Ionic.Zip.SharedUtilities.Utf8StringFromBuffer(block);
-                }
-                else
-                {
-                    zde._Comment = Ionic.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding);
-                }
-            }
-            //zde._LengthOfDirEntry = bytesRead;
-            return zde;
-        }
-
-
-        /// <summary>
-        /// Returns true if the passed-in value is a valid signature for a ZipDirEntry.
-        /// </summary>
-        /// <param name="signature">the candidate 4-byte signature value.</param>
-        /// <returns>true, if the signature is valid according to the PKWare spec.</returns>
-        internal static bool IsNotValidZipDirEntrySig(int signature)
-        {
-            return (signature != ZipConstants.ZipDirEntrySignature);
-        }
-
-
-        private Int16 _VersionMadeBy;
-        private Int16 _InternalFileAttrs;
-        private Int32 _ExternalFileAttrs;
-
-        //private Int32 _LengthOfDirEntry;
-        private Int16 _filenameLength;
-        private Int16 _extraFieldLength;
-        private Int16 _commentLength;
-    }
-
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipEntry.Extract.cs b/EPPlus/Packaging/DotNetZip/ZipEntry.Extract.cs
deleted file mode 100644
index eb92b4c..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipEntry.Extract.cs
+++ /dev/null
@@ -1,1455 +0,0 @@
-// ZipEntry.Extract.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-August-06 18:08:21>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for Extract methods on the ZipEntry class.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    internal partial class ZipEntry
-    {
-        /// <summary>
-        ///   Extract the entry to the filesystem, starting at the current
-        ///   working directory.
-        /// </summary>
-        ///
-        /// <overloads>
-        ///   This method has a bunch of overloads! One of them is sure to
-        ///   be the right one for you... If you don't like these, check
-        ///   out the <c>ExtractWithPassword()</c> methods.
-        /// </overloads>
-        ///
-        /// <seealso cref="ZipEntry.ExtractExistingFile"/>
-        /// <seealso cref="ZipEntry.Extract(ExtractExistingFileAction)"/>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This method extracts an entry from a zip file into the current
-        ///   working directory.  The path of the entry as extracted is the full
-        ///   path as specified in the zip archive, relative to the current
-        ///   working directory.  After the file is extracted successfully, the
-        ///   file attributes and timestamps are set.
-        /// </para>
-        ///
-        /// <para>
-        ///   The action taken when extraction an entry would overwrite an
-        ///   existing file is determined by the <see cref="ExtractExistingFile"
-        ///   /> property.
-        /// </para>
-        ///
-        /// <para>
-        ///   Within the call to <c>Extract()</c>, the content for the entry is
-        ///   written into a filesystem file, and then the last modified time of the
-        ///   file is set according to the <see cref="LastModified"/> property on
-        ///   the entry. See the remarks the <see cref="LastModified"/> property for
-        ///   some details about the last modified time.
-        /// </para>
-        ///
-        /// </remarks>
-        internal void Extract()
-        {
-            InternalExtract(".", null, null);
-        }
-
-
-        /// <summary>
-        ///   Extract the entry to a file in the filesystem, using the specified
-        ///   behavior when extraction would overwrite an existing file.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the remarks on the <see cref="LastModified"/> property, for some
-        ///   details about how the last modified time of the file is set after
-        ///   extraction.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="extractExistingFile">
-        ///   The action to take if extraction would overwrite an existing file.
-        /// </param>
-        internal void Extract(ExtractExistingFileAction extractExistingFile)
-        {
-            ExtractExistingFile = extractExistingFile;
-            InternalExtract(".", null, null);
-        }
-
-        /// <summary>
-        ///   Extracts the entry to the specified stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The caller can specify any write-able stream, for example a <see
-        ///   cref="System.IO.FileStream"/>, a <see
-        ///   cref="System.IO.MemoryStream"/>, or ASP.NET's
-        ///   <c>Response.OutputStream</c>.  The content will be decrypted and
-        ///   decompressed as necessary. If the entry is encrypted and no password
-        ///   is provided, this method will throw.
-        /// </para>
-        /// <para>
-        ///   The position on the stream is not reset by this method before it extracts.
-        ///   You may want to call stream.Seek() before calling ZipEntry.Extract().
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="stream">
-        ///   the stream to which the entry should be extracted.
-        /// </param>
-        ///
-        public void Extract(Stream stream)
-        {
-            InternalExtract(null, stream, null);
-        }
-
-        /// <summary>
-        ///   Extract the entry to the filesystem, starting at the specified base
-        ///   directory.
-        /// </summary>
-        ///
-        /// <param name="baseDirectory">the pathname of the base directory</param>
-        ///
-        /// <seealso cref="ZipEntry.ExtractExistingFile"/>
-        /// <seealso cref="ZipEntry.Extract(string, ExtractExistingFileAction)"/>
-        ///
-        /// <example>
-        /// This example extracts only the entries in a zip file that are .txt files,
-        /// into a directory called "textfiles".
-        /// <code lang="C#">
-        /// using (ZipFile zip = ZipFile.Read("PackedDocuments.zip"))
-        /// {
-        ///   foreach (string s1 in zip.EntryFilenames)
-        ///   {
-        ///     if (s1.EndsWith(".txt"))
-        ///     {
-        ///       zip[s1].Extract("textfiles");
-        ///     }
-        ///   }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        ///   Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip")
-        ///       Dim s1 As String
-        ///       For Each s1 In zip.EntryFilenames
-        ///           If s1.EndsWith(".txt") Then
-        ///               zip(s1).Extract("textfiles")
-        ///           End If
-        ///       Next
-        ///   End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Using this method, existing entries in the filesystem will not be
-        ///   overwritten. If you would like to force the overwrite of existing
-        ///   files, see the <see cref="ExtractExistingFile"/> property, or call
-        ///   <see cref="Extract(string, ExtractExistingFileAction)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   See the remarks on the <see cref="LastModified"/> property, for some
-        ///   details about how the last modified time of the created file is set.
-        /// </para>
-        /// </remarks>
-        public void Extract(string baseDirectory)
-        {
-            InternalExtract(baseDirectory, null, null);
-        }
-
-
-
-
-
-        /// <summary>
-        ///   Extract the entry to the filesystem, starting at the specified base
-        ///   directory, and using the specified behavior when extraction would
-        ///   overwrite an existing file.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the remarks on the <see cref="LastModified"/> property, for some
-        ///   details about how the last modified time of the created file is set.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code lang="C#">
-        /// String sZipPath = "Airborne.zip";
-        /// String sFilePath = "Readme.txt";
-        /// String sRootFolder = "Digado";
-        /// using (ZipFile zip = ZipFile.Read(sZipPath))
-        /// {
-        ///   if (zip.EntryFileNames.Contains(sFilePath))
-        ///   {
-        ///     // use the string indexer on the zip file
-        ///     zip[sFileName].Extract(sRootFolder,
-        ///                            ExtractExistingFileAction.OverwriteSilently);
-        ///   }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim sZipPath as String = "Airborne.zip"
-        /// Dim sFilePath As String = "Readme.txt"
-        /// Dim sRootFolder As String = "Digado"
-        /// Using zip As ZipFile = ZipFile.Read(sZipPath)
-        ///   If zip.EntryFileNames.Contains(sFilePath)
-        ///     ' use the string indexer on the zip file
-        ///     zip(sFilePath).Extract(sRootFolder, _
-        ///                            ExtractExistingFileAction.OverwriteSilently)
-        ///   End If
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="baseDirectory">the pathname of the base directory</param>
-        /// <param name="extractExistingFile">
-        /// The action to take if extraction would overwrite an existing file.
-        /// </param>
-        internal void Extract(string baseDirectory, ExtractExistingFileAction extractExistingFile)
-        {
-            ExtractExistingFile = extractExistingFile;
-            InternalExtract(baseDirectory, null, null);
-        }
-
-
-        /// <summary>
-        ///   Extract the entry to the filesystem, using the current working directory
-        ///   and the specified password.
-        /// </summary>
-        ///
-        /// <overloads>
-        ///   This method has a bunch of overloads! One of them is sure to be
-        ///   the right one for you...
-        /// </overloads>
-        ///
-        /// <seealso cref="ZipEntry.ExtractExistingFile"/>
-        /// <seealso cref="ZipEntry.ExtractWithPassword(ExtractExistingFileAction, string)"/>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Existing entries in the filesystem will not be overwritten. If you
-        ///   would like to force the overwrite of existing files, see the <see
-        ///   cref="ZipEntry.ExtractExistingFile"/>property, or call
-        ///   <see
-        ///   cref="ExtractWithPassword(ExtractExistingFileAction,string)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   See the remarks on the <see cref="LastModified"/> property for some
-        ///   details about how the "last modified" time of the created file is
-        ///   set.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///   In this example, entries that use encryption are extracted using a
-        ///   particular password.
-        /// <code>
-        /// using (var zip = ZipFile.Read(FilePath))
-        /// {
-        ///     foreach (ZipEntry e in zip)
-        ///     {
-        ///         if (e.UsesEncryption)
-        ///             e.ExtractWithPassword("Secret!");
-        ///         else
-        ///             e.Extract();
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read(FilePath)
-        ///     Dim e As ZipEntry
-        ///     For Each e In zip
-        ///         If (e.UsesEncryption)
-        ///           e.ExtractWithPassword("Secret!")
-        ///         Else
-        ///           e.Extract
-        ///         End If
-        ///     Next
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="password">The Password to use for decrypting the entry.</param>
-        public void ExtractWithPassword(string password)
-        {
-            InternalExtract(".", null, password);
-        }
-
-        /// <summary>
-        ///   Extract the entry to the filesystem, starting at the specified base
-        ///   directory, and using the specified password.
-        /// </summary>
-        ///
-        /// <seealso cref="ZipEntry.ExtractExistingFile"/>
-        /// <seealso cref="ZipEntry.ExtractWithPassword(string, ExtractExistingFileAction, string)"/>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Existing entries in the filesystem will not be overwritten. If you
-        ///   would like to force the overwrite of existing files, see the <see
-        ///   cref="ZipEntry.ExtractExistingFile"/>property, or call
-        ///   <see
-        ///   cref="ExtractWithPassword(ExtractExistingFileAction,string)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   See the remarks on the <see cref="LastModified"/> property, for some
-        ///   details about how the last modified time of the created file is set.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="baseDirectory">The pathname of the base directory.</param>
-        /// <param name="password">The Password to use for decrypting the entry.</param>
-        public void ExtractWithPassword(string baseDirectory, string password)
-        {
-            InternalExtract(baseDirectory, null, password);
-        }
-
-
-
-
-        /// <summary>
-        ///   Extract the entry to a file in the filesystem, relative to the
-        ///   current directory, using the specified behavior when extraction
-        ///   would overwrite an existing file.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the remarks on the <see cref="LastModified"/> property, for some
-        ///   details about how the last modified time of the created file is set.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="password">The Password to use for decrypting the entry.</param>
-        ///
-        /// <param name="extractExistingFile">
-        /// The action to take if extraction would overwrite an existing file.
-        /// </param>
-        internal void ExtractWithPassword(ExtractExistingFileAction extractExistingFile, string password)
-        {
-            ExtractExistingFile = extractExistingFile;
-            InternalExtract(".", null, password);
-        }
-
-
-
-        /// <summary>
-        ///   Extract the entry to the filesystem, starting at the specified base
-        ///   directory, and using the specified behavior when extraction would
-        ///   overwrite an existing file.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   See the remarks on the <see cref="LastModified"/> property, for some
-        ///   details about how the last modified time of the created file is set.
-        /// </remarks>
-        ///
-        /// <param name="baseDirectory">the pathname of the base directory</param>
-        ///
-        /// <param name="extractExistingFile">The action to take if extraction would
-        /// overwrite an existing file.</param>
-        ///
-        /// <param name="password">The Password to use for decrypting the entry.</param>
-        internal void ExtractWithPassword(string baseDirectory, ExtractExistingFileAction extractExistingFile, string password)
-        {
-            ExtractExistingFile = extractExistingFile;
-            InternalExtract(baseDirectory, null, password);
-        }
-
-        /// <summary>
-        ///   Extracts the entry to the specified stream, using the specified
-        ///   Password.  For example, the caller could extract to Console.Out, or
-        ///   to a MemoryStream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The caller can specify any write-able stream, for example a <see
-        ///   cref="System.IO.FileStream"/>, a <see
-        ///   cref="System.IO.MemoryStream"/>, or ASP.NET's
-        ///   <c>Response.OutputStream</c>.  The content will be decrypted and
-        ///   decompressed as necessary. If the entry is encrypted and no password
-        ///   is provided, this method will throw.
-        /// </para>
-        /// <para>
-        ///   The position on the stream is not reset by this method before it extracts.
-        ///   You may want to call stream.Seek() before calling ZipEntry.Extract().
-        /// </para>
-        /// </remarks>
-        ///
-        ///
-        /// <param name="stream">
-        ///   the stream to which the entry should be extracted.
-        /// </param>
-        /// <param name="password">
-        ///   The password to use for decrypting the entry.
-        /// </param>
-        public void ExtractWithPassword(Stream stream, string password)
-        {
-            InternalExtract(null, stream, password);
-        }
-
-
-        /// <summary>
-        ///   Opens a readable stream corresponding to the zip entry in the
-        ///   archive.  The stream decompresses and decrypts as necessary, as it
-        ///   is read.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   DotNetZip offers a variety of ways to extract entries from a zip
-        ///   file.  This method allows an application to extract an entry by
-        ///   reading a <see cref="System.IO.Stream"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   The return value is of type <see
-        ///   cref="Ionic.Crc.CrcCalculatorStream"/>.  Use it as you would any
-        ///   stream for reading.  When an application calls <see
-        ///   cref="Stream.Read(byte[], int, int)"/> on that stream, it will
-        ///   receive data from the zip entry that is decrypted and decompressed
-        ///   as necessary.
-        /// </para>
-        ///
-        /// <para>
-        ///   <c>CrcCalculatorStream</c> adds one additional feature: it keeps a
-        ///   CRC32 checksum on the bytes of the stream as it is read.  The CRC
-        ///   value is available in the <see
-        ///   cref="Ionic.Crc.CrcCalculatorStream.Crc"/> property on the
-        ///   <c>CrcCalculatorStream</c>.  When the read is complete, your
-        ///   application
-        ///   <em>should</em> check this CRC against the <see cref="ZipEntry.Crc"/>
-        ///   property on the <c>ZipEntry</c> to validate the content of the
-        ///   ZipEntry. You don't have to validate the entry using the CRC, but
-        ///   you should, to verify integrity. Check the example for how to do
-        ///   this.
-        /// </para>
-        ///
-        /// <para>
-        ///   If the entry is protected with a password, then you need to provide
-        ///   a password prior to calling <see cref="OpenReader()"/>, either by
-        ///   setting the <see cref="Password"/> property on the entry, or the
-        ///   <see cref="ZipFile.Password"/> property on the <c>ZipFile</c>
-        ///   itself. Or, you can use <see cref="OpenReader(String)" />, the
-        ///   overload of OpenReader that accepts a password parameter.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you want to extract entry data into a write-able stream that is
-        ///   already opened, like a <see cref="System.IO.FileStream"/>, do not
-        ///   use this method. Instead, use <see cref="Extract(Stream)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Your application may use only one stream created by OpenReader() at
-        ///   a time, and you should not call other Extract methods before
-        ///   completing your reads on a stream obtained from OpenReader().  This
-        ///   is because there is really only one source stream for the compressed
-        ///   content.  A call to OpenReader() seeks in the source stream, to the
-        ///   beginning of the compressed content.  A subsequent call to
-        ///   OpenReader() on a different entry will seek to a different position
-        ///   in the source stream, as will a call to Extract() or one of its
-        ///   overloads.  This will corrupt the state for the decompressing stream
-        ///   from the original call to OpenReader().
-        /// </para>
-        ///
-        /// <para>
-        ///    The <c>OpenReader()</c> method works only when the ZipEntry is
-        ///    obtained from an instance of <c>ZipFile</c>. This method will throw
-        ///    an exception if the ZipEntry is obtained from a ZipInputStream.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example shows how to open a zip archive, then read in a named
-        ///   entry via a stream. After the read loop is complete, the code
-        ///   compares the calculated during the read loop with the expected CRC
-        ///   on the <c>ZipEntry</c>, to verify the extraction.
-        /// <code>
-        /// using (ZipFile zip = new ZipFile(ZipFileToRead))
-        /// {
-        ///   ZipEntry e1= zip["Elevation.mp3"];
-        ///   using (Ionic.Zlib.CrcCalculatorStream s = e1.OpenReader())
-        ///   {
-        ///     byte[] buffer = new byte[4096];
-        ///     int n, totalBytesRead= 0;
-        ///     do {
-        ///       n = s.Read(buffer,0, buffer.Length);
-        ///       totalBytesRead+=n;
-        ///     } while (n&gt;0);
-        ///      if (s.Crc32 != e1.Crc32)
-        ///       throw new Exception(string.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32));
-        ///      if (totalBytesRead != e1.UncompressedSize)
-        ///       throw new Exception(string.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize));
-        ///   }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        ///   Using zip As New ZipFile(ZipFileToRead)
-        ///       Dim e1 As ZipEntry = zip.Item("Elevation.mp3")
-        ///       Using s As Ionic.Zlib.CrcCalculatorStream = e1.OpenReader
-        ///           Dim n As Integer
-        ///           Dim buffer As Byte() = New Byte(4096) {}
-        ///           Dim totalBytesRead As Integer = 0
-        ///           Do
-        ///               n = s.Read(buffer, 0, buffer.Length)
-        ///               totalBytesRead = (totalBytesRead + n)
-        ///           Loop While (n &gt; 0)
-        ///           If (s.Crc32 &lt;&gt; e1.Crc32) Then
-        ///               Throw New Exception(String.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32))
-        ///           End If
-        ///           If (totalBytesRead &lt;&gt; e1.UncompressedSize) Then
-        ///               Throw New Exception(String.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize))
-        ///           End If
-        ///       End Using
-        ///   End Using
-        /// </code>
-        /// </example>
-        /// <seealso cref="ZipEntry.Extract(System.IO.Stream)"/>
-        /// <returns>The Stream for reading.</returns>
-        internal Ionic.Crc.CrcCalculatorStream OpenReader()
-        {
-            // workitem 10923
-            if (_container.ZipFile == null)
-                throw new InvalidOperationException("Use OpenReader() only with ZipFile.");
-
-            // use the entry password if it is non-null,
-            // else use the zipfile password, which is possibly null
-            return InternalOpenReader(this._Password ?? this._container.Password);
-        }
-
-        /// <summary>
-        ///   Opens a readable stream for an encrypted zip entry in the archive.
-        ///   The stream decompresses and decrypts as necessary, as it is read.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the documentation on the <see cref="OpenReader()"/> method for
-        ///   full details. This overload allows the application to specify a
-        ///   password for the <c>ZipEntry</c> to be read.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="password">The password to use for decrypting the entry.</param>
-        /// <returns>The Stream for reading.</returns>
-        internal Ionic.Crc.CrcCalculatorStream OpenReader(string password)
-        {
-            // workitem 10923
-            if (_container.ZipFile == null)
-                throw new InvalidOperationException("Use OpenReader() only with ZipFile.");
-
-            return InternalOpenReader(password);
-        }
-
-
-
-        internal Ionic.Crc.CrcCalculatorStream InternalOpenReader(string password)
-        {
-            ValidateCompression();
-            ValidateEncryption();
-            SetupCryptoForExtract(password);
-
-            // workitem 7958
-            if (this._Source != ZipEntrySource.ZipFile)
-                throw new BadStateException("You must call ZipFile.Save before calling OpenReader");
-
-            // LeftToRead is a count of bytes remaining to be read (out)
-            // from the stream AFTER decompression and decryption.
-            // It is the uncompressed size, unless ... there is no compression in which
-            // case ...?  :< I'm not sure why it's not always UncompressedSize
-            Int64 LeftToRead = (_CompressionMethod_FromZipFile == (short)CompressionMethod.None)
-                ? this._CompressedFileDataSize
-                : this.UncompressedSize;
-
-            Stream input = this.ArchiveStream;
-
-            this.ArchiveStream.Seek(this.FileDataPosition, SeekOrigin.Begin);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
-            _inputDecryptorStream = GetExtractDecryptor(input);
-            Stream input3 = GetExtractDecompressor(_inputDecryptorStream);
-
-            return new Ionic.Crc.CrcCalculatorStream(input3, LeftToRead);
-        }
-
-
-
-        private void OnExtractProgress(Int64 bytesWritten, Int64 totalBytesToWrite)
-        {
-            if (_container.ZipFile != null)
-            _ioOperationCanceled = _container.ZipFile.OnExtractBlock(this, bytesWritten, totalBytesToWrite);
-        }
-
-
-        private void OnBeforeExtract(string path)
-        {
-            // When in the context of a ZipFile.ExtractAll, the events are generated from
-            // the ZipFile method, not from within the ZipEntry instance. (why?)
-            // Therefore we suppress the events originating from the ZipEntry method.
-            if (_container.ZipFile != null)
-            {
-                if (!_container.ZipFile._inExtractAll)
-                {
-                    _ioOperationCanceled = _container.ZipFile.OnSingleEntryExtract(this, path, true);
-                }
-            }
-        }
-
-        private void OnAfterExtract(string path)
-        {
-            // When in the context of a ZipFile.ExtractAll, the events are generated from
-            // the ZipFile method, not from within the ZipEntry instance. (why?)
-            // Therefore we suppress the events originating from the ZipEntry method.
-            if (_container.ZipFile != null)
-            {
-                if (!_container.ZipFile._inExtractAll)
-                {
-                    _container.ZipFile.OnSingleEntryExtract(this, path, false);
-                }
-            }
-        }
-
-        private void OnExtractExisting(string path)
-        {
-            if (_container.ZipFile != null)
-                _ioOperationCanceled = _container.ZipFile.OnExtractExisting(this, path);
-        }
-
-        private static void ReallyDelete(string fileName)
-        {
-            // workitem 7881
-            // reset ReadOnly bit if necessary
-#if NETCF
-            if ( (NetCfFile.GetAttributes(fileName) & (uint)FileAttributes.ReadOnly) == (uint)FileAttributes.ReadOnly)
-                NetCfFile.SetAttributes(fileName, (uint)FileAttributes.Normal);
-#elif SILVERLIGHT
-#else
-            if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
-                File.SetAttributes(fileName, FileAttributes.Normal);
-#endif
-            File.Delete(fileName);
-        }
-
-
-        private void WriteStatus(string format, params Object[] args)
-        {
-            if (_container.ZipFile != null && _container.ZipFile.Verbose) _container.ZipFile.StatusMessageTextWriter.WriteLine(format, args);
-        }
-
-
-        // Pass in either basedir or s, but not both.
-        // In other words, you can extract to a stream or to a directory (filesystem), but not both!
-        // The Password param is required for encrypted entries.
-        private void InternalExtract(string baseDir, Stream outstream, string password)
-        {
-            // workitem 7958
-            if (_container == null)
-                throw new BadStateException("This entry is an orphan");
-
-            // workitem 10355
-            if (_container.ZipFile == null)
-                throw new InvalidOperationException("Use Extract() only with ZipFile.");
-
-            _container.ZipFile.Reset(false);
-
-            if (this._Source != ZipEntrySource.ZipFile)
-                throw new BadStateException("You must call ZipFile.Save before calling any Extract method");
-
-            OnBeforeExtract(baseDir);
-            _ioOperationCanceled = false;
-            string targetFileName = null;
-            Stream output = null;
-            bool fileExistsBeforeExtraction = false;
-            bool checkLaterForResetDirTimes = false;
-            try
-            {
-                ValidateCompression();
-                ValidateEncryption();
-
-                if (ValidateOutput(baseDir, outstream, out targetFileName))
-                {
-                    WriteStatus("extract dir {0}...", targetFileName);
-                    // if true, then the entry was a directory and has been created.
-                    // We need to fire the Extract Event.
-                    OnAfterExtract(baseDir);
-                    return;
-                }
-
-                // workitem 10639
-                // do we want to extract to a regular filesystem file?
-                if (targetFileName != null)
-                {
-                    // Check for extracting to a previously extant file. The user
-                    // can specify bejavior for that case: overwrite, don't
-                    // overwrite, and throw.  Also, if the file exists prior to
-                    // extraction, it affects exception handling: whether to delete
-                    // the target of extraction or not.  This check needs to be done
-                    // before the password check is done, because password check may
-                    // throw a BadPasswordException, which triggers the catch,
-                    // wherein the extant file may be deleted if not flagged as
-                    // pre-existing.
-                    if (File.Exists(targetFileName))
-                    {
-                        fileExistsBeforeExtraction = true;
-                        int rc = CheckExtractExistingFile(baseDir, targetFileName);
-                        if (rc == 2) goto ExitTry; // cancel
-                        if (rc == 1) return; // do not overwrite
-                    }
-                }
-
-                // If no password explicitly specified, use the password on the entry itself,
-                // or on the zipfile itself.
-                string p = password ?? this._Password ?? this._container.Password;
-                if (_Encryption_FromZipFile != EncryptionAlgorithm.None)
-                {
-                    if (p == null)
-                        throw new BadPasswordException();
-                    SetupCryptoForExtract(p);
-                }
-
-
-                // set up the output stream
-                if (targetFileName != null)
-                {
-                    WriteStatus("extract file {0}...", targetFileName);
-                    targetFileName += ".tmp";
-                    var dirName = Path.GetDirectoryName(targetFileName);
-                    // ensure the target path exists
-                    if (!Directory.Exists(dirName))
-                    {
-                        // we create the directory here, but we do not set the
-                        // create/modified/accessed times on it because it is being
-                        // created implicitly, not explcitly. There's no entry in the
-                        // zip archive for the directory.
-                        Directory.CreateDirectory(dirName);
-                    }
-                    else
-                    {
-                        // workitem 8264
-                        if (_container.ZipFile != null)
-                            checkLaterForResetDirTimes = _container.ZipFile._inExtractAll;
-                    }
-
-                    // File.Create(CreateNew) will overwrite any existing file.
-                    output = new FileStream(targetFileName, FileMode.CreateNew);
-                }
-                else
-                {
-                    WriteStatus("extract entry {0} to stream...", FileName);
-                    output = outstream;
-                }
-
-
-                if (_ioOperationCanceled)
-                    goto ExitTry;
-
-                Int32 ActualCrc32 = ExtractOne(output);
-
-                if (_ioOperationCanceled)
-                    goto ExitTry;
-
-                VerifyCrcAfterExtract(ActualCrc32);
-
-                if (targetFileName != null)
-                {
-                    output.Close();
-                    output = null;
-
-                    // workitem 10639
-                    // move file to permanent home
-                    string tmpName = targetFileName;
-                    string zombie = null;
-                    targetFileName = tmpName.Substring(0,tmpName.Length-4);
-
-                    if (fileExistsBeforeExtraction)
-                    {
-                        // An AV program may hold the target file open, which means
-                        // File.Delete() will succeed, though the actual deletion
-                        // remains pending. This will prevent a subsequent
-                        // File.Move() from succeeding. To avoid this, when the file
-                        // already exists, we need to replace it in 3 steps:
-                        //
-                        //     1. rename the existing file to a zombie name;
-                        //     2. rename the extracted file from the temp name to
-                        //        the target file name;
-                        //     3. delete the zombie.
-                        //
-                        zombie = targetFileName + ".PendingOverwrite";
-                        File.Move(targetFileName, zombie);
-                    }
-
-                    File.Move(tmpName, targetFileName);
-                    _SetTimes(targetFileName, true);
-
-                    if (zombie != null && File.Exists(zombie))
-                        ReallyDelete(zombie);
-
-                    // workitem 8264
-                    if (checkLaterForResetDirTimes)
-                    {
-                        // This is sort of a hack.  What I do here is set the time on
-                        // the parent directory, every time a file is extracted into
-                        // it.  If there is a directory with 1000 files, then I set
-                        // the time on the dir, 1000 times. This allows the directory
-                        // to have times that reflect the actual time on the entry in
-                        // the zip archive.
-
-                        // String.Contains is not available on .NET CF 2.0
-                        if (this.FileName.IndexOf('/') != -1)
-                        {
-                            string dirname = Path.GetDirectoryName(this.FileName);
-                            if (this._container.ZipFile[dirname] == null)
-                            {
-                                _SetTimes(Path.GetDirectoryName(targetFileName), false);
-                            }
-                        }
-                    }
-
-#if NETCF
-                    // workitem 7926 - version made by OS can be zero or 10
-                    if ((_VersionMadeBy & 0xFF00) == 0x0a00 || (_VersionMadeBy & 0xFF00) == 0x0000)
-                        NetCfFile.SetAttributes(targetFileName, (uint)_ExternalFileAttrs);
-
-#else
-                    // workitem 7071
-                    //
-                    // We can only apply attributes if they are relevant to the NTFS
-                    // OS.  Must do this LAST because it may involve a ReadOnly bit,
-                    // which would prevent us from setting the time, etc.
-                    //
-                    // workitem 7926 - version made by OS can be zero (FAT) or 10
-                    // (NTFS)
-                    if ((_VersionMadeBy & 0xFF00) == 0x0a00 || (_VersionMadeBy & 0xFF00) == 0x0000)
-                        File.SetAttributes(targetFileName, (FileAttributes)_ExternalFileAttrs);
-#endif
-                }
-
-                OnAfterExtract(baseDir);
-
-                ExitTry: ;
-            }
-            catch (Exception)
-            {
-                _ioOperationCanceled = true;
-                throw;
-            }
-            finally
-            {
-                if (_ioOperationCanceled)
-                {
-                    if (targetFileName != null)
-                    {
-                        try
-                        {
-                            if (output != null) output.Close();
-                            // An exception has occurred. If the file exists, check
-                            // to see if it existed before we tried extracting.  If
-                            // it did not, attempt to remove the target file. There
-                            // is a small possibility that the existing file has
-                            // been extracted successfully, overwriting a previously
-                            // existing file, and an exception was thrown after that
-                            // but before final completion (setting times, etc). In
-                            // that case the file will remain, even though some
-                            // error occurred.  Nothing to be done about it.
-                            if (File.Exists(targetFileName) && !fileExistsBeforeExtraction)
-                                File.Delete(targetFileName);
-
-                        }
-                        finally { }
-                    }
-                }
-            }
-        }
-
-
-#if NOT
-        internal void CalcWinZipAesMac(Stream input)
-        {
-            if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                if (input is WinZipAesCipherStream)
-                    wzs = input as WinZipAesCipherStream;
-
-                else if (input is Ionic.Zlib.CrcCalculatorStream)
-                {
-                    xxx;
-                }
-
-            }
-        }
-#endif
-
-
-        internal void VerifyCrcAfterExtract(Int32 actualCrc32)
-        {
-
-#if AESCRYPTO
-                // After extracting, Validate the CRC32
-                if (actualCrc32 != _Crc32)
-                {
-                    // CRC is not meaningful with WinZipAES and AES method 2 (AE-2)
-                    if ((Encryption != EncryptionAlgorithm.WinZipAes128 &&
-                         Encryption != EncryptionAlgorithm.WinZipAes256)
-                        || _WinZipAesMethod != 0x02)
-                        throw new BadCrcException("CRC error: the file being extracted appears to be corrupted. " +
-                                                  String.Format("Expected 0x{0:X8}, Actual 0x{1:X8}", _Crc32, actualCrc32));
-                }
-
-                // ignore MAC if the size of the file is zero
-                if (this.UncompressedSize == 0)
-                    return;
-
-                // calculate the MAC
-                if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                    Encryption == EncryptionAlgorithm.WinZipAes256)
-                {
-                    WinZipAesCipherStream wzs = _inputDecryptorStream as WinZipAesCipherStream;
-                    _aesCrypto_forExtract.CalculatedMac = wzs.FinalAuthentication;
-
-                    _aesCrypto_forExtract.ReadAndVerifyMac(this.ArchiveStream); // throws if MAC is bad
-                    // side effect: advances file position.
-                }
-
-
-
-
-#else
-            if (actualCrc32 != _Crc32)
-                throw new BadCrcException("CRC error: the file being extracted appears to be corrupted. " +
-                                          String.Format("Expected 0x{0:X8}, Actual 0x{1:X8}", _Crc32, actualCrc32));
-#endif
-        }
-
-
-
-
-        private int CheckExtractExistingFile(string baseDir, string targetFileName)
-        {
-            int loop = 0;
-            // returns: 0 == extract, 1 = don't, 2 = cancel
-            do
-            {
-                switch (ExtractExistingFile)
-                {
-                    case ExtractExistingFileAction.OverwriteSilently:
-                        WriteStatus("the file {0} exists; will overwrite it...", targetFileName);
-                        return 0;
-
-                    case ExtractExistingFileAction.DoNotOverwrite:
-                        WriteStatus("the file {0} exists; not extracting entry...", FileName);
-                        OnAfterExtract(baseDir);
-                        return 1;
-
-                    case ExtractExistingFileAction.InvokeExtractProgressEvent:
-                        if (loop>0)
-                            throw new ZipException(String.Format("The file {0} already exists.", targetFileName));
-                        OnExtractExisting(baseDir);
-                        if (_ioOperationCanceled)
-                            return 2;
-
-                        // loop around
-                        break;
-
-                    case ExtractExistingFileAction.Throw:
-                    default:
-                        throw new ZipException(String.Format("The file {0} already exists.", targetFileName));
-                }
-                loop++;
-            }
-            while (true);
-        }
-
-
-
-
-        private void _CheckRead(int nbytes)
-        {
-            if (nbytes == 0)
-                throw new BadReadException(String.Format("bad read of entry {0} from compressed archive.",
-                             this.FileName));
-        }
-
-
-        private Stream _inputDecryptorStream;
-
-        private Int32 ExtractOne(Stream output)
-        {
-            Int32 CrcResult = 0;
-            Stream input = this.ArchiveStream;
-
-            try
-            {
-                // change for workitem 8098
-                input.Seek(this.FileDataPosition, SeekOrigin.Begin);
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(input);
-
-                byte[] bytes = new byte[BufferSize];
-
-                // The extraction process varies depending on how the entry was
-                // stored.  It could have been encrypted, and it coould have
-                // been compressed, or both, or neither. So we need to check
-                // both the encryption flag and the compression flag, and take
-                // the proper action in all cases.
-
-                Int64 LeftToRead = (_CompressionMethod_FromZipFile != (short)CompressionMethod.None)
-                    ? this.UncompressedSize
-                    : this._CompressedFileDataSize;
-
-                // Get a stream that either decrypts or not.
-                _inputDecryptorStream = GetExtractDecryptor(input);
-
-                Stream input3 = GetExtractDecompressor( _inputDecryptorStream );
-
-                Int64 bytesWritten = 0;
-                // As we read, we maybe decrypt, and then we maybe decompress. Then we write.
-                using (var s1 = new Ionic.Crc.CrcCalculatorStream(input3))
-                {
-                    while (LeftToRead > 0)
-                    {
-                        //Console.WriteLine("ExtractOne: LeftToRead {0}", LeftToRead);
-
-                        // Casting LeftToRead down to an int is ok here in the else clause,
-                        // because that only happens when it is less than bytes.Length,
-                        // which is much less than MAX_INT.
-                        int len = (LeftToRead > bytes.Length) ? bytes.Length : (int)LeftToRead;
-                        int n = s1.Read(bytes, 0, len);
-
-                        // must check data read - essential for detecting corrupt zip files
-                        _CheckRead(n);
-
-                        output.Write(bytes, 0, n);
-                        LeftToRead -= n;
-                        bytesWritten += n;
-
-                        // fire the progress event, check for cancels
-                        OnExtractProgress(bytesWritten, UncompressedSize);
-                        if (_ioOperationCanceled)
-                        {
-                            break;
-                        }
-                    }
-
-                    CrcResult = s1.Crc;
-                }
-            }
-            finally
-            {
-                var zss = input as ZipSegmentedStream;
-                if (zss != null)
-                {
-#if NETCF
-                    zss.Close();
-#else
-                    // need to dispose it
-                    zss.Dispose();
-#endif
-                    _archiveStream = null;
-                }
-            }
-
-            return CrcResult;
-        }
-
-
-
-        internal Stream GetExtractDecompressor(Stream input2)
-        {
-            // get a stream that either decompresses or not.
-            switch (_CompressionMethod_FromZipFile)
-            {
-                case (short)CompressionMethod.None:
-                    return input2;
-                case (short)CompressionMethod.Deflate:
-                    return new Ionic.Zlib.DeflateStream(input2, Ionic.Zlib.CompressionMode.Decompress, true);
-#if BZIP
-                case (short)CompressionMethod.BZip2:
-                    return new Ionic.BZip2.BZip2InputStream(input2, true);
-#endif
-            }
-
-            return null;
-        }
-
-
-
-        internal Stream GetExtractDecryptor(Stream input)
-        {
-            Stream input2 = null;
-            if (_Encryption_FromZipFile == EncryptionAlgorithm.PkzipWeak)
-                input2 = new ZipCipherStream(input, _zipCrypto_forExtract, CryptoMode.Decrypt);
-
-#if AESCRYPTO
-            else if (_Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes128 ||
-                 _Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes256)
-                input2 = new WinZipAesCipherStream(input, _aesCrypto_forExtract, _CompressedFileDataSize, CryptoMode.Decrypt);
-#endif
-
-            else
-                input2 = input;
-
-            return input2;
-        }
-
-
-
-
-        internal void _SetTimes(string fileOrDirectory, bool isFile)
-        {
-#if SILVERLIGHT
-                    // punt on setting file times
-#else
-            // workitem 8807:
-            // Because setting the time is not considered to be a fatal error,
-            // and because other applications can interfere with the setting
-            // of a time on a directory, we're going to swallow IO exceptions
-            // in this method.
-
-            try
-            {
-                if (_ntfsTimesAreSet)
-                {
-#if NETCF
-                    // workitem 7944: set time should not be a fatal error on CF
-                    int rc = NetCfFile.SetTimes(fileOrDirectory, _Ctime, _Atime, _Mtime);
-                    if ( rc != 0)
-                    {
-                        WriteStatus("Warning: SetTimes failed.  entry({0})  file({1})  rc({2})",
-                                    FileName, fileOrDirectory, rc);
-                    }
-#else
-                    if (isFile)
-                    {
-                        // It's possible that the extract was cancelled, in which case,
-                        // the file does not exist.
-                        if (File.Exists(fileOrDirectory))
-                        {
-                            File.SetCreationTimeUtc(fileOrDirectory, _Ctime);
-                            File.SetLastAccessTimeUtc(fileOrDirectory, _Atime);
-                            File.SetLastWriteTimeUtc(fileOrDirectory, _Mtime);
-                        }
-                    }
-                    else
-                    {
-                        // It's possible that the extract was cancelled, in which case,
-                        // the directory does not exist.
-                        if (Directory.Exists(fileOrDirectory))
-                        {
-                            Directory.SetCreationTimeUtc(fileOrDirectory, _Ctime);
-                            Directory.SetLastAccessTimeUtc(fileOrDirectory, _Atime);
-                            Directory.SetLastWriteTimeUtc(fileOrDirectory, _Mtime);
-                        }
-                    }
-#endif
-                }
-                else
-                {
-                    // workitem 6191
-                    DateTime AdjustedLastModified = Ionic.Zip.SharedUtilities.AdjustTime_Reverse(LastModified);
-
-#if NETCF
-                    int rc = NetCfFile.SetLastWriteTime(fileOrDirectory, AdjustedLastModified);
-
-                    if ( rc != 0)
-                    {
-                        WriteStatus("Warning: SetLastWriteTime failed.  entry({0})  file({1})  rc({2})",
-                                    FileName, fileOrDirectory, rc);
-                    }
-#else
-                    if (isFile)
-                        File.SetLastWriteTime(fileOrDirectory, AdjustedLastModified);
-                    else
-                        Directory.SetLastWriteTime(fileOrDirectory, AdjustedLastModified);
-#endif
-                }
-            }
-            catch (System.IO.IOException ioexc1)
-            {
-                WriteStatus("failed to set time on {0}: {1}", fileOrDirectory, ioexc1.Message);
-            }
-#endif
-        }
-
-
-        #region Support methods
-
-
-        // workitem 7968
-        private string UnsupportedAlgorithm
-        {
-            get
-            {
-                string alg = String.Empty;
-                switch (_UnsupportedAlgorithmId)
-                {
-                    case 0:
-                        alg = "--";
-                        break;
-                    case 0x6601:
-                        alg = "DES";
-                        break;
-                    case 0x6602: // - RC2 (version needed to extract < 5.2)
-                        alg = "RC2";
-                        break;
-                    case 0x6603: // - 3DES 168
-                        alg = "3DES-168";
-                        break;
-                    case 0x6609: // - 3DES 112
-                        alg = "3DES-112";
-                        break;
-                    case 0x660E: // - AES 128
-                        alg = "PKWare AES128";
-                        break;
-                    case 0x660F: // - AES 192
-                        alg = "PKWare AES192";
-                        break;
-                    case 0x6610: // - AES 256
-                        alg = "PKWare AES256";
-                        break;
-                    case 0x6702: // - RC2 (version needed to extract >= 5.2)
-                        alg = "RC2";
-                        break;
-                    case 0x6720: // - Blowfish
-                        alg = "Blowfish";
-                        break;
-                    case 0x6721: // - Twofish
-                        alg = "Twofish";
-                        break;
-                    case 0x6801: // - RC4
-                        alg = "RC4";
-                        break;
-                    case 0xFFFF: // - Unknown algorithm
-                    default:
-                        alg = String.Format("Unknown (0x{0:X4})", _UnsupportedAlgorithmId);
-                        break;
-                }
-                return alg;
-            }
-        }
-
-        // workitem 7968
-        private string UnsupportedCompressionMethod
-        {
-            get
-            {
-                string meth = String.Empty;
-                switch ((int)_CompressionMethod)
-                {
-                    case 0:
-                        meth = "Store";
-                        break;
-                    case 1:
-                        meth = "Shrink";
-                        break;
-                    case 8:
-                        meth = "DEFLATE";
-                        break;
-                    case 9:
-                        meth = "Deflate64";
-                        break;
-                    case 12:
-                        meth = "BZIP2"; // only if BZIP not compiled in
-                        break;
-                    case 14:
-                        meth = "LZMA";
-                        break;
-                    case 19:
-                        meth = "LZ77";
-                        break;
-                    case 98:
-                        meth = "PPMd";
-                        break;
-                    default:
-                        meth = String.Format("Unknown (0x{0:X4})", _CompressionMethod);
-                        break;
-                }
-                return meth;
-            }
-        }
-
-
-        internal void ValidateEncryption()
-        {
-            if (Encryption != EncryptionAlgorithm.PkzipWeak &&
-#if AESCRYPTO
- Encryption != EncryptionAlgorithm.WinZipAes128 &&
-                Encryption != EncryptionAlgorithm.WinZipAes256 &&
-#endif
- Encryption != EncryptionAlgorithm.None)
-            {
-                // workitem 7968
-                if (_UnsupportedAlgorithmId != 0)
-                    throw new ZipException(String.Format("Cannot extract: Entry {0} is encrypted with an algorithm not supported by DotNetZip: {1}",
-                                                         FileName, UnsupportedAlgorithm));
-                else
-                    throw new ZipException(String.Format("Cannot extract: Entry {0} uses an unsupported encryption algorithm ({1:X2})",
-                                                         FileName, (int)Encryption));
-            }
-        }
-
-
-        private void ValidateCompression()
-        {
-            if ((_CompressionMethod_FromZipFile != (short)CompressionMethod.None) &&
-                (_CompressionMethod_FromZipFile != (short)CompressionMethod.Deflate)
-#if BZIP
-                && (_CompressionMethod_FromZipFile != (short)CompressionMethod.BZip2)
-#endif
-                )
-                throw new ZipException(String.Format("Entry {0} uses an unsupported compression method (0x{1:X2}, {2})",
-                                                          FileName, _CompressionMethod_FromZipFile, UnsupportedCompressionMethod));
-        }
-
-
-        private void SetupCryptoForExtract(string password)
-        {
-            //if (password == null) return;
-            if (_Encryption_FromZipFile == EncryptionAlgorithm.None) return;
-
-            if (_Encryption_FromZipFile == EncryptionAlgorithm.PkzipWeak)
-            {
-                if (password == null)
-                    throw new ZipException("Missing password.");
-
-                this.ArchiveStream.Seek(this.FileDataPosition - 12, SeekOrigin.Begin);
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-                _zipCrypto_forExtract = ZipCrypto.ForRead(password, this);
-            }
-
-#if AESCRYPTO
-            else if (_Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes128 ||
-                 _Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes256)
-            {
-                if (password == null)
-                    throw new ZipException("Missing password.");
-
-                // If we already have a WinZipAesCrypto object in place, use it.
-                // It can be set up in the ReadDirEntry(), or during a previous Extract.
-                if (_aesCrypto_forExtract != null)
-                {
-                    _aesCrypto_forExtract.Password = password;
-                }
-                else
-                {
-                    int sizeOfSaltAndPv = GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
-                    this.ArchiveStream.Seek(this.FileDataPosition - sizeOfSaltAndPv, SeekOrigin.Begin);
-                    // workitem 10178
-                    Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-                    int keystrength = GetKeyStrengthInBits(_Encryption_FromZipFile);
-                    _aesCrypto_forExtract = WinZipAesCrypto.ReadFromStream(password, keystrength, this.ArchiveStream);
-                }
-            }
-#endif
-        }
-
-
-
-        /// <summary>
-        /// Validates that the args are consistent.
-        /// </summary>
-        /// <remarks>
-        /// Only one of {baseDir, outStream} can be non-null.
-        /// If baseDir is non-null, then the outputFile is created.
-        /// </remarks>
-        private bool ValidateOutput(string basedir, Stream outstream, out string outFileName)
-        {
-            if (basedir != null)
-            {
-                // Sometimes the name on the entry starts with a slash.
-                // Rather than unpack to the root of the volume, we're going to
-                // drop the slash and unpack to the specified base directory.
-                string f = this.FileName.Replace("\\","/");
-
-                // workitem 11772: remove drive letter with separator
-                if (f.IndexOf(':') == 1)
-                    f= f.Substring(2);
-
-                if (f.StartsWith("/"))
-                    f= f.Substring(1);
-
-                // String.Contains is not available on .NET CF 2.0
-
-                if (_container.ZipFile.FlattenFoldersOnExtract)
-                    outFileName = Path.Combine(basedir,
-                                              (f.IndexOf('/') != -1) ? Path.GetFileName(f) : f);
-                else
-                    outFileName = Path.Combine(basedir, f);
-
-                // workitem 10639
-                outFileName = outFileName.Replace("/","\\");
-
-                // check if it is a directory
-                if ((IsDirectory) || (FileName.EndsWith("/")))
-                {
-                    if (!Directory.Exists(outFileName))
-                    {
-                        Directory.CreateDirectory(outFileName);
-                        _SetTimes(outFileName, false);
-                    }
-                    else
-                    {
-                        // the dir exists, maybe we want to overwrite times.
-                        if (ExtractExistingFile == ExtractExistingFileAction.OverwriteSilently)
-                            _SetTimes(outFileName, false);
-                    }
-                    return true;  // true == all done, caller will return
-                }
-                return false;  // false == work to do by caller.
-            }
-
-            if (outstream != null)
-            {
-                outFileName = null;
-                if ((IsDirectory) || (FileName.EndsWith("/")))
-                {
-                    // extract a directory to streamwriter?  nothing to do!
-                    return true;  // true == all done!  caller can return
-                }
-                return false;
-            }
-
-            throw new ArgumentNullException("outstream");
-        }
-
-
-        #endregion
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipEntry.Read.cs b/EPPlus/Packaging/DotNetZip/ZipEntry.Read.cs
deleted file mode 100644
index 46a69eb..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipEntry.Read.cs
+++ /dev/null
@@ -1,798 +0,0 @@
-// ZipEntry.Read.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-09 21:31:28>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for Reading the ZipEntry from a
-// zip file.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal partial class ZipEntry
-    {
-        private int _readExtraDepth;
-        private void ReadExtraField()
-        {
-            _readExtraDepth++;
-            // workitem 8098: ok (restore)
-            long posn = this.ArchiveStream.Position;
-            this.ArchiveStream.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
-            byte[] block = new byte[30];
-            this.ArchiveStream.Read(block, 0, block.Length);
-            int i = 26;
-            Int16 filenameLength = (short)(block[i++] + block[i++] * 256);
-            Int16 extraFieldLength = (short)(block[i++] + block[i++] * 256);
-
-            // workitem 8098: ok (relative)
-            this.ArchiveStream.Seek(filenameLength, SeekOrigin.Current);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
-            ProcessExtraField(this.ArchiveStream, extraFieldLength);
-
-            // workitem 8098: ok (restore)
-            this.ArchiveStream.Seek(posn, SeekOrigin.Begin);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-            _readExtraDepth--;
-        }
-
-
-        private static bool ReadHeader(ZipEntry ze, System.Text.Encoding defaultEncoding)
-        {
-            int bytesRead = 0;
-
-            // change for workitem 8098
-            ze._RelativeOffsetOfLocalHeader = ze.ArchiveStream.Position;
-
-            int signature = Ionic.Zip.SharedUtilities.ReadEntrySignature(ze.ArchiveStream);
-            bytesRead += 4;
-
-            // Return false if this is not a local file header signature.
-            if (ZipEntry.IsNotValidSig(signature))
-            {
-                // Getting "not a ZipEntry signature" is not always wrong or an error.
-                // This will happen after the last entry in a zipfile.  In that case, we
-                // expect to read :
-                //    a ZipDirEntry signature (if a non-empty zip file) or
-                //    a ZipConstants.EndOfCentralDirectorySignature.
-                //
-                // Anything else is a surprise.
-
-                ze.ArchiveStream.Seek(-4, SeekOrigin.Current); // unread the signature
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(ze.ArchiveStream);
-                if (ZipEntry.IsNotValidZipDirEntrySig(signature) && (signature != ZipConstants.EndOfCentralDirectorySignature))
-                {
-                    throw new BadReadException(String.Format("  Bad signature (0x{0:X8}) at position  0x{1:X8}", signature, ze.ArchiveStream.Position));
-                }
-                return false;
-            }
-
-            byte[] block = new byte[26];
-            int n = ze.ArchiveStream.Read(block, 0, block.Length);
-            if (n != block.Length) return false;
-            bytesRead += n;
-
-            int i = 0;
-            ze._VersionNeeded = (Int16)(block[i++] + block[i++] * 256);
-            ze._BitField = (Int16)(block[i++] + block[i++] * 256);
-            ze._CompressionMethod_FromZipFile = ze._CompressionMethod = (Int16)(block[i++] + block[i++] * 256);
-            ze._TimeBlob = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
-            // transform the time data into something usable (a DateTime)
-            ze._LastModified = Ionic.Zip.SharedUtilities.PackedToDateTime(ze._TimeBlob);
-            ze._timestamp |= ZipEntryTimestamp.DOS;
-
-            if ((ze._BitField & 0x01) == 0x01)
-            {
-                ze._Encryption_FromZipFile = ze._Encryption = EncryptionAlgorithm.PkzipWeak; // this *may* change after processing the Extra field
-                ze._sourceIsEncrypted = true;
-            }
-
-            // NB: if ((ze._BitField & 0x0008) != 0x0008), then the Compressed, uncompressed and
-            // CRC values are not true values; the true values will follow the entry data.
-            // But, regardless of the status of bit 3 in the bitfield, the slots for
-            // the three amigos may contain marker values for ZIP64.  So we must read them.
-            {
-                ze._Crc32 = (Int32)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-                ze._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-                ze._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-
-                if ((uint)ze._CompressedSize == 0xFFFFFFFF ||
-                    (uint)ze._UncompressedSize == 0xFFFFFFFF)
-
-                    ze._InputUsesZip64 = true;
-            }
-
-            Int16 filenameLength = (short)(block[i++] + block[i++] * 256);
-            Int16 extraFieldLength = (short)(block[i++] + block[i++] * 256);
-
-            block = new byte[filenameLength];
-            n = ze.ArchiveStream.Read(block, 0, block.Length);
-            bytesRead += n;
-
-            // if the UTF8 bit is set for this entry, override the
-            // encoding the application requested.
-
-            if ((ze._BitField & 0x0800) == 0x0800)
-            {
-                // workitem 12744
-                ze.AlternateEncoding = System.Text.Encoding.UTF8;
-                ze.AlternateEncodingUsage = ZipOption.Always;
-            }
-
-            // need to use this form of GetString() for .NET CF
-            ze._FileNameInArchive = ze.AlternateEncoding.GetString(block, 0, block.Length);
-
-            // workitem 6898
-            if (ze._FileNameInArchive.EndsWith("/")) ze.MarkAsDirectory();
-
-            bytesRead += ze.ProcessExtraField(ze.ArchiveStream, extraFieldLength);
-
-            ze._LengthOfTrailer = 0;
-
-            // workitem 6607 - don't read for directories
-            // actually get the compressed size and CRC if necessary
-            if (!ze._FileNameInArchive.EndsWith("/") && (ze._BitField & 0x0008) == 0x0008)
-            {
-                // This descriptor exists only if bit 3 of the general
-                // purpose bit flag is set (see below).  It is byte aligned
-                // and immediately follows the last byte of compressed data,
-                // as well as any encryption trailer, as with AES.
-                // This descriptor is used only when it was not possible to
-                // seek in the output .ZIP file, e.g., when the output .ZIP file
-                // was standard output or a non-seekable device.  For ZIP64(tm) format
-                // archives, the compressed and uncompressed sizes are 8 bytes each.
-
-                // workitem 8098: ok (restore)
-                long posn = ze.ArchiveStream.Position;
-
-                // Here, we're going to loop until we find a ZipEntryDataDescriptorSignature and
-                // a consistent data record after that.   To be consistent, the data record must
-                // indicate the length of the entry data.
-                bool wantMore = true;
-                long SizeOfDataRead = 0;
-                int tries = 0;
-                while (wantMore)
-                {
-                    tries++;
-                    // We call the FindSignature shared routine to find the specified signature
-                    // in the already-opened zip archive, starting from the current cursor
-                    // position in that filestream.  If we cannot find the signature, then the
-                    // routine returns -1, and the ReadHeader() method returns false,
-                    // indicating we cannot read a legal entry header.  If we have found it,
-                    // then the FindSignature() method returns the number of bytes in the
-                    // stream we had to seek forward, to find the sig.  We need this to
-                    // determine if the zip entry is valid, later.
-
-                    if (ze._container.ZipFile != null)
-                        ze._container.ZipFile.OnReadBytes(ze);
-
-                    long d = Ionic.Zip.SharedUtilities.FindSignature(ze.ArchiveStream, ZipConstants.ZipEntryDataDescriptorSignature);
-                    if (d == -1) return false;
-
-                    // total size of data read (through all loops of this).
-                    SizeOfDataRead += d;
-
-                    if (ze._InputUsesZip64)
-                    {
-                        // read 1x 4-byte (CRC) and 2x 8-bytes (Compressed Size, Uncompressed Size)
-                        block = new byte[20];
-                        n = ze.ArchiveStream.Read(block, 0, block.Length);
-                        if (n != 20) return false;
-
-                        // do not increment bytesRead - it is for entry header only.
-                        // the data we have just read is a footer (falls after the file data)
-                        //bytesRead += n;
-
-                        i = 0;
-                        ze._Crc32 = (Int32)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-                        ze._CompressedSize = BitConverter.ToInt64(block, i);
-                        i += 8;
-                        ze._UncompressedSize = BitConverter.ToInt64(block, i);
-                        i += 8;
-
-                        ze._LengthOfTrailer = 24;  // bytes including sig, CRC, Comp and Uncomp sizes
-                    }
-                    else
-                    {
-                        // read 3x 4-byte fields (CRC, Compressed Size, Uncompressed Size)
-                        block = new byte[12];
-                        n = ze.ArchiveStream.Read(block, 0, block.Length);
-                        if (n != 12) return false;
-
-                        // do not increment bytesRead - it is for entry header only.
-                        // the data we have just read is a footer (falls after the file data)
-                        //bytesRead += n;
-
-                        i = 0;
-                        ze._Crc32 = (Int32)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-                        ze._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-                        ze._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-
-                        ze._LengthOfTrailer = 16;  // bytes including sig, CRC, Comp and Uncomp sizes
-
-                    }
-
-                    wantMore = (SizeOfDataRead != ze._CompressedSize);
-
-                    if (wantMore)
-                    {
-                        // Seek back to un-read the last 12 bytes  - maybe THEY contain
-                        // the ZipEntryDataDescriptorSignature.
-                        // (12 bytes for the CRC, Comp and Uncomp size.)
-                        ze.ArchiveStream.Seek(-12, SeekOrigin.Current);
-                        // workitem 10178
-                        Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(ze.ArchiveStream);
-
-                        // Adjust the size to account for the false signature read in
-                        // FindSignature().
-                        SizeOfDataRead += 4;
-                    }
-                }
-
-                // seek back to previous position, to prepare to read file data
-                // workitem 8098: ok (restore)
-                ze.ArchiveStream.Seek(posn, SeekOrigin.Begin);
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(ze.ArchiveStream);
-            }
-
-            ze._CompressedFileDataSize = ze._CompressedSize;
-
-
-            // bit 0 set indicates that some kind of encryption is in use
-            if ((ze._BitField & 0x01) == 0x01)
-            {
-#if AESCRYPTO
-                if (ze.Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                    ze.Encryption == EncryptionAlgorithm.WinZipAes256)
-                {
-                    int bits = ZipEntry.GetKeyStrengthInBits(ze._Encryption_FromZipFile);
-                    // read in the WinZip AES metadata: salt + PV. 18 bytes for AES256. 10 bytes for AES128.
-                    ze._aesCrypto_forExtract = WinZipAesCrypto.ReadFromStream(null, bits, ze.ArchiveStream);
-                    bytesRead += ze._aesCrypto_forExtract.SizeOfEncryptionMetadata - 10; // MAC (follows crypto bytes)
-                    // according to WinZip, the CompressedSize includes the AES Crypto framing data.
-                    ze._CompressedFileDataSize -= ze._aesCrypto_forExtract.SizeOfEncryptionMetadata;
-                    ze._LengthOfTrailer += 10;  // MAC
-                }
-                else
-#endif
-                {
-                    // read in the header data for "weak" encryption
-                    ze._WeakEncryptionHeader = new byte[12];
-                    bytesRead += ZipEntry.ReadWeakEncryptionHeader(ze._archiveStream, ze._WeakEncryptionHeader);
-                    // decrease the filedata size by 12 bytes
-                    ze._CompressedFileDataSize -= 12;
-                }
-            }
-
-            // Remember the size of the blob for this entry.
-            // We also have the starting position in the stream for this entry.
-            ze._LengthOfHeader = bytesRead;
-            ze._TotalEntrySize = ze._LengthOfHeader + ze._CompressedFileDataSize + ze._LengthOfTrailer;
-
-
-            // We've read in the regular entry header, the extra field, and any
-            // encryption header.  The pointer in the file is now at the start of the
-            // filedata, which is potentially compressed and encrypted.  Just ahead in
-            // the file, there are _CompressedFileDataSize bytes of data, followed by
-            // potentially a non-zero length trailer, consisting of optionally, some
-            // encryption stuff (10 byte MAC for AES), and the bit-3 trailer (16 or 24
-            // bytes).
-
-            return true;
-        }
-
-
-
-        internal static int ReadWeakEncryptionHeader(Stream s, byte[] buffer)
-        {
-            // PKZIP encrypts the compressed data stream.  Encrypted files must
-            // be decrypted before they can be extracted.
-
-            // Each PKZIP-encrypted file has an extra 12 bytes stored at the start of the data
-            // area defining the encryption header for that file.  The encryption header is
-            // originally set to random values, and then itself encrypted, using three, 32-bit
-            // keys.  The key values are initialized using the supplied encryption password.
-            // After each byte is encrypted, the keys are then updated using pseudo-random
-            // number generation techniques in combination with the same CRC-32 algorithm used
-            // in PKZIP and implemented in the CRC32.cs module in this project.
-
-            // read the 12-byte encryption header
-            int additionalBytesRead = s.Read(buffer, 0, 12);
-            if (additionalBytesRead != 12)
-                throw new ZipException(String.Format("Unexpected end of data at position 0x{0:X8}", s.Position));
-
-            return additionalBytesRead;
-        }
-
-
-
-        private static bool IsNotValidSig(int signature)
-        {
-            return (signature != ZipConstants.ZipEntrySignature);
-        }
-
-
-        /// <summary>
-        ///   Reads one <c>ZipEntry</c> from the given stream.  The content for
-        ///   the entry does not get decompressed or decrypted.  This method
-        ///   basically reads metadata, and seeks.
-        /// </summary>
-        /// <param name="zc">the ZipContainer this entry belongs to.</param>
-        /// <param name="first">
-        ///   true of this is the first entry being read from the stream.
-        /// </param>
-        /// <returns>the <c>ZipEntry</c> read from the stream.</returns>
-        internal static ZipEntry ReadEntry(ZipContainer zc, bool first)
-        {
-            ZipFile zf = zc.ZipFile;
-            Stream s = zc.ReadStream;
-            System.Text.Encoding defaultEncoding = zc.AlternateEncoding;
-            ZipEntry entry = new ZipEntry();
-            entry._Source = ZipEntrySource.ZipFile;
-            entry._container = zc;
-            entry._archiveStream = s;
-            if (zf != null)
-                zf.OnReadEntry(true, null);
-
-            if (first) HandlePK00Prefix(s);
-
-            // Read entry header, including any encryption header
-            if (!ReadHeader(entry, defaultEncoding)) return null;
-
-            // Store the position in the stream for this entry
-            // change for workitem 8098
-            entry.__FileDataPosition = entry.ArchiveStream.Position;
-
-            // seek past the data without reading it. We will read on Extract()
-            s.Seek(entry._CompressedFileDataSize + entry._LengthOfTrailer, SeekOrigin.Current);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-
-            // ReadHeader moves the file pointer to the end of the entry header,
-            // as well as any encryption header.
-
-            // CompressedFileDataSize includes:
-            //   the maybe compressed, maybe encrypted file data
-            //   the encryption trailer, if any
-            //   the bit 3 descriptor, if any
-
-            // workitem 5306
-            // http://www.codeplex.com/DotNetZip/WorkItem/View.aspx?WorkItemId=5306
-            HandleUnexpectedDataDescriptor(entry);
-
-            if (zf != null)
-            {
-                zf.OnReadBytes(entry);
-                zf.OnReadEntry(false, entry);
-            }
-
-            return entry;
-        }
-
-
-        internal static void HandlePK00Prefix(Stream s)
-        {
-            // in some cases, the zip file begins with "PK00".  This is a throwback and is rare,
-            // but we handle it anyway. We do not change behavior based on it.
-            uint datum = (uint)Ionic.Zip.SharedUtilities.ReadInt(s);
-            if (datum != ZipConstants.PackedToRemovableMedia)
-            {
-                s.Seek(-4, SeekOrigin.Current); // unread the block
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-            }
-        }
-
-
-
-        private static void HandleUnexpectedDataDescriptor(ZipEntry entry)
-        {
-            Stream s = entry.ArchiveStream;
-
-            // In some cases, the "data descriptor" is present, without a signature, even when
-            // bit 3 of the BitField is NOT SET.  This is the CRC, followed
-            //    by the compressed length and the uncompressed length (4 bytes for each
-            //    of those three elements).  Need to check that here.
-            //
-            uint datum = (uint)Ionic.Zip.SharedUtilities.ReadInt(s);
-            if (datum == entry._Crc32)
-            {
-                int sz = Ionic.Zip.SharedUtilities.ReadInt(s);
-                if (sz == entry._CompressedSize)
-                {
-                    sz = Ionic.Zip.SharedUtilities.ReadInt(s);
-                    if (sz == entry._UncompressedSize)
-                    {
-                        // ignore everything and discard it.
-                    }
-                    else
-                    {
-                        s.Seek(-12, SeekOrigin.Current); // unread the three blocks
-
-                        // workitem 10178
-                        Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-                    }
-                }
-                else
-                {
-                    s.Seek(-8, SeekOrigin.Current); // unread the two blocks
-
-                    // workitem 10178
-                    Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-                }
-            }
-            else
-            {
-                s.Seek(-4, SeekOrigin.Current); // unread the block
-
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-            }
-        }
-
-
-        /// <summary>
-        ///   Finds a particular segment in the given extra field.
-        ///   This is used when modifying a previously-generated
-        ///   extra field, in particular when removing the AES crypto
-        ///   segment in the extra field.
-        /// </summary>
-        static internal int FindExtraFieldSegment(byte[] extra, int offx, UInt16 targetHeaderId)
-        {
-            int j = offx;
-            while (j + 3 < extra.Length)
-            {
-                UInt16 headerId = (UInt16)(extra[j++] + extra[j++] * 256);
-                if (headerId == targetHeaderId) return j-2;
-
-                // else advance to next segment
-                Int16 dataSize = (short)(extra[j++] + extra[j++] * 256);
-                j+= dataSize;
-            }
-
-            return -1;
-        }
-
-
-        /// <summary>
-        ///   At current cursor position in the stream, read the extra
-        ///   field, and set the properties on the ZipEntry instance
-        ///   appropriately.  This can be called when processing the
-        ///   Extra field in the Central Directory, or in the local
-        ///   header.
-        /// </summary>
-        internal int ProcessExtraField(Stream s, Int16 extraFieldLength)
-        {
-            int additionalBytesRead = 0;
-            if (extraFieldLength > 0)
-            {
-                byte[] buffer = this._Extra = new byte[extraFieldLength];
-                additionalBytesRead = s.Read(buffer, 0, buffer.Length);
-                long posn = s.Position - additionalBytesRead;
-                int j = 0;
-                while (j + 3 < buffer.Length)
-                {
-                    int start = j;
-                    UInt16 headerId = (UInt16)(buffer[j++] + buffer[j++] * 256);
-                    Int16 dataSize = (short)(buffer[j++] + buffer[j++] * 256);
-
-                    switch (headerId)
-                    {
-                        case 0x000a:  // NTFS ctime, atime, mtime
-                            j = ProcessExtraFieldWindowsTimes(buffer, j, dataSize, posn);
-                            break;
-
-                        case 0x5455:  // Unix ctime, atime, mtime
-                            j = ProcessExtraFieldUnixTimes(buffer, j, dataSize, posn);
-                            break;
-
-                        case 0x5855:  // Info-zip Extra field (outdated)
-                            // This is outdated, so the field is supported on
-                            // read only.
-                            j = ProcessExtraFieldInfoZipTimes(buffer, j, dataSize, posn);
-                            break;
-
-                        case 0x7855:  // Unix uid/gid
-                            // ignored. DotNetZip does not handle this field.
-                            break;
-
-                        case 0x7875:  // ??
-                            // ignored.  I could not find documentation on this field,
-                            // though it appears in some zip files.
-                            break;
-
-                        case 0x0001: // ZIP64
-                            j = ProcessExtraFieldZip64(buffer, j, dataSize, posn);
-                            break;
-
-#if AESCRYPTO
-                        case 0x9901: // WinZip AES encryption is in use.  (workitem 6834)
-                            // we will handle this extra field only  if compressionmethod is 0x63
-                            j = ProcessExtraFieldWinZipAes(buffer, j, dataSize, posn);
-                            break;
-#endif
-                        case 0x0017: // workitem 7968: handle PKWare Strong encryption header
-                            j = ProcessExtraFieldPkwareStrongEncryption(buffer, j);
-                            break;
-                    }
-
-                    // move to the next Header in the extra field
-                    j = start + dataSize + 4;
-                }
-            }
-            return additionalBytesRead;
-        }
-
-        private int ProcessExtraFieldPkwareStrongEncryption(byte[] Buffer, int j)
-        {
-            //           Value     Size     Description
-            //           -----     ----     -----------
-            //           0x0017    2 bytes  Tag for this "extra" block type
-            //           TSize     2 bytes  Size of data that follows
-            //           Format    2 bytes  Format definition for this record
-            //           AlgID     2 bytes  Encryption algorithm identifier
-            //           Bitlen    2 bytes  Bit length of encryption key
-            //           Flags     2 bytes  Processing flags
-            //           CertData  TSize-8  Certificate decryption extra field data
-            //                              (refer to the explanation for CertData
-            //                               in the section describing the
-            //                               Certificate Processing Method under
-            //                               the Strong Encryption Specification)
-
-            j += 2;
-            _UnsupportedAlgorithmId = (UInt16)(Buffer[j++] + Buffer[j++] * 256);
-            _Encryption_FromZipFile = _Encryption = EncryptionAlgorithm.Unsupported;
-
-            // DotNetZip doesn't support this algorithm, but we don't need to throw
-            // here.  we might just be reading the archive, which is fine.  We'll
-            // need to throw if Extract() is called.
-
-            return j;
-        }
-
-
-#if AESCRYPTO
-        private int ProcessExtraFieldWinZipAes(byte[] buffer, int j, Int16 dataSize, long posn)
-        {
-            if (this._CompressionMethod == 0x0063)
-            {
-                if ((this._BitField & 0x01) != 0x01)
-                    throw new BadReadException(String.Format("  Inconsistent metadata at position 0x{0:X16}", posn));
-
-                this._sourceIsEncrypted = true;
-
-                //this._aesCrypto = new WinZipAesCrypto(this);
-                // see spec at http://www.winzip.com/aes_info.htm
-                if (dataSize != 7)
-                    throw new BadReadException(String.Format("  Inconsistent size (0x{0:X4}) in WinZip AES field at position 0x{1:X16}", dataSize, posn));
-
-                this._WinZipAesMethod = BitConverter.ToInt16(buffer, j);
-                j += 2;
-                if (this._WinZipAesMethod != 0x01 && this._WinZipAesMethod != 0x02)
-                    throw new BadReadException(String.Format("  Unexpected vendor version number (0x{0:X4}) for WinZip AES metadata at position 0x{1:X16}",
-                        this._WinZipAesMethod, posn));
-
-                Int16 vendorId = BitConverter.ToInt16(buffer, j);
-                j += 2;
-                if (vendorId != 0x4541)
-                    throw new BadReadException(String.Format("  Unexpected vendor ID (0x{0:X4}) for WinZip AES metadata at position 0x{1:X16}", vendorId, posn));
-
-                int keystrength = (buffer[j] == 1) ? 128 : (buffer[j] == 3) ? 256 : -1;
-                if (keystrength < 0)
-                    throw new BadReadException(String.Format("Invalid key strength ({0})", keystrength));
-
-                _Encryption_FromZipFile = this._Encryption = (keystrength == 128)
-                    ? EncryptionAlgorithm.WinZipAes128
-                    : EncryptionAlgorithm.WinZipAes256;
-
-                j++;
-
-                // set the actual compression method
-                this._CompressionMethod_FromZipFile =
-                this._CompressionMethod = BitConverter.ToInt16(buffer, j);
-                j += 2; // for the next segment of the extra field
-            }
-            return j;
-        }
-
-#endif
-
-        private delegate T Func<T>();
-
-        private int ProcessExtraFieldZip64(byte[] buffer, int j, Int16 dataSize, long posn)
-        {
-            // The PKWare spec says that any of {UncompressedSize, CompressedSize,
-            // RelativeOffset} exceeding 0xFFFFFFFF can lead to the ZIP64 header,
-            // and the ZIP64 header may contain one or more of those.  If the
-            // values are present, they will be found in the prescribed order.
-            // There may also be a 4-byte "disk start number."
-            // This means that the DataSize must be 28 bytes or less.
-
-            this._InputUsesZip64 = true;
-
-            // workitem 7941: check datasize before reading.
-            if (dataSize > 28)
-                throw new BadReadException(String.Format("  Inconsistent size (0x{0:X4}) for ZIP64 extra field at position 0x{1:X16}",
-                                                         dataSize, posn));
-            int remainingData = dataSize;
-
-            var slurp = new Func<Int64>( () => {
-                    if (remainingData < 8)
-                        throw new BadReadException(String.Format("  Missing data for ZIP64 extra field, position 0x{0:X16}", posn));
-                    var x = BitConverter.ToInt64(buffer, j);
-                    j+= 8;
-                    remainingData -= 8;
-                    return x;
-                });
-
-            if (this._UncompressedSize == 0xFFFFFFFF)
-                this._UncompressedSize = slurp();
-
-            if (this._CompressedSize == 0xFFFFFFFF)
-                this._CompressedSize = slurp();
-
-            if (this._RelativeOffsetOfLocalHeader == 0xFFFFFFFF)
-                this._RelativeOffsetOfLocalHeader = slurp();
-
-            // Ignore anything else. Potentially there are 4 more bytes for the
-            // disk start number.  DotNetZip currently doesn't handle multi-disk
-            // archives.
-            return j;
-        }
-
-
-        private int ProcessExtraFieldInfoZipTimes(byte[] buffer, int j, Int16 dataSize, long posn)
-        {
-            if (dataSize != 12 && dataSize != 8)
-                throw new BadReadException(String.Format("  Unexpected size (0x{0:X4}) for InfoZip v1 extra field at position 0x{1:X16}", dataSize, posn));
-
-            Int32 timet = BitConverter.ToInt32(buffer, j);
-            this._Mtime = _unixEpoch.AddSeconds(timet);
-            j += 4;
-
-            timet = BitConverter.ToInt32(buffer, j);
-            this._Atime = _unixEpoch.AddSeconds(timet);
-            j += 4;
-
-            this._Ctime = DateTime.UtcNow;
-
-            _ntfsTimesAreSet = true;
-            _timestamp |= ZipEntryTimestamp.InfoZip1; return j;
-        }
-
-
-
-        private int ProcessExtraFieldUnixTimes(byte[] buffer, int j, Int16 dataSize, long posn)
-        {
-            // The Unix filetimes are 32-bit unsigned integers,
-            // storing seconds since Unix epoch.
-
-            if (dataSize != 13 && dataSize != 9 && dataSize != 5)
-                throw new BadReadException(String.Format("  Unexpected size (0x{0:X4}) for Extended Timestamp extra field at position 0x{1:X16}", dataSize, posn));
-
-            int remainingData = dataSize;
-
-            var slurp = new Func<DateTime>( () => {
-                    Int32 timet = BitConverter.ToInt32(buffer, j);
-                    j += 4;
-                    remainingData -= 4;
-                    return _unixEpoch.AddSeconds(timet);
-                });
-
-            if (dataSize == 13 || _readExtraDepth > 0)
-            {
-                byte flag = buffer[j++];
-                remainingData--;
-
-                if ((flag & 0x0001) != 0 && remainingData >= 4)
-                    this._Mtime = slurp();
-
-                 this._Atime = ((flag & 0x0002) != 0 && remainingData >= 4)
-                     ? slurp()
-                     : DateTime.UtcNow;
-
-                 this._Ctime =  ((flag & 0x0004) != 0 && remainingData >= 4)
-                     ? slurp()
-                     :DateTime.UtcNow;
-
-                _timestamp |= ZipEntryTimestamp.Unix;
-                _ntfsTimesAreSet = true;
-                _emitUnixTimes = true;
-            }
-            else
-                ReadExtraField(); // will recurse
-
-            return j;
-        }
-
-
-        private int ProcessExtraFieldWindowsTimes(byte[] buffer, int j, Int16 dataSize, long posn)
-        {
-            // The NTFS filetimes are 64-bit unsigned integers, stored in Intel
-            // (least significant byte first) byte order. They are expressed as the
-            // number of 1.0E-07 seconds (1/10th microseconds!) past WinNT "epoch",
-            // which is "01-Jan-1601 00:00:00 UTC".
-            //
-            // HeaderId   2 bytes    0x000a == NTFS stuff
-            // Datasize   2 bytes    ?? (usually 32)
-            // reserved   4 bytes    ??
-            // timetag    2 bytes    0x0001 == time
-            // size       2 bytes    24 == 8 bytes each for ctime, mtime, atime
-            // mtime      8 bytes    win32 ticks since win32epoch
-            // atime      8 bytes    win32 ticks since win32epoch
-            // ctime      8 bytes    win32 ticks since win32epoch
-
-            if (dataSize != 32)
-                throw new BadReadException(String.Format("  Unexpected size (0x{0:X4}) for NTFS times extra field at position 0x{1:X16}", dataSize, posn));
-
-            j += 4;  // reserved
-            Int16 timetag = (Int16)(buffer[j] + buffer[j + 1] * 256);
-            Int16 addlsize = (Int16)(buffer[j + 2] + buffer[j + 3] * 256);
-            j += 4;  // tag and size
-
-            if (timetag == 0x0001 && addlsize == 24)
-            {
-                Int64 z = BitConverter.ToInt64(buffer, j);
-                this._Mtime = DateTime.FromFileTimeUtc(z);
-                j += 8;
-
-                // At this point the library *could* set the LastModified value
-                // to coincide with the Mtime value.  In theory, they refer to
-                // the same property of the file, and should be the same anyway,
-                // allowing for differences in precision.  But they are
-                // independent quantities in the zip archive, and this library
-                // will keep them separate in the object model. There is no ill
-                // effect from this, because as files are extracted, the
-                // higher-precision value (Mtime) is used if it is present.
-                // Apps may wish to compare the Mtime versus LastModified
-                // values, but any difference when both are present is not
-                // germaine to the correctness of the library. but note: when
-                // explicitly setting either value, both are set. See the setter
-                // for LastModified or the SetNtfsTimes() method.
-
-                z = BitConverter.ToInt64(buffer, j);
-                this._Atime = DateTime.FromFileTimeUtc(z);
-                j += 8;
-
-                z = BitConverter.ToInt64(buffer, j);
-                this._Ctime = DateTime.FromFileTimeUtc(z);
-                j += 8;
-
-                _ntfsTimesAreSet = true;
-                _timestamp |= ZipEntryTimestamp.Windows;
-                _emitNtfsTimes = true;
-            }
-            return j;
-        }
-
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipEntry.Write.cs b/EPPlus/Packaging/DotNetZip/ZipEntry.Write.cs
deleted file mode 100644
index dc95211..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipEntry.Write.cs
+++ /dev/null
@@ -1,2583 +0,0 @@
-//#define Trace
-
-// ZipEntry.Write.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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: <2011-July-30 14:55:47>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for writing (saving) the ZipEntry into a
-// zip file.
-//
-// ------------------------------------------------------------------
-
-
-using OfficeOpenXml.Packaging.Ionic.Zlib;
-using System;
-using System.IO;
-using RE = System.Text.RegularExpressions;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal partial class ZipEntry
-    {
-        internal void WriteCentralDirectoryEntry(Stream s)
-        {
-            byte[] bytes = new byte[4096];
-            int i = 0;
-            // signature
-            bytes[i++] = (byte)(ZipConstants.ZipDirEntrySignature & 0x000000FF);
-            bytes[i++] = (byte)((ZipConstants.ZipDirEntrySignature & 0x0000FF00) >> 8);
-            bytes[i++] = (byte)((ZipConstants.ZipDirEntrySignature & 0x00FF0000) >> 16);
-            bytes[i++] = (byte)((ZipConstants.ZipDirEntrySignature & 0xFF000000) >> 24);
-
-            // Version Made By
-            // workitem 7071
-            // We must not overwrite the VersionMadeBy field when writing out a zip
-            // archive.  The VersionMadeBy tells the zip reader the meaning of the
-            // File attributes.  Overwriting the VersionMadeBy will result in
-            // inconsistent metadata.  Consider the scenario where the application
-            // opens and reads a zip file that had been created on Linux. Then the
-            // app adds one file to the Zip archive, and saves it.  The file
-            // attributes for all the entries added on Linux will be significant for
-            // Linux.  Therefore the VersionMadeBy for those entries must not be
-            // changed.  Only the entries that are actually created on Windows NTFS
-            // should get the VersionMadeBy indicating Windows/NTFS.
-            bytes[i++] = (byte)(_VersionMadeBy & 0x00FF);
-            bytes[i++] = (byte)((_VersionMadeBy & 0xFF00) >> 8);
-
-            // Apparently we want to duplicate the extra field here; we cannot
-            // simply zero it out and assume tools and apps will use the right one.
-
-            ////Int16 extraFieldLengthSave = (short)(_EntryHeader[28] + _EntryHeader[29] * 256);
-            ////_EntryHeader[28] = 0;
-            ////_EntryHeader[29] = 0;
-
-            // Version Needed, Bitfield, compression method, lastmod,
-            // crc, compressed and uncompressed sizes, filename length and extra field length.
-            // These are all present in the local file header, but they may be zero values there.
-            // So we cannot just copy them.
-
-            // workitem 11969: Version Needed To Extract in central directory must be
-            // the same as the local entry or MS .NET System.IO.Zip fails read.
-            Int16 vNeeded = (Int16)(VersionNeeded != 0 ? VersionNeeded : 20);
-            // workitem 12964
-            if (_OutputUsesZip64==null)
-            {
-                // a zipentry in a zipoutputstream, with zero bytes written
-                _OutputUsesZip64 = new Nullable<bool>(_container.Zip64 == Zip64Option.Always);
-            }
-
-            Int16 versionNeededToExtract = (Int16)(_OutputUsesZip64.Value ? 45 : vNeeded);
-#if BZIP
-            if (this.CompressionMethod == Ionic.Zip.CompressionMethod.BZip2)
-                versionNeededToExtract = 46;
-#endif
-
-            bytes[i++] = (byte)(versionNeededToExtract & 0x00FF);
-            bytes[i++] = (byte)((versionNeededToExtract & 0xFF00) >> 8);
-
-            bytes[i++] = (byte)(_BitField & 0x00FF);
-            bytes[i++] = (byte)((_BitField & 0xFF00) >> 8);
-
-            bytes[i++] = (byte)(_CompressionMethod & 0x00FF);
-            bytes[i++] = (byte)((_CompressionMethod & 0xFF00) >> 8);
-
-#if AESCRYPTO
-            if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-            Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                i -= 2;
-                bytes[i++] = 0x63;
-                bytes[i++] = 0;
-            }
-#endif
-
-            bytes[i++] = (byte)(_TimeBlob & 0x000000FF);
-            bytes[i++] = (byte)((_TimeBlob & 0x0000FF00) >> 8);
-            bytes[i++] = (byte)((_TimeBlob & 0x00FF0000) >> 16);
-            bytes[i++] = (byte)((_TimeBlob & 0xFF000000) >> 24);
-            bytes[i++] = (byte)(_Crc32 & 0x000000FF);
-            bytes[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8);
-            bytes[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16);
-            bytes[i++] = (byte)((_Crc32 & 0xFF000000) >> 24);
-
-            int j = 0;
-            if (_OutputUsesZip64.Value)
-            {
-                // CompressedSize (Int32) and UncompressedSize - all 0xFF
-                for (j = 0; j < 8; j++)
-                    bytes[i++] = 0xFF;
-            }
-            else
-            {
-                bytes[i++] = (byte)(_CompressedSize & 0x000000FF);
-                bytes[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
-                bytes[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
-                bytes[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
-                bytes[i++] = (byte)(_UncompressedSize & 0x000000FF);
-                bytes[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
-                bytes[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
-                bytes[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
-            }
-
-            byte[] fileNameBytes = GetEncodedFileNameBytes();
-            Int16 filenameLength = (Int16)fileNameBytes.Length;
-            bytes[i++] = (byte)(filenameLength & 0x00FF);
-            bytes[i++] = (byte)((filenameLength & 0xFF00) >> 8);
-
-            // do this again because now we have real data
-            _presumeZip64 = _OutputUsesZip64.Value;
-
-            // workitem 11131
-            //
-            // cannot generate the extra field again, here's why: In the case of a
-            // zero-byte entry, which uses encryption, DotNetZip will "remove" the
-            // encryption from the entry.  It does this in PostProcessOutput; it
-            // modifies the entry header, and rewrites it, resetting the Bitfield
-            // (one bit indicates encryption), and potentially resetting the
-            // compression method - for AES the Compression method is 0x63, and it
-            // would get reset to zero (no compression).  It then calls SetLength()
-            // to truncate the stream to remove the encryption header (12 bytes for
-            // AES256).  But, it leaves the previously-generated "Extra Field"
-            // metadata (11 bytes) for AES in the entry header. This extra field
-            // data is now "orphaned" - it refers to AES encryption when in fact no
-            // AES encryption is used. But no problem, the PKWARE spec says that
-            // unrecognized extra fields can just be ignored. ok.  After "removal"
-            // of AES encryption, the length of the Extra Field can remains the
-            // same; it's just that there will be 11 bytes in there that previously
-            // pertained to AES which are now unused. Even the field code is still
-            // there, but it will be unused by readers, as the encryption bit is not
-            // set.
-            //
-            // Re-calculating the Extra field now would produce a block that is 11
-            // bytes shorter, and that mismatch - between the extra field in the
-            // local header and the extra field in the Central Directory - would
-            // cause problems. (where? why? what problems?)  So we can't do
-            // that. It's all good though, because though the content may have
-            // changed, the length definitely has not. Also, the _EntryHeader
-            // contains the "updated" extra field (after PostProcessOutput) at
-            // offset (30 + filenameLength).
-
-            _Extra = ConstructExtraField(true);
-
-            Int16 extraFieldLength = (Int16)((_Extra == null) ? 0 : _Extra.Length);
-            bytes[i++] = (byte)(extraFieldLength & 0x00FF);
-            bytes[i++] = (byte)((extraFieldLength & 0xFF00) >> 8);
-
-            // File (entry) Comment Length
-            // the _CommentBytes private field was set during WriteHeader()
-            int commentLength = (_CommentBytes == null) ? 0 : _CommentBytes.Length;
-
-            // the size of our buffer defines the max length of the comment we can write
-            if (commentLength + i > bytes.Length) commentLength = bytes.Length - i;
-            bytes[i++] = (byte)(commentLength & 0x00FF);
-            bytes[i++] = (byte)((commentLength & 0xFF00) >> 8);
-
-            // Disk number start
-            bool segmented = (this._container.ZipFile != null) &&
-                (this._container.ZipFile.MaxOutputSegmentSize != 0);
-            if (segmented) // workitem 13915
-            {
-                // Emit nonzero disknumber only if saving segmented archive.
-                bytes[i++] = (byte)(_diskNumber & 0x00FF);
-                bytes[i++] = (byte)((_diskNumber & 0xFF00) >> 8);
-            }
-            else
-            {
-                // If reading a segmneted archive and saving to a regular archive,
-                // ZipEntry._diskNumber will be non-zero but it should be saved as
-                // zero.
-                bytes[i++] = 0;
-                bytes[i++] = 0;
-            }
-
-            // internal file attrs
-            // workitem 7801
-            bytes[i++] = (byte)((_IsText) ? 1 : 0); // lo bit: filetype hint.  0=bin, 1=txt.
-            bytes[i++] = 0;
-
-            // external file attrs
-            // workitem 7071
-            bytes[i++] = (byte)(_ExternalFileAttrs & 0x000000FF);
-            bytes[i++] = (byte)((_ExternalFileAttrs & 0x0000FF00) >> 8);
-            bytes[i++] = (byte)((_ExternalFileAttrs & 0x00FF0000) >> 16);
-            bytes[i++] = (byte)((_ExternalFileAttrs & 0xFF000000) >> 24);
-
-            // workitem 11131
-            // relative offset of local header.
-            //
-            // If necessary to go to 64-bit value, then emit 0xFFFFFFFF,
-            // else write out the value.
-            //
-            // Even if zip64 is required for other reasons - number of the entry
-            // > 65534, or uncompressed size of the entry > MAX_INT32, the ROLH
-            // need not be stored in a 64-bit field .
-            if (_RelativeOffsetOfLocalHeader > 0xFFFFFFFFL) // _OutputUsesZip64.Value
-            {
-                bytes[i++] = 0xFF;
-                bytes[i++] = 0xFF;
-                bytes[i++] = 0xFF;
-                bytes[i++] = 0xFF;
-            }
-            else
-            {
-                bytes[i++] = (byte)(_RelativeOffsetOfLocalHeader & 0x000000FF);
-                bytes[i++] = (byte)((_RelativeOffsetOfLocalHeader & 0x0000FF00) >> 8);
-                bytes[i++] = (byte)((_RelativeOffsetOfLocalHeader & 0x00FF0000) >> 16);
-                bytes[i++] = (byte)((_RelativeOffsetOfLocalHeader & 0xFF000000) >> 24);
-            }
-
-            // actual filename
-            Buffer.BlockCopy(fileNameBytes, 0, bytes, i, filenameLength);
-            i += filenameLength;
-
-            // "Extra field"
-            if (_Extra != null)
-            {
-                // workitem 11131
-                //
-                // copy from EntryHeader if available - it may have been updated.
-                // if not, copy from Extra. This would be unnecessary if I just
-                // updated the Extra field when updating EntryHeader, in
-                // PostProcessOutput.
-
-                //?? I don't understand why I wouldn't want to just use
-                // the recalculated Extra field. ??
-
-                // byte[] h = _EntryHeader ?? _Extra;
-                // int offx = (h == _EntryHeader) ? 30 + filenameLength : 0;
-                // Buffer.BlockCopy(h, offx, bytes, i, extraFieldLength);
-                // i += extraFieldLength;
-
-                byte[] h = _Extra;
-                int offx = 0;
-                Buffer.BlockCopy(h, offx, bytes, i, extraFieldLength);
-                i += extraFieldLength;
-            }
-
-            // file (entry) comment
-            if (commentLength != 0)
-            {
-                // now actually write the comment itself into the byte buffer
-                Buffer.BlockCopy(_CommentBytes, 0, bytes, i, commentLength);
-                // for (j = 0; (j < commentLength) && (i + j < bytes.Length); j++)
-                //     bytes[i + j] = _CommentBytes[j];
-                i += commentLength;
-            }
-
-            s.Write(bytes, 0, i);
-        }
-
-
-#if INFOZIP_UTF8
-        static private bool FileNameIsUtf8(char[] FileNameChars)
-        {
-            bool isUTF8 = false;
-            bool isUnicode = false;
-            for (int j = 0; j < FileNameChars.Length; j++)
-            {
-                byte[] b = System.BitConverter.GetBytes(FileNameChars[j]);
-                isUnicode |= (b.Length != 2);
-                isUnicode |= (b[1] != 0);
-                isUTF8 |= ((b[0] & 0x80) != 0);
-            }
-
-            return isUTF8;
-        }
-#endif
-
-
-        private byte[] ConstructExtraField(bool forCentralDirectory)
-        {
-            var listOfBlocks = new System.Collections.Generic.List<byte[]>();
-            byte[] block;
-
-            // Conditionally emit an extra field with Zip64 information.  If the
-            // Zip64 option is Always, we emit the field, before knowing that it's
-            // necessary.  Later, if it turns out this entry does not need zip64,
-            // we'll set the header ID to rubbish and the data will be ignored.
-            // This results in additional overhead metadata in the zip file, but
-            // it will be small in comparison to the entry data.
-            //
-            // On the other hand if the Zip64 option is AsNecessary and it's NOT
-            // for the central directory, then we do the same thing.  Or, if the
-            // Zip64 option is AsNecessary and it IS for the central directory,
-            // and the entry requires zip64, then emit the header.
-            if (_container.Zip64 == Zip64Option.Always ||
-                (_container.Zip64 == Zip64Option.AsNecessary &&
-                 (!forCentralDirectory || _entryRequiresZip64.Value)))
-            {
-                // add extra field for zip64 here
-                // workitem 7924
-                int sz = 4 + (forCentralDirectory ? 28 : 16);
-                block = new byte[sz];
-                int i = 0;
-
-                if (_presumeZip64 || forCentralDirectory)
-                {
-                    // HeaderId = always use zip64 extensions.
-                    block[i++] = 0x01;
-                    block[i++] = 0x00;
-                }
-                else
-                {
-                    // HeaderId = dummy data now, maybe set to 0x0001 (ZIP64) later.
-                    block[i++] = 0x99;
-                    block[i++] = 0x99;
-                }
-
-                // DataSize
-                block[i++] = (byte)(sz - 4);  // decimal 28 or 16  (workitem 7924)
-                block[i++] = 0x00;
-
-                // The actual metadata - we may or may not have real values yet...
-
-                // uncompressed size
-                Array.Copy(BitConverter.GetBytes(_UncompressedSize), 0, block, i, 8);
-                i += 8;
-                // compressed size
-                Array.Copy(BitConverter.GetBytes(_CompressedSize), 0, block, i, 8);
-                i += 8;
-
-                // workitem 7924 - only include this if the "extra" field is for
-                // use in the central directory.  It is unnecessary and not useful
-                // for local header; makes WinZip choke.
-                if (forCentralDirectory)
-                {
-                    // relative offset
-                    Array.Copy(BitConverter.GetBytes(_RelativeOffsetOfLocalHeader), 0, block, i, 8);
-                    i += 8;
-
-                    // starting disk number
-                    Array.Copy(BitConverter.GetBytes(0), 0, block, i, 4);
-                }
-                listOfBlocks.Add(block);
-            }
-
-
-#if AESCRYPTO
-            if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                block = new byte[4 + 7];
-                int i = 0;
-                // extra field for WinZip AES
-                // header id
-                block[i++] = 0x01;
-                block[i++] = 0x99;
-
-                // data size
-                block[i++] = 0x07;
-                block[i++] = 0x00;
-
-                // vendor number
-                block[i++] = 0x01;  // AE-1 - means "Verify CRC"
-                block[i++] = 0x00;
-
-                // vendor id "AE"
-                block[i++] = 0x41;
-                block[i++] = 0x45;
-
-                // key strength
-                int keystrength = GetKeyStrengthInBits(Encryption);
-                if (keystrength == 128)
-                    block[i] = 1;
-                else if (keystrength == 256)
-                    block[i] = 3;
-                else
-                    block[i] = 0xFF;
-                i++;
-
-                // actual compression method
-                block[i++] = (byte)(_CompressionMethod & 0x00FF);
-                block[i++] = (byte)(_CompressionMethod & 0xFF00);
-
-                listOfBlocks.Add(block);
-            }
-#endif
-
-            if (_ntfsTimesAreSet && _emitNtfsTimes)
-            {
-                block = new byte[32 + 4];
-                // HeaderId   2 bytes    0x000a == NTFS times
-                // Datasize   2 bytes    32
-                // reserved   4 bytes    ?? don't care
-                // timetag    2 bytes    0x0001 == NTFS time
-                // size       2 bytes    24 == 8 bytes each for ctime, mtime, atime
-                // mtime      8 bytes    win32 ticks since win32epoch
-                // atime      8 bytes    win32 ticks since win32epoch
-                // ctime      8 bytes    win32 ticks since win32epoch
-                int i = 0;
-                // extra field for NTFS times
-                // header id
-                block[i++] = 0x0a;
-                block[i++] = 0x00;
-
-                // data size
-                block[i++] = 32;
-                block[i++] = 0;
-
-                i += 4; // reserved
-
-                // time tag
-                block[i++] = 0x01;
-                block[i++] = 0x00;
-
-                // data size (again)
-                block[i++] = 24;
-                block[i++] = 0;
-
-                Int64 z = _Mtime.ToFileTime();
-                Array.Copy(BitConverter.GetBytes(z), 0, block, i, 8);
-                i += 8;
-                z = _Atime.ToFileTime();
-                Array.Copy(BitConverter.GetBytes(z), 0, block, i, 8);
-                i += 8;
-                z = _Ctime.ToFileTime();
-                Array.Copy(BitConverter.GetBytes(z), 0, block, i, 8);
-                i += 8;
-
-                listOfBlocks.Add(block);
-            }
-
-            if (_ntfsTimesAreSet && _emitUnixTimes)
-            {
-                int len = 5 + 4;
-                if (!forCentralDirectory) len += 8;
-
-                block = new byte[len];
-                // local form:
-                // --------------
-                // HeaderId   2 bytes    0x5455 == unix timestamp
-                // Datasize   2 bytes    13
-                // flags      1 byte     7 (low three bits all set)
-                // mtime      4 bytes    seconds since unix epoch
-                // atime      4 bytes    seconds since unix epoch
-                // ctime      4 bytes    seconds since unix epoch
-                //
-                // central directory form:
-                //---------------------------------
-                // HeaderId   2 bytes    0x5455 == unix timestamp
-                // Datasize   2 bytes    5
-                // flags      1 byte     7 (low three bits all set)
-                // mtime      4 bytes    seconds since unix epoch
-                //
-                int i = 0;
-                // extra field for "unix" times
-                // header id
-                block[i++] = 0x55;
-                block[i++] = 0x54;
-
-                // data size
-                block[i++] = unchecked((byte)(len - 4));
-                block[i++] = 0;
-
-                // flags
-                block[i++] = 0x07;
-
-                Int32 z = unchecked((int)((_Mtime - _unixEpoch).TotalSeconds));
-                Array.Copy(BitConverter.GetBytes(z), 0, block, i, 4);
-                i += 4;
-                if (!forCentralDirectory)
-                {
-                    z = unchecked((int)((_Atime - _unixEpoch).TotalSeconds));
-                    Array.Copy(BitConverter.GetBytes(z), 0, block, i, 4);
-                    i += 4;
-                    z = unchecked((int)((_Ctime - _unixEpoch).TotalSeconds));
-                    Array.Copy(BitConverter.GetBytes(z), 0, block, i, 4);
-                    i += 4;
-                }
-                listOfBlocks.Add(block);
-            }
-
-
-            // inject other blocks here...
-
-
-            // concatenate any blocks we've got:
-            byte[] aggregateBlock = null;
-            if (listOfBlocks.Count > 0)
-            {
-                int totalLength = 0;
-                int i, current = 0;
-                for (i = 0; i < listOfBlocks.Count; i++)
-                    totalLength += listOfBlocks[i].Length;
-                aggregateBlock = new byte[totalLength];
-                for (i = 0; i < listOfBlocks.Count; i++)
-                {
-                    System.Array.Copy(listOfBlocks[i], 0, aggregateBlock, current, listOfBlocks[i].Length);
-                    current += listOfBlocks[i].Length;
-                }
-            }
-
-            return aggregateBlock;
-        }
-
-
-
-        // private System.Text.Encoding GenerateCommentBytes()
-        // {
-        //     var getEncoding = new Func<System.Text.Encoding>({
-        //     switch (AlternateEncodingUsage)
-        //     {
-        //         case ZipOption.Always:
-        //             return AlternateEncoding;
-        //         case ZipOption.Never:
-        //             return ibm437;
-        //     }
-        //     var cb = ibm437.GetBytes(_Comment);
-        //     // need to use this form of GetString() for .NET CF
-        //     string s1 = ibm437.GetString(cb, 0, cb.Length);
-        //     if (s1 == _Comment)
-        //         return ibm437;
-        //     return AlternateEncoding;
-        //     });
-        //
-        //     var encoding = getEncoding();
-        //     _CommentBytes = encoding.GetBytes(_Comment);
-        //     return encoding;
-        // }
-
-
-        private string NormalizeFileName()
-        {
-            // here, we need to flip the backslashes to forward-slashes,
-            // also, we need to trim the \\server\share syntax from any UNC path.
-            // and finally, we need to remove any leading .\
-
-            string SlashFixed = FileName.Replace("\\", "/");
-            string s1 = null;
-            if ((_TrimVolumeFromFullyQualifiedPaths) && (FileName.Length >= 3)
-                && (FileName[1] == ':') && (SlashFixed[2] == '/'))
-            {
-                // trim off volume letter, colon, and slash
-                s1 = SlashFixed.Substring(3);
-            }
-            else if ((FileName.Length >= 4)
-                     && ((SlashFixed[0] == '/') && (SlashFixed[1] == '/')))
-            {
-                int n = SlashFixed.IndexOf('/', 2);
-                if (n == -1)
-                    throw new ArgumentException("The path for that entry appears to be badly formatted");
-                s1 = SlashFixed.Substring(n + 1);
-            }
-            else if ((FileName.Length >= 3)
-                     && ((SlashFixed[0] == '.') && (SlashFixed[1] == '/')))
-            {
-                // trim off dot and slash
-                s1 = SlashFixed.Substring(2);
-            }
-            else
-            {
-                s1 = SlashFixed;
-            }
-            return s1;
-        }
-
-
-        /// <summary>
-        ///   generate and return a byte array that encodes the filename
-        ///   for the entry.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     side effects: generate and store into _CommentBytes the
-        ///     byte array for any comment attached to the entry. Also
-        ///     sets _actualEncoding to indicate the actual encoding
-        ///     used. The same encoding is used for both filename and
-        ///     comment.
-        ///   </para>
-        /// </remarks>
-        private byte[] GetEncodedFileNameBytes()
-        {
-            // workitem 6513
-            var s1 = NormalizeFileName();
-
-            switch(AlternateEncodingUsage)
-            {
-                case ZipOption.Always:
-                    if (!(_Comment == null || _Comment.Length == 0))
-                        _CommentBytes = AlternateEncoding.GetBytes(_Comment);
-                    _actualEncoding = AlternateEncoding;
-                    return AlternateEncoding.GetBytes(s1);
-
-                case ZipOption.Never:
-                    if (!(_Comment == null || _Comment.Length == 0))
-                        _CommentBytes = ibm437.GetBytes(_Comment);
-                    _actualEncoding = ibm437;
-                    return ibm437.GetBytes(s1);
-            }
-
-            // arriving here means AlternateEncodingUsage is "AsNecessary"
-
-            // case ZipOption.AsNecessary:
-            // workitem 6513: when writing, use the alternative encoding
-            // only when _actualEncoding is not yet set (it can be set
-            // during Read), and when ibm437 will not do.
-
-            byte[] result = ibm437.GetBytes(s1);
-            // need to use this form of GetString() for .NET CF
-            string s2 = ibm437.GetString(result, 0, result.Length);
-            _CommentBytes = null;
-            if (s2 != s1)
-            {
-                // Encoding the filename with ibm437 does not allow round-trips.
-                // Therefore, use the alternate encoding.  Assume it will work,
-                // no checking of round trips here.
-                result = AlternateEncoding.GetBytes(s1);
-                if (_Comment != null && _Comment.Length != 0)
-                    _CommentBytes = AlternateEncoding.GetBytes(_Comment);
-                _actualEncoding = AlternateEncoding;
-                return result;
-            }
-
-            _actualEncoding = ibm437;
-
-            // Using ibm437, FileName can be encoded without information
-            // loss; now try the Comment.
-
-            // if there is no comment, use ibm437.
-            if (_Comment == null || _Comment.Length == 0)
-                return result;
-
-            // there is a comment. Get the encoded form.
-            byte[] cbytes = ibm437.GetBytes(_Comment);
-            string c2 = ibm437.GetString(cbytes,0,cbytes.Length);
-
-            // Check for round-trip.
-            if (c2 != Comment)
-            {
-                // Comment cannot correctly be encoded with ibm437.  Use
-                // the alternate encoding.
-
-                result = AlternateEncoding.GetBytes(s1);
-                _CommentBytes = AlternateEncoding.GetBytes(_Comment);
-                _actualEncoding = AlternateEncoding;
-                return result;
-            }
-
-            // use IBM437
-            _CommentBytes = cbytes;
-            return result;
-        }
-
-
-
-        private bool WantReadAgain()
-        {
-            if (_UncompressedSize < 0x10) return false;
-            if (_CompressionMethod == 0x00) return false;
-            if (CompressionLevel == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.None) return false;
-            if (_CompressedSize < _UncompressedSize) return false;
-
-            if (this._Source == ZipEntrySource.Stream && !this._sourceStream.CanSeek) return false;
-
-#if AESCRYPTO
-            if (_aesCrypto_forWrite != null && (CompressedSize - _aesCrypto_forWrite.SizeOfEncryptionMetadata) <= UncompressedSize + 0x10) return false;
-#endif
-
-            if (_zipCrypto_forWrite != null && (CompressedSize - 12) <= UncompressedSize) return false;
-
-            return true;
-        }
-
-
-
-        private void MaybeUnsetCompressionMethodForWriting(int cycle)
-        {
-            // if we've already tried with compression... turn it off this time
-            if (cycle > 1)
-            {
-                _CompressionMethod = 0x0;
-                return;
-            }
-            // compression for directories = 0x00 (No Compression)
-            if (IsDirectory)
-            {
-                _CompressionMethod = 0x0;
-                return;
-            }
-
-            if (this._Source == ZipEntrySource.ZipFile)
-            {
-                return; // do nothing
-            }
-
-            // If __FileDataPosition is zero, then that means we will get the data
-            // from a file or stream.
-
-            // It is never possible to compress a zero-length file, so we check for
-            // this condition.
-
-            if (this._Source == ZipEntrySource.Stream)
-            {
-                // workitem 7742
-                if (_sourceStream != null && _sourceStream.CanSeek)
-                {
-                    // Length prop will throw if CanSeek is false
-                    long fileLength = _sourceStream.Length;
-                    if (fileLength == 0)
-                    {
-                        _CompressionMethod = 0x00;
-                        return;
-                    }
-                }
-            }
-            else if ((this._Source == ZipEntrySource.FileSystem) && (SharedUtilities.GetFileLength(LocalFileName) == 0L))
-            {
-                _CompressionMethod = 0x00;
-                return;
-            }
-
-            // Ok, we're getting the data to be compressed from a
-            // non-zero-length file or stream, or a file or stream of
-            // unknown length, and we presume that it is non-zero.  In
-            // that case we check the callback to see if the app wants
-            // to tell us whether to compress or not.
-            if (SetCompression != null)
-                CompressionLevel = SetCompression(LocalFileName, _FileNameInArchive);
-
-            // finally, set CompressionMethod to None if CompressionLevel is None
-            if (CompressionLevel == (short)Ionic.Zlib.CompressionLevel.None &&
-                CompressionMethod == Ionic.Zip.CompressionMethod.Deflate)
-                _CompressionMethod = 0x00;
-
-            return;
-        }
-
-
-
-        // write the header info for an entry
-        internal void WriteHeader(Stream s, int cycle)
-        {
-            // Must remember the offset, within the output stream, of this particular
-            // entry header.
-            //
-            // This is for 2 reasons:
-            //
-            //  1. so we can determine the RelativeOffsetOfLocalHeader (ROLH) for
-            //     use in the central directory.
-            //  2. so we can seek backward in case there is an error opening or reading
-            //     the file, and the application decides to skip the file. In this case,
-            //     we need to seek backward in the output stream to allow the next entry
-            //     to be added to the zipfile output stream.
-            //
-            // Normally you would just store the offset before writing to the output
-            // stream and be done with it.  But the possibility to use split archives
-            // makes this approach ineffective.  In split archives, each file or segment
-            // is bound to a max size limit, and each local file header must not span a
-            // segment boundary; it must be written contiguously.  If it will fit in the
-            // current segment, then the ROLH is just the current Position in the output
-            // stream.  If it won't fit, then we need a new file (segment) and the ROLH
-            // is zero.
-            //
-            // But we only can know if it is possible to write a header contiguously
-            // after we know the size of the local header, a size that varies with
-            // things like filename length, comments, and extra fields.  We have to
-            // compute the header fully before knowing whether it will fit.
-            //
-            // That takes care of item #1 above.  Now, regarding #2.  If an error occurs
-            // while computing the local header, we want to just seek backward. The
-            // exception handling logic (in the caller of WriteHeader) uses ROLH to
-            // scroll back.
-            //
-            // All this means we have to preserve the starting offset before computing
-            // the header, and also we have to compute the offset later, to handle the
-            // case of split archives.
-
-            var counter = s as CountingStream;
-
-            // workitem 8098: ok (output)
-            // This may change later, for split archives
-
-            // Don't set _RelativeOffsetOfLocalHeader. Instead, set a temp variable.
-            // This allows for re-streaming, where a zip entry might be read from a
-            // zip archive (and maybe decrypted, and maybe decompressed) and then
-            // written to another zip archive, with different settings for
-            // compression method, compression level, or encryption algorithm.
-            _future_ROLH = (counter != null)
-                ? counter.ComputedPosition
-                : s.Position;
-
-            int j = 0, i = 0;
-
-            byte[] block = new byte[30];
-
-            // signature
-            block[i++] = (byte)(ZipConstants.ZipEntrySignature & 0x000000FF);
-            block[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x0000FF00) >> 8);
-            block[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x00FF0000) >> 16);
-            block[i++] = (byte)((ZipConstants.ZipEntrySignature & 0xFF000000) >> 24);
-
-            // Design notes for ZIP64:
-            //
-            // The specification says that the header must include the Compressed
-            // and Uncompressed sizes, as well as the CRC32 value.  When creating
-            // a zip via streamed processing, these quantities are not known until
-            // after the compression is done.  Thus, a typical way to do it is to
-            // insert zeroes for these quantities, then do the compression, then
-            // seek back to insert the appropriate values, then seek forward to
-            // the end of the file data.
-            //
-            // There is also the option of using bit 3 in the GP bitfield - to
-            // specify that there is a data descriptor after the file data
-            // containing these three quantities.
-            //
-            // This works when the size of the quantities is known, either 32-bits
-            // or 64 bits as with the ZIP64 extensions.
-            //
-            // With Zip64, the 4-byte fields are set to 0xffffffff, and there is a
-            // corresponding data block in the "extra field" that contains the
-            // actual Compressed, uncompressed sizes.  (As well as an additional
-            // field, the "Relative Offset of Local Header")
-            //
-            // The problem is when the app desires to use ZIP64 extensions
-            // optionally, only when necessary.  Suppose the library assumes no
-            // zip64 extensions when writing the header, then after compression
-            // finds that the size of the data requires zip64.  At this point, the
-            // header, already written to the file, won't have the necessary data
-            // block in the "extra field".  The size of the entry header is fixed,
-            // so it is not possible to just "add on" the zip64 data block after
-            // compressing the file.  On the other hand, always using zip64 will
-            // break interoperability with many other systems and apps.
-            //
-            // The approach we take is to insert a 32-byte dummy data block in the
-            // extra field, whenever zip64 is to be used "as necessary". This data
-            // block will get the actual zip64 HeaderId and zip64 metadata if
-            // necessary.  If not necessary, the data block will get a meaningless
-            // HeaderId (0x1111), and will be filled with zeroes.
-            //
-            // When zip64 is actually in use, we also need to set the
-            // VersionNeededToExtract field to 45.
-            //
-            // There is one additional wrinkle: using zip64 as necessary conflicts
-            // with output to non-seekable devices.  The header is emitted and
-            // must indicate whether zip64 is in use, before we know if zip64 is
-            // necessary.  Because there is no seeking, the header can never be
-            // changed.  Therefore, on non-seekable devices,
-            // Zip64Option.AsNecessary is the same as Zip64Option.Always.
-            //
-
-
-            // version needed- see AppNote.txt.
-            //
-            // need v5.1 for PKZIP strong encryption, or v2.0 for no encryption or
-            // for PK encryption, 4.5 for zip64.  We may reset this later, as
-            // necessary or zip64.
-
-            _presumeZip64 = (_container.Zip64 == Zip64Option.Always ||
-                             (_container.Zip64 == Zip64Option.AsNecessary && !s.CanSeek));
-            Int16 VersionNeededToExtract = (Int16)(_presumeZip64 ? 45 : 20);
-#if BZIP
-            if (this.CompressionMethod == Ionic.Zip.CompressionMethod.BZip2)
-                VersionNeededToExtract = 46;
-#endif
-
-            // (i==4)
-            block[i++] = (byte)(VersionNeededToExtract & 0x00FF);
-            block[i++] = (byte)((VersionNeededToExtract & 0xFF00) >> 8);
-
-            // Get byte array. Side effect: sets ActualEncoding.
-            // Must determine encoding before setting the bitfield.
-            // workitem 6513
-            byte[] fileNameBytes = GetEncodedFileNameBytes();
-            Int16 filenameLength = (Int16)fileNameBytes.Length;
-
-            // general purpose bitfield
-            // In the current implementation, this library uses only these bits
-            // in the GP bitfield:
-            //  bit 0 = if set, indicates the entry is encrypted
-            //  bit 3 = if set, indicates the CRC, C and UC sizes follow the file data.
-            //  bit 6 = strong encryption - for pkware's meaning of strong encryption
-            //  bit 11 = UTF-8 encoding is used in the comment and filename
-
-
-            // Here we set or unset the encryption bit.
-            // _BitField may already be set, as with a ZipEntry added into ZipOutputStream, which
-            // has bit 3 always set. We only want to set one bit
-            if (_Encryption == EncryptionAlgorithm.None)
-                _BitField &= ~1;  // encryption bit OFF
-            else
-                _BitField |= 1;   // encryption bit ON
-
-
-            // workitem 7941: WinZip does not the "strong encryption" bit  when using AES.
-            // This "Strong Encryption" is a PKWare Strong encryption thing.
-            //                 _BitField |= 0x0020;
-
-            // set the UTF8 bit if necessary
-#if SILVERLIGHT
-            if (_actualEncoding.WebName == "utf-8")
-#else
-            if (_actualEncoding.CodePage == System.Text.Encoding.UTF8.CodePage)
-#endif
-                _BitField |= 0x0800;
-
-            // The PKZIP spec says that if bit 3 is set (0x0008) in the General
-            // Purpose BitField, then the CRC, Compressed size, and uncompressed
-            // size are written directly after the file data.
-            //
-            // These 3 quantities are normally present in the regular zip entry
-            // header. But, they are not knowable until after the compression is
-            // done. So, in the normal case, we
-            //
-            //  - write the header, using zeros for these quantities
-            //  - compress the data, and incidentally compute these quantities.
-            //  - seek back and write the correct values them into the header.
-            //
-            // This is nice because, while it is more complicated to write the zip
-            // file, it is simpler and less error prone to read the zip file, and
-            // as a result more applications can read zip files produced this way,
-            // with those 3 quantities in the header.
-            //
-            // But if seeking in the output stream is not possible, then we need
-            // to set the appropriate bitfield and emit these quantities after the
-            // compressed file data in the output.
-            //
-            // workitem 7216 - having trouble formatting a zip64 file that is
-            // readable by WinZip.  not sure why!  What I found is that setting
-            // bit 3 and following all the implications, the zip64 file is
-            // readable by WinZip 12. and Perl's IO::Compress::Zip .  Perl takes
-            // an interesting approach - it always sets bit 3 if ZIP64 in use.
-            // DotNetZip now does the same; this gives better compatibility with
-            // WinZip 12.
-
-            if (IsDirectory || cycle == 99)
-            {
-                // (cycle == 99) indicates a zero-length entry written by ZipOutputStream
-
-                _BitField &= ~0x0008;  // unset bit 3 - no "data descriptor" - ever
-                _BitField &= ~0x0001;  // unset bit 1 - no encryption - ever
-                Encryption = EncryptionAlgorithm.None;
-                Password = null;
-            }
-            else if (!s.CanSeek)
-                _BitField |= 0x0008;
-
-#if DONT_GO_THERE
-            else if (this.Encryption == EncryptionAlgorithm.PkzipWeak  &&
-                     this._Source != ZipEntrySource.ZipFile)
-            {
-                // Set bit 3 to avoid the double-read perf issue.
-                //
-                // When PKZIP encryption is used, byte 11 of the encryption header is
-                // used as a consistency check. It is normally set to the MSByte of the
-                // CRC.  But this means the cRC must be known ebfore compression and
-                // encryption, which means the entire stream has to be read twice.  To
-                // avoid that, the high-byte of the time blob (when in DOS format) can
-                // be used for the consistency check (byte 11 in the encryption header).
-                // But this means the entry must have bit 3 set.
-                //
-                // Previously I used a more complex arrangement - using the methods like
-                // FigureCrc32(), PrepOutputStream() and others, in order to manage the
-                // seek-back in the source stream.  Why?  Because bit 3 is not always
-                // friendly with third-party zip tools, like those on the Mac.
-                //
-                // This is why this code is still ifdef'd  out.
-                //
-                // Might consider making this yet another programmable option -
-                // AlwaysUseBit3ForPkzip.  But that's for another day.
-                //
-                _BitField |= 0x0008;
-            }
-#endif
-
-            // (i==6)
-            block[i++] = (byte)(_BitField & 0x00FF);
-            block[i++] = (byte)((_BitField & 0xFF00) >> 8);
-
-            // Here, we want to set values for Compressed Size, Uncompressed Size,
-            // and CRC.  If we have __FileDataPosition as not -1 (zero is a valid
-            // FDP), then that means we are reading this zip entry from a zip
-            // file, and we have good values for those quantities.
-            //
-            // If _FileDataPosition is -1, then we are constructing this Entry
-            // from nothing.  We zero those quantities now, and we will compute
-            // actual values for the three quantities later, when we do the
-            // compression, and then seek back to write them into the appropriate
-            // place in the header.
-            if (this.__FileDataPosition == -1)
-            {
-                //_UncompressedSize = 0; // do not unset - may need this value for restream
-                // _Crc32 = 0;           // ditto
-                _CompressedSize = 0;
-                _crcCalculated = false;
-            }
-
-            // set compression method here
-            MaybeUnsetCompressionMethodForWriting(cycle);
-
-            // (i==8) compression method
-            block[i++] = (byte)(_CompressionMethod & 0x00FF);
-            block[i++] = (byte)((_CompressionMethod & 0xFF00) >> 8);
-
-            if (cycle == 99)
-            {
-                // (cycle == 99) indicates a zero-length entry written by ZipOutputStream
-                SetZip64Flags();
-            }
-
-#if AESCRYPTO
-            else if (Encryption == EncryptionAlgorithm.WinZipAes128 || Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                i -= 2;
-                block[i++] = 0x63;
-                block[i++] = 0;
-            }
-#endif
-
-            // LastMod
-            _TimeBlob = Ionic.Zip.SharedUtilities.DateTimeToPacked(LastModified);
-
-            // (i==10) time blob
-            block[i++] = (byte)(_TimeBlob & 0x000000FF);
-            block[i++] = (byte)((_TimeBlob & 0x0000FF00) >> 8);
-            block[i++] = (byte)((_TimeBlob & 0x00FF0000) >> 16);
-            block[i++] = (byte)((_TimeBlob & 0xFF000000) >> 24);
-
-            // (i==14) CRC - if source==filesystem, this is zero now, actual value
-            // will be calculated later.  if source==archive, this is a bonafide
-            // value.
-            block[i++] = (byte)(_Crc32 & 0x000000FF);
-            block[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8);
-            block[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16);
-            block[i++] = (byte)((_Crc32 & 0xFF000000) >> 24);
-
-            if (_presumeZip64)
-            {
-                // (i==18) CompressedSize (Int32) and UncompressedSize - all 0xFF for now
-                for (j = 0; j < 8; j++)
-                    block[i++] = 0xFF;
-            }
-            else
-            {
-                // (i==18) CompressedSize (Int32) - this value may or may not be
-                // bonafide.  if source == filesystem, then it is zero, and we'll
-                // learn it after we compress.  if source == archive, then it is
-                // bonafide data.
-                block[i++] = (byte)(_CompressedSize & 0x000000FF);
-                block[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
-                block[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
-                block[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
-                // (i==22) UncompressedSize (Int32) - this value may or may not be
-                // bonafide.
-                block[i++] = (byte)(_UncompressedSize & 0x000000FF);
-                block[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
-                block[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
-                block[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
-            }
-
-            // (i==26) filename length (Int16)
-            block[i++] = (byte)(filenameLength & 0x00FF);
-            block[i++] = (byte)((filenameLength & 0xFF00) >> 8);
-
-            _Extra = ConstructExtraField(false);
-
-            // (i==28) extra field length (short)
-            Int16 extraFieldLength = (Int16)((_Extra == null) ? 0 : _Extra.Length);
-            block[i++] = (byte)(extraFieldLength & 0x00FF);
-            block[i++] = (byte)((extraFieldLength & 0xFF00) >> 8);
-
-            // workitem 13542
-            byte[] bytes = new byte[i + filenameLength + extraFieldLength];
-
-            // get the fixed portion
-            Buffer.BlockCopy(block, 0, bytes, 0, i);
-            //for (j = 0; j < i; j++) bytes[j] = block[j];
-
-            // The filename written to the archive.
-            Buffer.BlockCopy(fileNameBytes, 0, bytes, i, fileNameBytes.Length);
-            // for (j = 0; j < fileNameBytes.Length; j++)
-            //     bytes[i + j] = fileNameBytes[j];
-
-            i += fileNameBytes.Length;
-
-            // "Extra field"
-            if (_Extra != null)
-            {
-                Buffer.BlockCopy(_Extra, 0, bytes, i, _Extra.Length);
-                // for (j = 0; j < _Extra.Length; j++)
-                //     bytes[i + j] = _Extra[j];
-                i += _Extra.Length;
-            }
-
-            _LengthOfHeader = i;
-
-            // handle split archives
-            var zss = s as ZipSegmentedStream;
-            if (zss != null)
-            {
-                zss.ContiguousWrite = true;
-                UInt32 requiredSegment = zss.ComputeSegment(i);
-                if (requiredSegment != zss.CurrentSegment)
-                    _future_ROLH = 0; // rollover!
-                else
-                    _future_ROLH = zss.Position;
-
-                _diskNumber = requiredSegment;
-            }
-
-            // validate the ZIP64 usage
-            if (_container.Zip64 == Zip64Option.Never && (uint)_RelativeOffsetOfLocalHeader >= 0xFFFFFFFF)
-                throw new ZipException("Offset within the zip archive exceeds 0xFFFFFFFF. Consider setting the UseZip64WhenSaving property on the ZipFile instance.");
-
-
-            // finally, write the header to the stream
-            s.Write(bytes, 0, i);
-
-            // now that the header is written, we can turn off the contiguous write restriction.
-            if (zss != null)
-                zss.ContiguousWrite = false;
-
-            // Preserve this header data, we'll use it again later.
-            // ..when seeking backward, to write again, after we have the Crc, compressed
-            //   and uncompressed sizes.
-            // ..and when writing the central directory structure.
-            _EntryHeader = bytes;
-        }
-
-
-
-
-        private Int32 FigureCrc32()
-        {
-            if (_crcCalculated == false)
-            {
-                Stream input = null;
-                // get the original stream:
-                if (this._Source == ZipEntrySource.WriteDelegate)
-                {
-                    var output = new Ionic.Crc.CrcCalculatorStream(Stream.Null);
-                    // allow the application to write the data
-                    this._WriteDelegate(this.FileName, output);
-                    _Crc32 = output.Crc;
-                }
-                else if (this._Source == ZipEntrySource.ZipFile)
-                {
-                    // nothing to do - the CRC is already set
-                }
-                else
-                {
-                    if (this._Source == ZipEntrySource.Stream)
-                    {
-                        PrepSourceStream();
-                        input = this._sourceStream;
-                    }
-                    else if (this._Source == ZipEntrySource.JitStream)
-                    {
-                        // allow the application to open the stream
-                        if (this._sourceStream == null)
-                            _sourceStream = this._OpenDelegate(this.FileName);
-                        PrepSourceStream();
-                        input = this._sourceStream;
-                    }
-                    else if (this._Source == ZipEntrySource.ZipOutputStream)
-                    {
-                    }
-                    else
-                    {
-                        //input = File.OpenRead(LocalFileName);
-                        input = File.Open(LocalFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-                    }
-
-                    var crc32 = new Ionic.Crc.CRC32();
-                    _Crc32 = crc32.GetCrc32(input);
-
-                    if (_sourceStream == null)
-                    {
-#if NETCF
-                        input.Close();
-#else
-                        input.Dispose();
-#endif
-                    }
-                }
-                _crcCalculated = true;
-            }
-            return _Crc32;
-        }
-
-
-        /// <summary>
-        ///   Stores the position of the entry source stream, or, if the position is
-        ///   already stored, seeks to that position.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method is called in prep for reading the source stream.  If PKZIP
-        ///   encryption is used, then we need to calc the CRC32 before doing the
-        ///   encryption, because the CRC is used in the 12th byte of the PKZIP
-        ///   encryption header.  So, we need to be able to seek backward in the source
-        ///   when saving the ZipEntry. This method is called from the place that
-        ///   calculates the CRC, and also from the method that does the encryption of
-        ///   the file data.
-        /// </para>
-        ///
-        /// <para>
-        ///   The first time through, this method sets the _sourceStreamOriginalPosition
-        ///   field. Subsequent calls to this method seek to that position.
-        /// </para>
-        /// </remarks>
-        private void PrepSourceStream()
-        {
-            if (_sourceStream == null)
-                throw new ZipException(String.Format("The input stream is null for entry '{0}'.", FileName));
-
-            if (this._sourceStreamOriginalPosition != null)
-            {
-                // this will happen the 2nd cycle through, if the stream is seekable
-                this._sourceStream.Position = this._sourceStreamOriginalPosition.Value;
-            }
-            else if (this._sourceStream.CanSeek)
-            {
-                // this will happen the first cycle through, if seekable
-                this._sourceStreamOriginalPosition = new Nullable<Int64>(this._sourceStream.Position);
-            }
-            else if (this.Encryption == EncryptionAlgorithm.PkzipWeak)
-            {
-                // In general, using PKZIP encryption on a a zip entry whose input
-                // comes from a non-seekable stream, is tricky.  Here's why:
-                //
-                // Byte 11 of the PKZIP encryption header is used for password
-                // validation and consistency checknig.
-                //
-                // Normally, the highest byte of the CRC is used as the 11th (last) byte
-                // in the PKZIP encryption header. This means the CRC must be known
-                // before encryption is performed. Normally that means we read the full
-                // data stream, compute the CRC, then seek back and read it again for
-                // the compression+encryption phase. Obviously this is bad for
-                // performance with a large input file.
-                //
-                // There's a twist in the ZIP spec (actually documented only in infozip
-                // code, not in the spec itself) that allows the high-order byte of the
-                // last modified time for the entry, when the lastmod time is in packed
-                // (DOS) format, to be used for Byte 11 in the encryption header. In
-                // this case, the bit 3 "data descriptor" must be used.
-                //
-                // An intelligent implementation would therefore force the use of the
-                // bit 3 data descriptor when PKZIP encryption is in use, regardless.
-                // This avoids the double-read of the stream to be encrypted.  So far,
-                // DotNetZip doesn't do that; it just punts when the input stream is
-                // non-seekable, and the output does not use Bit 3.
-                //
-                // The other option is to use the CRC when it is already available, eg,
-                // when the source for the data is a ZipEntry (when the zip file is
-                // being updated). In this case we already know the CRC and can just use
-                // what we know.
-
-                if (this._Source != ZipEntrySource.ZipFile && ((this._BitField & 0x0008) != 0x0008))
-                    throw new ZipException("It is not possible to use PKZIP encryption on a non-seekable input stream");
-            }
-        }
-
-
-        /// <summary>
-        /// Copy metadata that may have been changed by the app.  We do this when
-        /// resetting the zipFile instance.  If the app calls Save() on a ZipFile, then
-        /// tries to party on that file some more, we may need to Reset() it , which
-        /// means re-reading the entries and then copying the metadata.  I think.
-        /// </summary>
-        internal void CopyMetaData(ZipEntry source)
-        {
-            this.__FileDataPosition = source.__FileDataPosition;
-            this.CompressionMethod = source.CompressionMethod;
-            this._CompressionMethod_FromZipFile = source._CompressionMethod_FromZipFile;
-            this._CompressedFileDataSize = source._CompressedFileDataSize;
-            this._UncompressedSize = source._UncompressedSize;
-            this._BitField = source._BitField;
-            this._Source = source._Source;
-            this._LastModified = source._LastModified;
-            this._Mtime = source._Mtime;
-            this._Atime = source._Atime;
-            this._Ctime = source._Ctime;
-            this._ntfsTimesAreSet = source._ntfsTimesAreSet;
-            this._emitUnixTimes = source._emitUnixTimes;
-            this._emitNtfsTimes = source._emitNtfsTimes;
-        }
-
-
-        private void OnWriteBlock(Int64 bytesXferred, Int64 totalBytesToXfer)
-        {
-            if (_container.ZipFile != null)
-                _ioOperationCanceled = _container.ZipFile.OnSaveBlock(this, bytesXferred, totalBytesToXfer);
-        }
-
-
-
-        private void _WriteEntryData(Stream s)
-        {
-            // Read in the data from the input stream (often a file in the filesystem),
-            // and write it to the output stream, calculating a CRC on it as we go.
-            // We will also compress and encrypt as necessary.
-
-            Stream input = null;
-            long fdp = -1L;
-            try
-            {
-                // Want to record the position in the zip file of the zip entry
-                // data (as opposed to the metadata).  s.Position may fail on some
-                // write-only streams, eg stdout or System.Web.HttpResponseStream.
-                // We swallow that exception, because we don't care, in that case.
-                // But, don't set __FileDataPosition directly.  It may be needed
-                // to READ the zip entry from the zip file, if this is a
-                // "re-stream" situation. In other words if the zip entry has
-                // changed compression level, or compression method, or (maybe?)
-                // encryption algorithm.  In that case if the original entry is
-                // encrypted, we need __FileDataPosition to be the value for the
-                // input zip file.  This s.Position is for the output zipfile.  So
-                // we copy fdp to __FileDataPosition after this entry has been
-                // (maybe) restreamed.
-                fdp = s.Position;
-            }
-            catch (Exception) { }
-
-            try
-            {
-                // Use fileLength for progress updates, and to decide whether we can
-                // skip encryption and compression altogether (in case of length==zero)
-                long fileLength = SetInputAndFigureFileLength(ref input);
-
-                // Wrap a counting stream around the raw output stream:
-                // This is the last thing that happens before the bits go to the
-                // application-provided stream.
-                //
-                // Sometimes s is a CountingStream. Doesn't matter. Wrap it with a
-                // counter anyway. We need to count at both levels.
-
-                CountingStream entryCounter = new CountingStream(s);
-
-                Stream encryptor;
-                Stream compressor;
-
-                if (fileLength != 0L)
-                {
-                    // Maybe wrap an encrypting stream around the counter: This will
-                    // happen BEFORE output counting, and AFTER compression, if encryption
-                    // is used.
-                    encryptor = MaybeApplyEncryption(entryCounter);
-
-                    // Maybe wrap a compressing Stream around that.
-                    // This will happen BEFORE encryption (if any) as we write data out.
-                    compressor = MaybeApplyCompression(encryptor, fileLength);
-                }
-                else
-                {
-                    encryptor = compressor = entryCounter;
-                }
-
-                // Wrap a CrcCalculatorStream around that.
-                // This will happen BEFORE compression (if any) as we write data out.
-                var output = new Ionic.Crc.CrcCalculatorStream(compressor, true);
-
-                // output.Write() causes this flow:
-                // calc-crc -> compress -> encrypt -> count -> actually write
-
-                if (this._Source == ZipEntrySource.WriteDelegate)
-                {
-                    // allow the application to write the data
-                    this._WriteDelegate(this.FileName, output);
-                }
-                else
-                {
-                    // synchronously copy the input stream to the output stream-chain
-                    byte[] buffer = new byte[BufferSize];
-                    int n;
-                    while ((n = SharedUtilities.ReadWithRetry(input, buffer, 0, buffer.Length, FileName)) != 0)
-                    {
-                        output.Write(buffer, 0, n);
-                        OnWriteBlock(output.TotalBytesSlurped, fileLength);
-                        if (_ioOperationCanceled)
-                            break;
-                    }
-                }
-
-                FinishOutputStream(s, entryCounter, encryptor, compressor, output);
-            }
-            finally
-            {
-                if (this._Source == ZipEntrySource.JitStream)
-                {
-                    // allow the application to close the stream
-                    if (this._CloseDelegate != null)
-                        this._CloseDelegate(this.FileName, input);
-                }
-                else if ((input as FileStream) != null)
-                {
-#if NETCF
-                    input.Close();
-#else
-                    input.Dispose();
-#endif
-                }
-            }
-
-            if (_ioOperationCanceled)
-                return;
-
-            // set FDP now, to allow for re-streaming
-            this.__FileDataPosition = fdp;
-            PostProcessOutput(s);
-        }
-
-
-        /// <summary>
-        ///   Set the input stream and get its length, if possible.  The length is
-        ///   used for progress updates, AND, to allow an optimization in case of
-        ///   a stream/file of zero length. In that case we skip the Encrypt and
-        ///   compression Stream. (like DeflateStream or BZip2OutputStream)
-        /// </summary>
-        private long SetInputAndFigureFileLength(ref Stream input)
-        {
-            long fileLength = -1L;
-            // get the original stream:
-            if (this._Source == ZipEntrySource.Stream)
-            {
-                PrepSourceStream();
-                input = this._sourceStream;
-
-                // Try to get the length, no big deal if not available.
-                try { fileLength = this._sourceStream.Length; }
-                catch (NotSupportedException) { }
-            }
-            else if (this._Source == ZipEntrySource.ZipFile)
-            {
-                // we are "re-streaming" the zip entry.
-                string pwd = (_Encryption_FromZipFile == EncryptionAlgorithm.None) ? null : (this._Password ?? this._container.Password);
-                this._sourceStream = InternalOpenReader(pwd);
-                PrepSourceStream();
-                input = this._sourceStream;
-                fileLength = this._sourceStream.Length;
-            }
-            else if (this._Source == ZipEntrySource.JitStream)
-            {
-                // allow the application to open the stream
-                if (this._sourceStream == null) _sourceStream = this._OpenDelegate(this.FileName);
-                PrepSourceStream();
-                input = this._sourceStream;
-                try { fileLength = this._sourceStream.Length; }
-                catch (NotSupportedException) { }
-            }
-            else if (this._Source == ZipEntrySource.FileSystem)
-            {
-                // workitem 7145
-                FileShare fs = FileShare.ReadWrite;
-#if !NETCF
-                // FileShare.Delete is not defined for the Compact Framework
-                fs |= FileShare.Delete;
-#endif
-                // workitem 8423
-                input = File.Open(LocalFileName, FileMode.Open, FileAccess.Read, fs);
-                fileLength = input.Length;
-            }
-
-            return fileLength;
-        }
-
-
-
-        internal void FinishOutputStream(Stream s,
-                                         CountingStream entryCounter,
-                                         Stream encryptor,
-                                         Stream compressor,
-                                         Ionic.Crc.CrcCalculatorStream output)
-        {
-            if (output == null) return;
-
-            output.Close();
-
-            // by calling Close() on the deflate stream, we write the footer bytes, as necessary.
-            if ((compressor as Ionic.Zlib.DeflateStream) != null)
-                compressor.Close();
-#if BZIP
-            else if ((compressor as Ionic.BZip2.BZip2OutputStream) != null)
-                compressor.Close();
-#if !NETCF
-            else if ((compressor as Ionic.BZip2.ParallelBZip2OutputStream) != null)
-                compressor.Close();
-#endif
-#endif
-
-#if !NETCF
-            else if ((compressor as Ionic.Zlib.ParallelDeflateOutputStream) != null)
-                compressor.Close();
-#endif
-
-            encryptor.Flush();
-            encryptor.Close();
-
-            _LengthOfTrailer = 0;
-
-            _UncompressedSize = output.TotalBytesSlurped;
-
-#if AESCRYPTO
-            WinZipAesCipherStream wzacs = encryptor as WinZipAesCipherStream;
-            if (wzacs != null && _UncompressedSize > 0)
-            {
-                s.Write(wzacs.FinalAuthentication, 0, 10);
-                _LengthOfTrailer += 10;
-            }
-#endif
-            _CompressedFileDataSize = entryCounter.BytesWritten;
-            _CompressedSize = _CompressedFileDataSize;   // may be adjusted
-            _Crc32 = output.Crc;
-
-            // Set _RelativeOffsetOfLocalHeader now, to allow for re-streaming
-            StoreRelativeOffset();
-        }
-
-
-
-
-        internal void PostProcessOutput(Stream s)
-        {
-            var s1 = s as CountingStream;
-
-            // workitem 8931 - for WriteDelegate.
-            // The WriteDelegate changes things because there can be a zero-byte stream
-            // written. In all other cases DotNetZip knows the length of the stream
-            // before compressing and encrypting. In this case we have to circle back,
-            // and omit all the crypto stuff - the GP bitfield, and the crypto header.
-            if (_UncompressedSize == 0 && _CompressedSize == 0)
-            {
-                if (this._Source == ZipEntrySource.ZipOutputStream) return;  // nothing to do...
-
-                if (_Password != null)
-                {
-                    int headerBytesToRetract = 0;
-                    if (Encryption == EncryptionAlgorithm.PkzipWeak)
-                        headerBytesToRetract = 12;
-#if AESCRYPTO
-                    else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                             Encryption == EncryptionAlgorithm.WinZipAes256)
-                    {
-                        headerBytesToRetract = _aesCrypto_forWrite._Salt.Length + _aesCrypto_forWrite.GeneratedPV.Length;
-                    }
-#endif
-                    if (this._Source == ZipEntrySource.ZipOutputStream && !s.CanSeek)
-                        throw new ZipException("Zero bytes written, encryption in use, and non-seekable output.");
-
-                    if (Encryption != EncryptionAlgorithm.None)
-                    {
-                        // seek back in the stream to un-output the security metadata
-                        s.Seek(-1 * headerBytesToRetract, SeekOrigin.Current);
-                        s.SetLength(s.Position);
-                        // workitem 10178
-                        Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-
-                        // workitem 11131
-                        // adjust the count on the CountingStream as necessary
-                        if (s1 != null) s1.Adjust(headerBytesToRetract);
-
-                        // subtract the size of the security header from the _LengthOfHeader
-                        _LengthOfHeader -= headerBytesToRetract;
-                        __FileDataPosition -= headerBytesToRetract;
-                    }
-                    _Password = null;
-
-                    // turn off the encryption bit
-                    _BitField &= ~(0x0001);
-
-                    // copy the updated bitfield value into the header
-                    int j = 6;
-                    _EntryHeader[j++] = (byte)(_BitField & 0x00FF);
-                    _EntryHeader[j++] = (byte)((_BitField & 0xFF00) >> 8);
-
-#if AESCRYPTO
-                    if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                        Encryption == EncryptionAlgorithm.WinZipAes256)
-                    {
-                        // Fix the extra field - overwrite the 0x9901 headerId
-                        // with dummy data. (arbitrarily, 0x9999)
-                        Int16 fnLength = (short)(_EntryHeader[26] + _EntryHeader[27] * 256);
-                        int offx = 30 + fnLength;
-                        int aesIndex = FindExtraFieldSegment(_EntryHeader, offx, 0x9901);
-                        if (aesIndex >= 0)
-                        {
-                            _EntryHeader[aesIndex++] = 0x99;
-                            _EntryHeader[aesIndex++] = 0x99;
-                        }
-                    }
-#endif
-                }
-
-                CompressionMethod = 0;
-                Encryption = EncryptionAlgorithm.None;
-            }
-            else if (_zipCrypto_forWrite != null
-#if AESCRYPTO
-                     || _aesCrypto_forWrite != null
-#endif
-                     )
-
-            {
-                if (Encryption == EncryptionAlgorithm.PkzipWeak)
-                {
-                    _CompressedSize += 12; // 12 extra bytes for the encryption header
-                }
-#if AESCRYPTO
-                else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                         Encryption == EncryptionAlgorithm.WinZipAes256)
-                {
-                    // adjust the compressed size to include the variable (salt+pv)
-                    // security header and 10-byte trailer. According to the winzip AES
-                    // spec, that metadata is included in the "Compressed Size" figure
-                    // when encoding the zip archive.
-                    _CompressedSize += _aesCrypto_forWrite.SizeOfEncryptionMetadata;
-                }
-#endif
-            }
-
-            int i = 8;
-            _EntryHeader[i++] = (byte)(_CompressionMethod & 0x00FF);
-            _EntryHeader[i++] = (byte)((_CompressionMethod & 0xFF00) >> 8);
-
-            i = 14;
-            // CRC - the correct value now
-            _EntryHeader[i++] = (byte)(_Crc32 & 0x000000FF);
-            _EntryHeader[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8);
-            _EntryHeader[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16);
-            _EntryHeader[i++] = (byte)((_Crc32 & 0xFF000000) >> 24);
-
-            SetZip64Flags();
-
-            // (i==26) filename length (Int16)
-            Int16 filenameLength = (short)(_EntryHeader[26] + _EntryHeader[27] * 256);
-            Int16 extraFieldLength = (short)(_EntryHeader[28] + _EntryHeader[29] * 256);
-
-            if (_OutputUsesZip64.Value)
-            {
-                // VersionNeededToExtract - set to 45 to indicate zip64
-                _EntryHeader[4] = (byte)(45 & 0x00FF);
-                _EntryHeader[5] = 0x00;
-
-                // workitem 7924 - don't need bit 3
-                // // workitem 7917
-                // // set bit 3 for ZIP64 compatibility with WinZip12
-                // _BitField |= 0x0008;
-                // _EntryHeader[6] = (byte)(_BitField & 0x00FF);
-
-                // CompressedSize and UncompressedSize - 0xFF
-                for (int j = 0; j < 8; j++)
-                    _EntryHeader[i++] = 0xff;
-
-                // At this point we need to find the "Extra field" that follows the
-                // filename.  We had already emitted it, but the data (uncomp, comp,
-                // ROLH) was not available at the time we did so.  Here, we emit it
-                // again, with final values.
-
-                i = 30 + filenameLength;
-                _EntryHeader[i++] = 0x01;  // zip64
-                _EntryHeader[i++] = 0x00;
-
-                i += 2; // skip over data size, which is 16+4
-
-                Array.Copy(BitConverter.GetBytes(_UncompressedSize), 0, _EntryHeader, i, 8);
-                i += 8;
-                Array.Copy(BitConverter.GetBytes(_CompressedSize), 0, _EntryHeader, i, 8);
-            }
-            else
-            {
-                // VersionNeededToExtract - reset to 20 since no zip64
-                _EntryHeader[4] = (byte)(20 & 0x00FF);
-                _EntryHeader[5] = 0x00;
-
-                // CompressedSize - the correct value now
-                i = 18;
-                _EntryHeader[i++] = (byte)(_CompressedSize & 0x000000FF);
-                _EntryHeader[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
-                _EntryHeader[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
-                _EntryHeader[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
-                // UncompressedSize - the correct value now
-                _EntryHeader[i++] = (byte)(_UncompressedSize & 0x000000FF);
-                _EntryHeader[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
-                _EntryHeader[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
-                _EntryHeader[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
-
-                // The HeaderId in the extra field header, is already dummied out.
-                if (extraFieldLength != 0)
-                {
-                    i = 30 + filenameLength;
-                    // For zip archives written by this library, if the zip64
-                    // header exists, it is the first header. Because of the logic
-                    // used when first writing the _EntryHeader bytes, the
-                    // HeaderId is not guaranteed to be any particular value.  So
-                    // we determine if the first header is a putative zip64 header
-                    // by examining the datasize.  UInt16 HeaderId =
-                    // (UInt16)(_EntryHeader[i] + _EntryHeader[i + 1] * 256);
-                    Int16 DataSize = (short)(_EntryHeader[i + 2] + _EntryHeader[i + 3] * 256);
-                    if (DataSize == 16)
-                    {
-                        // reset to Header Id to dummy value, effectively dummy-ing out the zip64 metadata
-                        _EntryHeader[i++] = 0x99;
-                        _EntryHeader[i++] = 0x99;
-                    }
-                }
-            }
-
-
-#if AESCRYPTO
-
-            if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                // Must set compressionmethod to 0x0063 (decimal 99)
-                //
-                // and then set the compression method bytes inside the extra
-                // field to the actual compression method value.
-
-                i = 8;
-                _EntryHeader[i++] = 0x63;
-                _EntryHeader[i++] = 0;
-
-                i = 30 + filenameLength;
-                do
-                {
-                    UInt16 HeaderId = (UInt16)(_EntryHeader[i] + _EntryHeader[i + 1] * 256);
-                    Int16 DataSize = (short)(_EntryHeader[i + 2] + _EntryHeader[i + 3] * 256);
-                    if (HeaderId != 0x9901)
-                    {
-                        // skip this header
-                        i += DataSize + 4;
-                    }
-                    else
-                    {
-                        i += 9;
-                        // actual compression method
-                        _EntryHeader[i++] = (byte)(_CompressionMethod & 0x00FF);
-                        _EntryHeader[i++] = (byte)(_CompressionMethod & 0xFF00);
-                    }
-                } while (i < (extraFieldLength - 30 - filenameLength));
-            }
-#endif
-
-            // finally, write the data.
-
-            // workitem 7216 - sometimes we don't seek even if we CAN.  ASP.NET
-            // Response.OutputStream, or stdout are non-seekable.  But we may also want
-            // to NOT seek in other cases, eg zip64.  For all cases, we just check bit 3
-            // to see if we want to seek.  There's one exception - if using a
-            // ZipOutputStream, and PKZip encryption is in use, then we set bit 3 even
-            // if the out is seekable. This is so the check on the last byte of the
-            // PKZip Encryption Header can be done on the current time, as opposed to
-            // the CRC, to prevent streaming the file twice.  So, test for
-            // ZipOutputStream and seekable, and if so, seek back, even if bit 3 is set.
-
-            if ((_BitField & 0x0008) != 0x0008 ||
-                 (this._Source == ZipEntrySource.ZipOutputStream && s.CanSeek))
-            {
-                // seek back and rewrite the entry header
-                var zss = s as ZipSegmentedStream;
-                if (zss != null && _diskNumber != zss.CurrentSegment)
-                {
-                    // In this case the entry header is in a different file,
-                    // which has already been closed. Need to re-open it.
-                    using (Stream hseg = ZipSegmentedStream.ForUpdate(this._container.ZipFile.Name, _diskNumber))
-                    {
-                        hseg.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-                        hseg.Write(_EntryHeader, 0, _EntryHeader.Length);
-                    }
-                }
-                else
-                {
-                    // seek in the raw output stream, to the beginning of the header for
-                    // this entry.
-                    // workitem 8098: ok (output)
-                    s.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
-                    // write the updated header to the output stream
-                    s.Write(_EntryHeader, 0, _EntryHeader.Length);
-
-                    // adjust the count on the CountingStream as necessary
-                    if (s1 != null) s1.Adjust(_EntryHeader.Length);
-
-                    // seek in the raw output stream, to the end of the file data
-                    // for this entry
-                    s.Seek(_CompressedSize, SeekOrigin.Current);
-                }
-            }
-
-            // emit the descriptor - only if not a directory.
-            if (((_BitField & 0x0008) == 0x0008) && !IsDirectory)
-            {
-                byte[] Descriptor = new byte[16 + (_OutputUsesZip64.Value ? 8 : 0)];
-                i = 0;
-
-                // signature
-                Array.Copy(BitConverter.GetBytes(ZipConstants.ZipEntryDataDescriptorSignature), 0, Descriptor, i, 4);
-                i += 4;
-
-                // CRC - the correct value now
-                Array.Copy(BitConverter.GetBytes(_Crc32), 0, Descriptor, i, 4);
-                i += 4;
-
-                // workitem 7917
-                if (_OutputUsesZip64.Value)
-                {
-                    // CompressedSize - the correct value now
-                    Array.Copy(BitConverter.GetBytes(_CompressedSize), 0, Descriptor, i, 8);
-                    i += 8;
-
-                    // UncompressedSize - the correct value now
-                    Array.Copy(BitConverter.GetBytes(_UncompressedSize), 0, Descriptor, i, 8);
-                    i += 8;
-                }
-                else
-                {
-                    // CompressedSize - (lower 32 bits) the correct value now
-                    Descriptor[i++] = (byte)(_CompressedSize & 0x000000FF);
-                    Descriptor[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
-                    Descriptor[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
-                    Descriptor[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
-                    // UncompressedSize - (lower 32 bits) the correct value now
-                    Descriptor[i++] = (byte)(_UncompressedSize & 0x000000FF);
-                    Descriptor[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
-                    Descriptor[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
-                    Descriptor[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
-                }
-
-                // finally, write the trailing descriptor to the output stream
-                s.Write(Descriptor, 0, Descriptor.Length);
-
-                _LengthOfTrailer += Descriptor.Length;
-            }
-        }
-
-
-
-        private void SetZip64Flags()
-        {
-            // zip64 housekeeping
-            _entryRequiresZip64 = new Nullable<bool>
-                (_CompressedSize >= 0xFFFFFFFF || _UncompressedSize >= 0xFFFFFFFF || _RelativeOffsetOfLocalHeader >= 0xFFFFFFFF);
-
-            // validate the ZIP64 usage
-            if (_container.Zip64 == Zip64Option.Never && _entryRequiresZip64.Value)
-                throw new ZipException("Compressed or Uncompressed size, or offset exceeds the maximum value. Consider setting the UseZip64WhenSaving property on the ZipFile instance.");
-
-            _OutputUsesZip64 = new Nullable<bool>(_container.Zip64 == Zip64Option.Always || _entryRequiresZip64.Value);
-        }
-
-
-
-        /// <summary>
-        ///   Prepare the given stream for output - wrap it in a CountingStream, and
-        ///   then in a CRC stream, and an encryptor and deflator as appropriate.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Previously this was used in ZipEntry.Write(), but in an effort to
-        ///     introduce some efficiencies in that method I've refactored to put the
-        ///     code inline.  This method still gets called by ZipOutputStream.
-        ///   </para>
-        /// </remarks>
-        internal void PrepOutputStream(Stream s,
-                                       long streamLength,
-                                       out CountingStream outputCounter,
-                                       out Stream encryptor,
-                                       out Stream compressor,
-                                       out Ionic.Crc.CrcCalculatorStream output)
-        {
-            TraceWriteLine("PrepOutputStream: e({0}) comp({1}) crypto({2}) zf({3})",
-                           FileName,
-                           CompressionLevel,
-                           Encryption,
-                           _container.Name);
-
-            // Wrap a counting stream around the raw output stream:
-            // This is the last thing that happens before the bits go to the
-            // application-provided stream.
-            outputCounter = new CountingStream(s);
-
-            // Sometimes the incoming "raw" output stream is already a CountingStream.
-            // Doesn't matter. Wrap it with a counter anyway. We need to count at both
-            // levels.
-
-            if (streamLength != 0L)
-            {
-                // Maybe wrap an encrypting stream around that:
-                // This will happen BEFORE output counting, and AFTER deflation, if encryption
-                // is used.
-                encryptor = MaybeApplyEncryption(outputCounter);
-
-                // Maybe wrap a compressing Stream around that.
-                // This will happen BEFORE encryption (if any) as we write data out.
-                compressor = MaybeApplyCompression(encryptor, streamLength);
-            }
-            else
-            {
-                encryptor = compressor = outputCounter;
-            }
-            // Wrap a CrcCalculatorStream around that.
-            // This will happen BEFORE compression (if any) as we write data out.
-            output = new Ionic.Crc.CrcCalculatorStream(compressor, true);
-        }
-
-
-
-        private Stream MaybeApplyCompression(Stream s, long streamLength)
-        {
-            if (_CompressionMethod == 0x08 && CompressionLevel != Ionic.Zlib.CompressionLevel.None)
-            {
-#if !NETCF
-                // ParallelDeflateThreshold == 0    means ALWAYS use parallel deflate
-                // ParallelDeflateThreshold == -1L  means NEVER use parallel deflate
-                // Other values specify the actual threshold.
-                if (_container.ParallelDeflateThreshold == 0L ||
-                    (streamLength > _container.ParallelDeflateThreshold &&
-                     _container.ParallelDeflateThreshold > 0L))
-                {
-                    // This is sort of hacky.
-                    //
-                    // It's expensive to create a ParallelDeflateOutputStream, because
-                    // of the large memory buffers.  But the class is unlike most Stream
-                    // classes in that it can be re-used, so the caller can compress
-                    // multiple files with it, one file at a time.  The key is to call
-                    // Reset() on it, in between uses.
-                    //
-                    // The ParallelDeflateOutputStream is attached to the container
-                    // itself - there is just one for the entire ZipFile or
-                    // ZipOutputStream. So it gets created once, per save, and then
-                    // re-used many times.
-                    //
-                    // This approach will break when we go to a "parallel save"
-                    // approach, where multiple entries within the zip file are being
-                    // compressed and saved at the same time.  But for now it's ok.
-                    //
-
-                    // instantiate the ParallelDeflateOutputStream
-                    if (_container.ParallelDeflater == null)
-                    {
-                        _container.ParallelDeflater =
-                            new ParallelDeflateOutputStream(s,
-                                                                        CompressionLevel,
-                                                                       _container.Strategy,
-                                                                       true);
-                        // can set the codec buffer size only before the first call to Write().
-                        if (_container.CodecBufferSize > 0)
-                            _container.ParallelDeflater.BufferSize = _container.CodecBufferSize;
-                        if (_container.ParallelDeflateMaxBufferPairs > 0)
-                            _container.ParallelDeflater.MaxBufferPairs =
-                                _container.ParallelDeflateMaxBufferPairs;
-                    }
-                    // reset it with the new stream
-                    Ionic.Zlib.ParallelDeflateOutputStream o1 = _container.ParallelDeflater;
-                    o1.Reset(s);
-                    return o1;
-                }
-#endif
-                var o = new DeflateStream(s, OfficeOpenXml.Packaging.Ionic.Zlib.CompressionMode.Compress,
-                                                     CompressionLevel,
-                                                     true);
-                if (_container.CodecBufferSize > 0)
-                    o.BufferSize = _container.CodecBufferSize;
-                o.Strategy = _container.Strategy;
-                return o;
-            }
-
-
-#if BZIP
-            if (_CompressionMethod == 0x0c)
-            {
-#if !NETCF
-                if (_container.ParallelDeflateThreshold == 0L ||
-                    (streamLength > _container.ParallelDeflateThreshold &&
-                     _container.ParallelDeflateThreshold > 0L))
-                {
-
-                    var o1 = new Ionic.BZip2.ParallelBZip2OutputStream(s, true);
-                    return o1;
-                }
-#endif
-                var o = new Ionic.BZip2.BZip2OutputStream(s, true);
-                return o;
-            }
-#endif
-
-            return s;
-        }
-
-
-
-        private Stream MaybeApplyEncryption(Stream s)
-        {
-            if (Encryption == EncryptionAlgorithm.PkzipWeak)
-            {
-                TraceWriteLine("MaybeApplyEncryption: e({0}) PKZIP", FileName);
-
-                return new ZipCipherStream(s, _zipCrypto_forWrite, CryptoMode.Encrypt);
-            }
-#if AESCRYPTO
-            if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                     Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                TraceWriteLine("MaybeApplyEncryption: e({0}) AES", FileName);
-
-                return new WinZipAesCipherStream(s, _aesCrypto_forWrite, CryptoMode.Encrypt);
-            }
-#endif
-            TraceWriteLine("MaybeApplyEncryption: e({0}) None", FileName);
-
-            return s;
-        }
-
-
-
-        private void OnZipErrorWhileSaving(Exception e)
-        {
-            if (_container.ZipFile != null)
-                _ioOperationCanceled = _container.ZipFile.OnZipErrorSaving(this, e);
-        }
-
-
-
-        internal void Write(Stream s)
-        {
-            var cs1 = s as CountingStream;
-            var zss1 = s as ZipSegmentedStream;
-
-            bool done = false;
-            do
-            {
-                try
-                {
-                    // When the app is updating a zip file, it may be possible to
-                    // just copy data for a ZipEntry from the source zipfile to the
-                    // destination, as a block, without decompressing and
-                    // recompressing, etc.  But, in some cases the app modifies the
-                    // properties on a ZipEntry prior to calling Save(). A change to
-                    // any of the metadata - the FileName, CompressioLeve and so on,
-                    // means DotNetZip cannot simply copy through the existing
-                    // ZipEntry data unchanged.
-                    //
-                    // There are two cases:
-                    //
-                    //  1. Changes to only metadata, which means the header and
-                    //     central directory must be changed.
-                    //
-                    //  2. Changes to the properties that affect the compressed
-                    //     stream, such as CompressionMethod, CompressionLevel, or
-                    //     EncryptionAlgorithm. In this case, DotNetZip must
-                    //     "re-stream" the data: the old entry data must be maybe
-                    //     decrypted, maybe decompressed, then maybe re-compressed
-                    //     and maybe re-encrypted.
-                    //
-                    // This test checks if the source for the entry data is a zip file, and
-                    // if a restream is necessary.  If NOT, then it just copies through
-                    // one entry, potentially changing the metadata.
-
-                    if (_Source == ZipEntrySource.ZipFile && !_restreamRequiredOnSave)
-                    {
-                        CopyThroughOneEntry(s);
-                        return;
-                    }
-
-                    // Is the entry a directory?  If so, the write is relatively simple.
-                    if (IsDirectory)
-                    {
-                        WriteHeader(s, 1);
-                        StoreRelativeOffset();
-                        _entryRequiresZip64 = new Nullable<bool>(_RelativeOffsetOfLocalHeader >= 0xFFFFFFFF);
-                        _OutputUsesZip64 = new Nullable<bool>(_container.Zip64 == Zip64Option.Always || _entryRequiresZip64.Value);
-                        // handle case for split archives
-                        if (zss1 != null)
-                            _diskNumber = zss1.CurrentSegment;
-
-                        return;
-                    }
-
-                    // At this point, the source for this entry is not a directory, and
-                    // not a previously created zip file, or the source for the entry IS
-                    // a previously created zip but the settings whave changed in
-                    // important ways and therefore we will need to process the
-                    // bytestream (compute crc, maybe compress, maybe encrypt) in order
-                    // to write the content into the new zip.
-                    //
-                    // We do this in potentially 2 passes: The first time we do it as
-                    // requested, maybe with compression and maybe encryption.  If that
-                    // causes the bytestream to inflate in size, and if compression was
-                    // on, then we turn off compression and do it again.
-
-
-                    bool readAgain = true;
-                    int nCycles = 0;
-                    do
-                    {
-                        nCycles++;
-
-                        WriteHeader(s, nCycles);
-
-                        // write the encrypted header
-                        WriteSecurityMetadata(s);
-
-                        // write the (potentially compressed, potentially encrypted) file data
-                        _WriteEntryData(s);
-
-                        // track total entry size (including the trailing descriptor and MAC)
-                        _TotalEntrySize = _LengthOfHeader + _CompressedFileDataSize + _LengthOfTrailer;
-
-                        // The file data has now been written to the stream, and
-                        // the file pointer is positioned directly after file data.
-
-                        if (nCycles > 1) readAgain = false;
-                        else if (!s.CanSeek) readAgain = false;
-                        else readAgain = WantReadAgain();
-
-                        if (readAgain)
-                        {
-                            // Seek back in the raw output stream, to the beginning of the file
-                            // data for this entry.
-
-                            // handle case for split archives
-                            if (zss1 != null)
-                            {
-                                // Console.WriteLine("***_diskNumber/first: {0}", _diskNumber);
-                                // Console.WriteLine("***_diskNumber/current: {0}", zss.CurrentSegment);
-                                zss1.TruncateBackward(_diskNumber, _RelativeOffsetOfLocalHeader);
-                            }
-                            else
-                                // workitem 8098: ok (output).
-                                s.Seek(_RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
-                            // If the last entry expands, we read again; but here, we must
-                            // truncate the stream to prevent garbage data after the
-                            // end-of-central-directory.
-
-                            // workitem 8098: ok (output).
-                            s.SetLength(s.Position);
-
-                            // Adjust the count on the CountingStream as necessary.
-                            if (cs1 != null) cs1.Adjust(_TotalEntrySize);
-                        }
-                    }
-                    while (readAgain);
-                    _skippedDuringSave = false;
-                    done = true;
-                }
-                catch (System.Exception exc1)
-                {
-                    ZipErrorAction orig = this.ZipErrorAction;
-                    int loop = 0;
-                    do
-                    {
-                        if (ZipErrorAction == ZipErrorAction.Throw)
-                            throw;
-
-                        if (ZipErrorAction == ZipErrorAction.Skip ||
-                            ZipErrorAction == ZipErrorAction.Retry)
-                        {
-                            // must reset file pointer here.
-                            // workitem 13903 - seek back only when necessary
-                            long p1 = (cs1 != null)
-                                ? cs1.ComputedPosition
-                                : s.Position;
-                            long delta = p1 - _future_ROLH;
-                            if (delta > 0)
-                            {
-                                s.Seek(delta, SeekOrigin.Current); // may throw
-                                long p2 = s.Position;
-                                s.SetLength(s.Position);  // to prevent garbage if this is the last entry
-                                if (cs1 != null) cs1.Adjust(p1 - p2);
-                            }
-                            if (ZipErrorAction == ZipErrorAction.Skip)
-                            {
-                                WriteStatus("Skipping file {0} (exception: {1})", LocalFileName, exc1.ToString());
-
-                                _skippedDuringSave = true;
-                                done = true;
-                            }
-                            else
-                                this.ZipErrorAction = orig;
-                            break;
-                        }
-
-                        if (loop > 0) throw;
-
-                        if (ZipErrorAction == ZipErrorAction.InvokeErrorEvent)
-                        {
-                            OnZipErrorWhileSaving(exc1);
-                            if (_ioOperationCanceled)
-                            {
-                                done = true;
-                                break;
-                            }
-                        }
-                        loop++;
-                    }
-                    while (true);
-                }
-            }
-            while (!done);
-        }
-
-
-        internal void StoreRelativeOffset()
-        {
-            _RelativeOffsetOfLocalHeader = _future_ROLH;
-        }
-
-
-
-        internal void NotifySaveComplete()
-        {
-            // When updating a zip file, there are two contexts for properties
-            // like Encryption or CompressionMethod - the values read from the
-            // original zip file, and the values used in the updated zip file.
-            // The _FromZipFile versions are the originals.  At the end of a save,
-            // these values are the same.  So we need to update them.  This takes
-            // care of the boundary case where a single zipfile instance can be
-            // saved multiple times, with distinct changes to the properties on
-            // the entries, in between each Save().
-            _Encryption_FromZipFile = _Encryption;
-            _CompressionMethod_FromZipFile = _CompressionMethod;
-            _restreamRequiredOnSave = false;
-            _metadataChanged = false;
-            //_Source = ZipEntrySource.None;
-            _Source = ZipEntrySource.ZipFile; // workitem 10694
-        }
-
-
-        internal void WriteSecurityMetadata(Stream outstream)
-        {
-            if (Encryption == EncryptionAlgorithm.None)
-                return;
-
-            string pwd = this._Password;
-
-            // special handling for source == ZipFile.
-            // Want to support the case where we re-stream an encrypted entry. This will involve,
-            // at runtime, reading, decrypting, and decompressing from the original zip file, then
-            // compressing, encrypting, and writing to the output zip file.
-
-            // If that's what we're doing, and the password hasn't been set on the entry,
-            // we use the container (ZipFile/ZipOutputStream) password to decrypt.
-            // This test here says to use the container password to re-encrypt, as well,
-            // with that password, if the entry password is null.
-
-            if (this._Source == ZipEntrySource.ZipFile && pwd == null)
-                pwd = this._container.Password;
-
-            if (pwd == null)
-            {
-                _zipCrypto_forWrite = null;
-#if AESCRYPTO
-                _aesCrypto_forWrite = null;
-#endif
-                return;
-            }
-
-            TraceWriteLine("WriteSecurityMetadata: e({0}) crypto({1}) pw({2})",
-                           FileName, Encryption.ToString(), pwd);
-
-            if (Encryption == EncryptionAlgorithm.PkzipWeak)
-            {
-                // If PKZip (weak) encryption is in use, then the encrypted entry data
-                // is preceded by 12-byte "encryption header" for the entry.
-
-                _zipCrypto_forWrite = ZipCrypto.ForWrite(pwd);
-
-                // generate the random 12-byte header:
-                var rnd = new System.Random();
-                byte[] encryptionHeader = new byte[12];
-                rnd.NextBytes(encryptionHeader);
-
-                // workitem 8271
-                if ((this._BitField & 0x0008) == 0x0008)
-                {
-                    // In the case that bit 3 of the general purpose bit flag is set to
-                    // indicate the presence of a 'data descriptor' (signature
-                    // 0x08074b50), the last byte of the decrypted header is sometimes
-                    // compared with the high-order byte of the lastmodified time,
-                    // rather than the high-order byte of the CRC, to verify the
-                    // password.
-                    //
-                    // This is not documented in the PKWare Appnote.txt.
-                    // This was discovered this by analysis of the Crypt.c source file in the
-                    // InfoZip library
-                    // http://www.info-zip.org/pub/infozip/
-
-                    // Also, winzip insists on this!
-                    _TimeBlob = Ionic.Zip.SharedUtilities.DateTimeToPacked(LastModified);
-                    encryptionHeader[11] = (byte)((this._TimeBlob >> 8) & 0xff);
-                }
-                else
-                {
-                    // When bit 3 is not set, the CRC value is required before
-                    // encryption of the file data begins. In this case there is no way
-                    // around it: must read the stream in its entirety to compute the
-                    // actual CRC before proceeding.
-                    FigureCrc32();
-                    encryptionHeader[11] = (byte)((this._Crc32 >> 24) & 0xff);
-                }
-
-                // Encrypt the random header, INCLUDING the final byte which is either
-                // the high-order byte of the CRC32, or the high-order byte of the
-                // _TimeBlob.  Must do this BEFORE encrypting the file data.  This
-                // step changes the state of the cipher, or in the words of the PKZIP
-                // spec, it "further initializes" the cipher keys.
-
-                byte[] cipherText = _zipCrypto_forWrite.EncryptMessage(encryptionHeader, encryptionHeader.Length);
-
-                // Write the ciphered bonafide encryption header.
-                outstream.Write(cipherText, 0, cipherText.Length);
-                _LengthOfHeader += cipherText.Length;  // 12 bytes
-            }
-
-#if AESCRYPTO
-            else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
-                Encryption == EncryptionAlgorithm.WinZipAes256)
-            {
-                // If WinZip AES encryption is in use, then the encrypted entry data is
-                // preceded by a variable-sized Salt and a 2-byte "password
-                // verification" value for the entry.
-
-                int keystrength = GetKeyStrengthInBits(Encryption);
-                _aesCrypto_forWrite = WinZipAesCrypto.Generate(pwd, keystrength);
-                outstream.Write(_aesCrypto_forWrite.Salt, 0, _aesCrypto_forWrite._Salt.Length);
-                outstream.Write(_aesCrypto_forWrite.GeneratedPV, 0, _aesCrypto_forWrite.GeneratedPV.Length);
-                _LengthOfHeader += _aesCrypto_forWrite._Salt.Length + _aesCrypto_forWrite.GeneratedPV.Length;
-
-                TraceWriteLine("WriteSecurityMetadata: AES e({0}) keybits({1}) _LOH({2})",
-                               FileName, keystrength, _LengthOfHeader);
-
-            }
-#endif
-
-        }
-
-
-
-        private void CopyThroughOneEntry(Stream outStream)
-        {
-            // Just read the entry from the existing input zipfile and write to the output.
-            // But, if metadata has changed (like file times or attributes), or if the ZIP64
-            // option has changed, we can re-stream the entry data but must recompute the
-            // metadata.
-            if (this.LengthOfHeader == 0)
-                throw new BadStateException("Bad header length.");
-
-            // is it necessary to re-constitute new metadata for this entry?
-            bool needRecompute = _metadataChanged ||
-                (this.ArchiveStream is ZipSegmentedStream) ||
-                (outStream is ZipSegmentedStream) ||
-                (_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Never) ||
-                (!_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Always);
-
-            if (needRecompute)
-                CopyThroughWithRecompute(outStream);
-            else
-                CopyThroughWithNoChange(outStream);
-
-            // zip64 housekeeping
-            _entryRequiresZip64 = new Nullable<bool>
-                (_CompressedSize >= 0xFFFFFFFF || _UncompressedSize >= 0xFFFFFFFF ||
-                _RelativeOffsetOfLocalHeader >= 0xFFFFFFFF
-                );
-
-            _OutputUsesZip64 = new Nullable<bool>(_container.Zip64 == Zip64Option.Always || _entryRequiresZip64.Value);
-        }
-
-
-
-        private void CopyThroughWithRecompute(Stream outstream)
-        {
-            int n;
-            byte[] bytes = new byte[BufferSize];
-            var input = new CountingStream(this.ArchiveStream);
-
-            long origRelativeOffsetOfHeader = _RelativeOffsetOfLocalHeader;
-
-            // The header length may change due to rename of file, add a comment, etc.
-            // We need to retain the original.
-            int origLengthOfHeader = LengthOfHeader; // including crypto bytes!
-
-            // WriteHeader() has the side effect of changing _RelativeOffsetOfLocalHeader
-            // and setting _LengthOfHeader.  While ReadHeader() reads the crypto header if
-            // present, WriteHeader() does not write the crypto header.
-            WriteHeader(outstream, 0);
-            StoreRelativeOffset();
-
-            if (!this.FileName.EndsWith("/"))
-            {
-                // Not a directory; there is file data.
-                // Seek to the beginning of the entry data in the input stream.
-
-                long pos = origRelativeOffsetOfHeader + origLengthOfHeader;
-                int len = GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
-                pos -= len; // want to keep the crypto header
-                _LengthOfHeader += len;
-
-                input.Seek(pos, SeekOrigin.Begin);
-
-                // copy through everything after the header to the output stream
-                long remaining = this._CompressedSize;
-
-                while (remaining > 0)
-                {
-                    len = (remaining > bytes.Length) ? bytes.Length : (int)remaining;
-
-                    // read
-                    n = input.Read(bytes, 0, len);
-                    //_CheckRead(n);
-
-                    // write
-                    outstream.Write(bytes, 0, n);
-                    remaining -= n;
-                    OnWriteBlock(input.BytesRead, this._CompressedSize);
-                    if (_ioOperationCanceled)
-                        break;
-                }
-
-                // bit 3 descriptor
-                if ((this._BitField & 0x0008) == 0x0008)
-                {
-                    int size = 16;
-                    if (_InputUsesZip64) size += 8;
-                    byte[] Descriptor = new byte[size];
-                    input.Read(Descriptor, 0, size);
-
-                    if (_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Never)
-                    {
-                        // original descriptor was 24 bytes, now we need 16.
-                        // Must check for underflow here.
-                        // signature + CRC.
-                        outstream.Write(Descriptor, 0, 8);
-
-                        // Compressed
-                        if (_CompressedSize > 0xFFFFFFFF)
-                            throw new InvalidOperationException("ZIP64 is required");
-                        outstream.Write(Descriptor, 8, 4);
-
-                        // UnCompressed
-                        if (_UncompressedSize > 0xFFFFFFFF)
-                            throw new InvalidOperationException("ZIP64 is required");
-                        outstream.Write(Descriptor, 16, 4);
-                        _LengthOfTrailer -= 8;
-                    }
-                    else if (!_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Always)
-                    {
-                        // original descriptor was 16 bytes, now we need 24
-                        // signature + CRC
-                        byte[] pad = new byte[4];
-                        outstream.Write(Descriptor, 0, 8);
-                        // Compressed
-                        outstream.Write(Descriptor, 8, 4);
-                        outstream.Write(pad, 0, 4);
-                        // UnCompressed
-                        outstream.Write(Descriptor, 12, 4);
-                        outstream.Write(pad, 0, 4);
-                        _LengthOfTrailer += 8;
-                    }
-                    else
-                    {
-                        // same descriptor on input and output. Copy it through.
-                        outstream.Write(Descriptor, 0, size);
-                        //_LengthOfTrailer += size;
-                    }
-                }
-            }
-
-            _TotalEntrySize = _LengthOfHeader + _CompressedFileDataSize + _LengthOfTrailer;
-        }
-
-
-        private void CopyThroughWithNoChange(Stream outstream)
-        {
-            int n;
-            byte[] bytes = new byte[BufferSize];
-            var input = new CountingStream(this.ArchiveStream);
-
-            // seek to the beginning of the entry data in the input stream
-            input.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
-            if (this._TotalEntrySize == 0)
-            {
-                // We've never set the length of the entry.
-                // Set it here.
-                this._TotalEntrySize = this._LengthOfHeader + this._CompressedFileDataSize + _LengthOfTrailer;
-
-                // The CompressedSize includes all the leading metadata associated
-                // to encryption, if any, as well as the compressed data, or
-                // compressed-then-encrypted data, and the trailer in case of AES.
-
-                // The CompressedFileData size is the same, less the encryption
-                // framing data (12 bytes header for PKZip; 10/18 bytes header and
-                // 10 byte trailer for AES).
-
-                // The _LengthOfHeader includes all the zip entry header plus the
-                // crypto header, if any.  The _LengthOfTrailer includes the
-                // 10-byte MAC for AES, where appropriate, and the bit-3
-                // Descriptor, where applicable.
-            }
-
-
-            // workitem 5616
-            // remember the offset, within the output stream, of this particular entry header.
-            // This may have changed if any of the other entries changed (eg, if a different
-            // entry was removed or added.)
-            var counter = outstream as CountingStream;
-            _RelativeOffsetOfLocalHeader = (counter != null)
-                ? counter.ComputedPosition
-                : outstream.Position;  // BytesWritten
-
-            // copy through the header, filedata, trailer, everything...
-            long remaining = this._TotalEntrySize;
-            while (remaining > 0)
-            {
-                int len = (remaining > bytes.Length) ? bytes.Length : (int)remaining;
-
-                // read
-                n = input.Read(bytes, 0, len);
-                //_CheckRead(n);
-
-                // write
-                outstream.Write(bytes, 0, n);
-                remaining -= n;
-                OnWriteBlock(input.BytesRead, this._TotalEntrySize);
-                if (_ioOperationCanceled)
-                    break;
-            }
-        }
-
-
-
-
-        [System.Diagnostics.ConditionalAttribute("Trace")]
-        private void TraceWriteLine(string format, params object[] varParams)
-        {
-            lock (_outputLock)
-            {
-                int tid = System.Threading.Thread.CurrentThread.GetHashCode();
-#if ! (NETCF || SILVERLIGHT)
-                Console.ForegroundColor = (ConsoleColor)(tid % 8 + 8);
-#endif
-                Console.Write("{0:000} ZipEntry.Write ", tid);
-                Console.WriteLine(format, varParams);
-#if ! (NETCF || SILVERLIGHT)
-                Console.ResetColor();
-#endif
-            }
-        }
-
-        private object _outputLock = new Object();
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipEntry.cs b/EPPlus/Packaging/DotNetZip/ZipEntry.cs
deleted file mode 100644
index 7d727d0..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipEntry.cs
+++ /dev/null
@@ -1,2968 +0,0 @@
-// ZipEntry.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006-2010 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-August-06 17:25:53>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZipEntry class, which models the entries within a zip file.
-//
-// Created: Tue, 27 Mar 2007  15:30
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-using Interop = System.Runtime.InteropServices;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    /// Represents a single entry in a ZipFile. Typically, applications get a ZipEntry
-    /// by enumerating the entries within a ZipFile, or by adding an entry to a ZipFile.
-    /// </summary>
-
-    [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00004")]
-    [Interop.ComVisible(true)]
-#if !NETCF
-    [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]  // AutoDual
-#endif
-    internal partial class ZipEntry
-    {
-        /// <summary>
-        /// Default constructor.
-        /// </summary>
-        /// <remarks>
-        /// Applications should never need to call this directly.  It is exposed to
-        /// support COM Automation environments.
-        /// </remarks>
-        public ZipEntry()
-        {
-            _CompressionMethod = (Int16)CompressionMethod.Deflate;
-            _CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
-            _Encryption = EncryptionAlgorithm.None;
-            _Source = ZipEntrySource.None;
-            AlternateEncoding = System.Text.Encoding.ASCII;
-            AlternateEncodingUsage = ZipOption.Never;
-        }
-
-        /// <summary>
-        ///   The time and date at which the file indicated by the <c>ZipEntry</c> was
-        ///   last modified.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The DotNetZip library sets the LastModified value for an entry, equal to
-        ///   the Last Modified time of the file in the filesystem.  If an entry is
-        ///   added from a stream, the library uses <c>System.DateTime.Now</c> for this
-        ///   value, for the given entry.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property allows the application to retrieve and possibly set the
-        ///   LastModified value on an entry, to an arbitrary value.  <see
-        ///   cref="System.DateTime"/> values with a <see cref="System.DateTimeKind" />
-        ///   setting of <c>DateTimeKind.Unspecified</c> are taken to be expressed as
-        ///   <c>DateTimeKind.Local</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Be aware that because of the way <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWare's
-        ///   Zip specification</see> describes how times are stored in the zip file,
-        ///   the full precision of the <c>System.DateTime</c> datatype is not stored
-        ///   for the last modified time when saving zip files.  For more information on
-        ///   how times are formatted, see the PKZip specification.
-        /// </para>
-        ///
-        /// <para>
-        ///   The actual last modified time of a file can be stored in multiple ways in
-        ///   the zip file, and they are not mutually exclusive:
-        /// </para>
-        ///
-        /// <list type="bullet">
-        ///   <item>
-        ///     In the so-called "DOS" format, which has a 2-second precision. Values
-        ///     are rounded to the nearest even second. For example, if the time on the
-        ///     file is 12:34:43, then it will be stored as 12:34:44. This first value
-        ///     is accessible via the <c>LastModified</c> property. This value is always
-        ///     present in the metadata for each zip entry.  In some cases the value is
-        ///     invalid, or zero.
-        ///   </item>
-        ///
-        ///   <item>
-        ///     In the so-called "Windows" or "NTFS" format, as an 8-byte integer
-        ///     quantity expressed as the number of 1/10 milliseconds (in other words
-        ///     the number of 100 nanosecond units) since January 1, 1601 (UTC).  This
-        ///     format is how Windows represents file times.  This time is accessible
-        ///     via the <c>ModifiedTime</c> property.
-        ///   </item>
-        ///
-        ///   <item>
-        ///     In the "Unix" format, a 4-byte quantity specifying the number of seconds since
-        ///     January 1, 1970 UTC.
-        ///   </item>
-        ///
-        ///   <item>
-        ///     In an older format, now deprecated but still used by some current
-        ///     tools. This format is also a 4-byte quantity specifying the number of
-        ///     seconds since January 1, 1970 UTC.
-        ///   </item>
-        ///
-        /// </list>
-        ///
-        /// <para>
-        ///   Zip tools and libraries will always at least handle (read or write) the
-        ///   DOS time, and may also handle the other time formats.  Keep in mind that
-        ///   while the names refer to particular operating systems, there is nothing in
-        ///   the time formats themselves that prevents their use on other operating
-        ///   systems.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading ZIP files, the DotNetZip library reads the Windows-formatted
-        ///   time, if it is stored in the entry, and sets both <c>LastModified</c> and
-        ///   <c>ModifiedTime</c> to that value. When writing ZIP files, the DotNetZip
-        ///   library by default will write both time quantities. It can also emit the
-        ///   Unix-formatted time if desired (See <see
-        ///   cref="EmitTimesInUnixFormatWhenSaving"/>.)
-        /// </para>
-        ///
-        /// <para>
-        ///   The last modified time of the file created upon a call to
-        ///   <c>ZipEntry.Extract()</c> may be adjusted during extraction to compensate
-        ///   for differences in how the .NET Base Class Library deals with daylight
-        ///   saving time (DST) versus how the Windows filesystem deals with daylight
-        ///   saving time.  Raymond Chen <see
-        ///   href="http://blogs.msdn.com/oldnewthing/archive/2003/10/24/55413.aspx">provides
-        ///   some good context</see>.
-        /// </para>
-        ///
-        /// <para>
-        ///   In a nutshell: Daylight savings time rules change regularly.  In 2007, for
-        ///   example, the inception week of DST changed.  In 1977, DST was in place all
-        ///   year round. In 1945, likewise.  And so on.  Win32 does not attempt to
-        ///   guess which time zone rules were in effect at the time in question.  It
-        ///   will render a time as "standard time" and allow the app to change to DST
-        ///   as necessary.  .NET makes a different choice.
-        /// </para>
-        ///
-        /// <para>
-        ///   Compare the output of FileInfo.LastWriteTime.ToString("f") with what you
-        ///   see in the Windows Explorer property sheet for a file that was last
-        ///   written to on the other side of the DST transition. For example, suppose
-        ///   the file was last modified on October 17, 2003, during DST but DST is not
-        ///   currently in effect. Explorer's file properties reports Thursday, October
-        ///   17, 2003, 8:45:38 AM, but .NETs FileInfo reports Thursday, October 17,
-        ///   2003, 9:45 AM.
-        /// </para>
-        ///
-        /// <para>
-        ///   Win32 says, "Thursday, October 17, 2002 8:45:38 AM PST". Note: Pacific
-        ///   STANDARD Time. Even though October 17 of that year occurred during Pacific
-        ///   Daylight Time, Win32 displays the time as standard time because that's
-        ///   what time it is NOW.
-        /// </para>
-        ///
-        /// <para>
-        ///   .NET BCL assumes that the current DST rules were in place at the time in
-        ///   question.  So, .NET says, "Well, if the rules in effect now were also in
-        ///   effect on October 17, 2003, then that would be daylight time" so it
-        ///   displays "Thursday, October 17, 2003, 9:45 AM PDT" - daylight time.
-        /// </para>
-        ///
-        /// <para>
-        ///   So .NET gives a value which is more intuitively correct, but is also
-        ///   potentially incorrect, and which is not invertible. Win32 gives a value
-        ///   which is intuitively incorrect, but is strictly correct.
-        /// </para>
-        ///
-        /// <para>
-        ///   Because of this funkiness, this library adds one hour to the LastModified
-        ///   time on the extracted file, if necessary.  That is to say, if the time in
-        ///   question had occurred in what the .NET Base Class Library assumed to be
-        ///   DST. This assumption may be wrong given the constantly changing DST rules,
-        ///   but it is the best we can do.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        public DateTime LastModified
-        {
-            get { return _LastModified.ToLocalTime(); }
-            set
-            {
-                _LastModified = (value.Kind == DateTimeKind.Unspecified)
-                    ? DateTime.SpecifyKind(value, DateTimeKind.Local)
-                    : value.ToLocalTime();
-                _Mtime = Ionic.Zip.SharedUtilities.AdjustTime_Reverse(_LastModified).ToUniversalTime();
-                _metadataChanged = true;
-            }
-        }
-
-
-        private int BufferSize
-        {
-            get
-            {
-                return this._container.BufferSize;
-            }
-        }
-
-        /// <summary>
-        /// Last Modified time for the file represented by the entry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This value corresponds to the "last modified" time in the NTFS file times
-        ///   as described in <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
-        ///   specification</see>.  When getting this property, the value may be
-        ///   different from <see cref="LastModified" />.  When setting the property,
-        ///   the <see cref="LastModified"/> property also gets set, but with a lower
-        ///   precision.
-        /// </para>
-        ///
-        /// <para>
-        ///   Let me explain. It's going to take a while, so get
-        ///   comfortable. Originally, waaaaay back in 1989 when the ZIP specification
-        ///   was originally described by the esteemed Mr. Phil Katz, the dominant
-        ///   operating system of the time was MS-DOS. MSDOS stored file times with a
-        ///   2-second precision, because, c'mon, <em>who is ever going to need better
-        ///   resolution than THAT?</em> And so ZIP files, regardless of the platform on
-        ///   which the zip file was created, store file times in exactly <see
-        ///   href="http://www.vsft.com/hal/dostime.htm">the same format that DOS used
-        ///   in 1989</see>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Since then, the ZIP spec has evolved, but the internal format for file
-        ///   timestamps remains the same.  Despite the fact that the way times are
-        ///   stored in a zip file is rooted in DOS heritage, any program on any
-        ///   operating system can format a time in this way, and most zip tools and
-        ///   libraries DO - they round file times to the nearest even second and store
-        ///   it just like DOS did 25+ years ago.
-        /// </para>
-        ///
-        /// <para>
-        ///   PKWare extended the ZIP specification to allow a zip file to store what
-        ///   are called "NTFS Times" and "Unix(tm) times" for a file.  These are the
-        ///   <em>last write</em>, <em>last access</em>, and <em>file creation</em>
-        ///   times of a particular file. These metadata are not actually specific
-        ///   to NTFS or Unix. They are tracked for each file by NTFS and by various
-        ///   Unix filesystems, but they are also tracked by other filesystems, too.
-        ///   The key point is that the times are <em>formatted in the zip file</em>
-        ///   in the same way that NTFS formats the time (ticks since win32 epoch),
-        ///   or in the same way that Unix formats the time (seconds since Unix
-        ///   epoch). As with the DOS time, any tool or library running on any
-        ///   operating system is capable of formatting a time in one of these ways
-        ///   and embedding it into the zip file.
-        /// </para>
-        ///
-        /// <para>
-        ///   These extended times are higher precision quantities than the DOS time.
-        ///   As described above, the (DOS) LastModified has a precision of 2 seconds.
-        ///   The Unix time is stored with a precision of 1 second. The NTFS time is
-        ///   stored with a precision of 0.0000001 seconds. The quantities are easily
-        ///   convertible, except for the loss of precision you may incur.
-        /// </para>
-        ///
-        /// <para>
-        ///   A zip archive can store the {C,A,M} times in NTFS format, in Unix format,
-        ///   or not at all.  Often a tool running on Unix or Mac will embed the times
-        ///   in Unix format (1 second precision), while WinZip running on Windows might
-        ///   embed the times in NTFS format (precision of of 0.0000001 seconds).  When
-        ///   reading a zip file with these "extended" times, in either format,
-        ///   DotNetZip represents the values with the
-        ///   <c>ModifiedTime</c>, <c>AccessedTime</c> and <c>CreationTime</c>
-        ///   properties on the <c>ZipEntry</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   While any zip application or library, regardless of the platform it
-        ///   runs on, could use any of the time formats allowed by the ZIP
-        ///   specification, not all zip tools or libraries do support all these
-        ///   formats.  Storing the higher-precision times for each entry is
-        ///   optional for zip files, and many tools and libraries don't use the
-        ///   higher precision quantities at all. The old DOS time, represented by
-        ///   <see cref="LastModified"/>, is guaranteed to be present, though it
-        ///   sometimes unset.
-        /// </para>
-        ///
-        /// <para>
-        ///   Ok, getting back to the question about how the <c>LastModified</c>
-        ///   property relates to this <c>ModifiedTime</c>
-        ///   property... <c>LastModified</c> is always set, while
-        ///   <c>ModifiedTime</c> is not. (The other times stored in the <em>NTFS
-        ///   times extension</em>, <c>CreationTime</c> and <c>AccessedTime</c> also
-        ///   may not be set on an entry that is read from an existing zip file.)
-        ///   When reading a zip file, then <c>LastModified</c> takes the DOS time
-        ///   that is stored with the file. If the DOS time has been stored as zero
-        ///   in the zipfile, then this library will use <c>DateTime.Now</c> for the
-        ///   <c>LastModified</c> value.  If the ZIP file was created by an evolved
-        ///   tool, then there will also be higher precision NTFS or Unix times in
-        ///   the zip file.  In that case, this library will read those times, and
-        ///   set <c>LastModified</c> and <c>ModifiedTime</c> to the same value, the
-        ///   one corresponding to the last write time of the file.  If there are no
-        ///   higher precision times stored for the entry, then <c>ModifiedTime</c>
-        ///   remains unset (likewise <c>AccessedTime</c> and <c>CreationTime</c>),
-        ///   and <c>LastModified</c> keeps its DOS time.
-        /// </para>
-        ///
-        /// <para>
-        ///   When creating zip files with this library, by default the extended time
-        ///   properties (<c>ModifiedTime</c>, <c>AccessedTime</c>, and
-        ///   <c>CreationTime</c>) are set on the ZipEntry instance, and these data are
-        ///   stored in the zip archive for each entry, in NTFS format. If you add an
-        ///   entry from an actual filesystem file, then the entry gets the actual file
-        ///   times for that file, to NTFS-level precision.  If you add an entry from a
-        ///   stream, or a string, then the times get the value <c>DateTime.Now</c>.  In
-        ///   this case <c>LastModified</c> and <c>ModifiedTime</c> will be identical,
-        ///   to 2 seconds of precision.  You can explicitly set the
-        ///   <c>CreationTime</c>, <c>AccessedTime</c>, and <c>ModifiedTime</c> of an
-        ///   entry using the property setters.  If you want to set all of those
-        ///   quantities, it's more efficient to use the <see
-        ///   cref="SetEntryTimes(DateTime, DateTime, DateTime)"/> method.  Those
-        ///   changes are not made permanent in the zip file until you call <see
-        ///   cref="ZipFile.Save()"/> or one of its cousins.
-        /// </para>
-        ///
-        /// <para>
-        ///   When creating a zip file, you can override the default behavior of
-        ///   this library for formatting times in the zip file, disabling the
-        ///   embedding of file times in NTFS format or enabling the storage of file
-        ///   times in Unix format, or both.  You may want to do this, for example,
-        ///   when creating a zip file on Windows, that will be consumed on a Mac,
-        ///   by an application that is not hip to the "NTFS times" format. To do
-        ///   this, use the <see cref="EmitTimesInWindowsFormatWhenSaving"/> and
-        ///   <see cref="EmitTimesInUnixFormatWhenSaving"/> properties.  A valid zip
-        ///   file may store the file times in both formats.  But, there are no
-        ///   guarantees that a program running on Mac or Linux will gracefully
-        ///   handle the NTFS-formatted times when Unix times are present, or that a
-        ///   non-DotNetZip-powered application running on Windows will be able to
-        ///   handle file times in Unix format. DotNetZip will always do something
-        ///   reasonable; other libraries or tools may not. When in doubt, test.
-        /// </para>
-        ///
-        /// <para>
-        ///   I'll bet you didn't think one person could type so much about time, eh?
-        ///   And reading it was so enjoyable, too!  Well, in appreciation, <see
-        ///   href="http://cheeso.members.winisp.net/DotNetZipDonate.aspx">maybe you
-        ///   should donate</see>?
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="AccessedTime"/>
-        /// <seealso cref="CreationTime"/>
-        /// <seealso cref="Ionic.Zip.ZipEntry.LastModified"/>
-        /// <seealso cref="SetEntryTimes"/>
-        public DateTime ModifiedTime
-        {
-            get { return _Mtime; }
-            set
-            {
-                SetEntryTimes(_Ctime, _Atime, value);
-            }
-        }
-
-        /// <summary>
-        /// Last Access time for the file represented by the entry.
-        /// </summary>
-        /// <remarks>
-        /// This value may or may not be meaningful.  If the <c>ZipEntry</c> was read from an existing
-        /// Zip archive, this information may not be available. For an explanation of why, see
-        /// <see cref="ModifiedTime"/>.
-        /// </remarks>
-        /// <seealso cref="ModifiedTime"/>
-        /// <seealso cref="CreationTime"/>
-        /// <seealso cref="SetEntryTimes"/>
-        public DateTime AccessedTime
-        {
-            get { return _Atime; }
-            set
-            {
-                SetEntryTimes(_Ctime, value, _Mtime);
-            }
-        }
-
-        /// <summary>
-        /// The file creation time for the file represented by the entry.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// This value may or may not be meaningful.  If the <c>ZipEntry</c> was read
-        /// from an existing zip archive, and the creation time was not set on the entry
-        /// when the zip file was created, then this property may be meaningless. For an
-        /// explanation of why, see <see cref="ModifiedTime"/>.
-        /// </remarks>
-        /// <seealso cref="ModifiedTime"/>
-        /// <seealso cref="AccessedTime"/>
-        /// <seealso cref="SetEntryTimes"/>
-        public DateTime CreationTime
-        {
-            get { return _Ctime; }
-            set
-            {
-                SetEntryTimes(value, _Atime, _Mtime);
-            }
-        }
-
-        /// <summary>
-        ///   Sets the NTFS Creation, Access, and Modified times for the given entry.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   When adding an entry from a file or directory, the Creation, Access, and
-        ///   Modified times for the given entry are automatically set from the
-        ///   filesystem values. When adding an entry from a stream or string, the
-        ///   values are implicitly set to DateTime.Now.  The application may wish to
-        ///   set these values to some arbitrary value, before saving the archive, and
-        ///   can do so using the various setters.  If you want to set all of the times,
-        ///   this method is more efficient.
-        /// </para>
-        ///
-        /// <para>
-        ///   The values you set here will be retrievable with the <see
-        ///   cref="ModifiedTime"/>, <see cref="CreationTime"/> and <see
-        ///   cref="AccessedTime"/> properties.
-        /// </para>
-        ///
-        /// <para>
-        ///   When this method is called, if both <see
-        ///   cref="EmitTimesInWindowsFormatWhenSaving"/> and <see
-        ///   cref="EmitTimesInUnixFormatWhenSaving"/> are false, then the
-        ///   <c>EmitTimesInWindowsFormatWhenSaving</c> flag is automatically set.
-        /// </para>
-        ///
-        /// <para>
-        ///   DateTime values provided here without a DateTimeKind are assumed to be Local Time.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <param name="created">the creation time of the entry.</param>
-        /// <param name="accessed">the last access time of the entry.</param>
-        /// <param name="modified">the last modified time of the entry.</param>
-        ///
-        /// <seealso cref="EmitTimesInWindowsFormatWhenSaving" />
-        /// <seealso cref="EmitTimesInUnixFormatWhenSaving" />
-        /// <seealso cref="AccessedTime"/>
-        /// <seealso cref="CreationTime"/>
-        /// <seealso cref="ModifiedTime"/>
-        public void SetEntryTimes(DateTime created, DateTime accessed, DateTime modified)
-        {
-            _ntfsTimesAreSet = true;
-            if (created == _zeroHour && created.Kind == _zeroHour.Kind) created = _win32Epoch;
-            if (accessed == _zeroHour && accessed.Kind == _zeroHour.Kind) accessed = _win32Epoch;
-            if (modified == _zeroHour && modified.Kind == _zeroHour.Kind) modified = _win32Epoch;
-            _Ctime = created.ToUniversalTime();
-            _Atime = accessed.ToUniversalTime();
-            _Mtime = modified.ToUniversalTime();
-            _LastModified = _Mtime;
-            if (!_emitUnixTimes && !_emitNtfsTimes)
-                _emitNtfsTimes = true;
-            _metadataChanged = true;
-        }
-
-
-
-        /// <summary>
-        ///   Specifies whether the Creation, Access, and Modified times for the given
-        ///   entry will be emitted in "Windows format" when the zip archive is saved.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   An application creating a zip archive can use this flag to explicitly
-        ///   specify that the file times for the entry should or should not be stored
-        ///   in the zip archive in the format used by Windows. The default value of
-        ///   this property is <c>true</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   When adding an entry from a file or directory, the Creation (<see
-        ///   cref="CreationTime"/>), Access (<see cref="AccessedTime"/>), and Modified
-        ///   (<see cref="ModifiedTime"/>) times for the given entry are automatically
-        ///   set from the filesystem values. When adding an entry from a stream or
-        ///   string, all three values are implicitly set to DateTime.Now.  Applications
-        ///   can also explicitly set those times by calling <see
-        ///   cref="SetEntryTimes(DateTime, DateTime, DateTime)" />.
-        /// </para>
-        ///
-        /// <para>
-        ///   <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
-        ///   zip specification</see> describes multiple ways to format these times in a
-        ///   zip file. One is the format Windows applications normally use: 100ns ticks
-        ///   since Jan 1, 1601 UTC.  The other is a format Unix applications typically
-        ///   use: seconds since January 1, 1970 UTC.  Each format can be stored in an
-        ///   "extra field" in the zip entry when saving the zip archive. The former
-        ///   uses an extra field with a Header Id of 0x000A, while the latter uses a
-        ///   header ID of 0x5455.
-        /// </para>
-        ///
-        /// <para>
-        ///   Not all zip tools and libraries can interpret these fields.  Windows
-        ///   compressed folders is one that can read the Windows Format timestamps,
-        ///   while I believe the <see href="http://www.info-zip.org/">Infozip</see>
-        ///   tools can read the Unix format timestamps. Although the time values are
-        ///   easily convertible, subject to a loss of precision, some tools and
-        ///   libraries may be able to read only one or the other. DotNetZip can read or
-        ///   write times in either or both formats.
-        /// </para>
-        ///
-        /// <para>
-        ///   The times stored are taken from <see cref="ModifiedTime"/>, <see
-        ///   cref="AccessedTime"/>, and <see cref="CreationTime"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is not mutually exclusive from the <see
-        ///   cref="ZipEntry.EmitTimesInUnixFormatWhenSaving"/> property.  It is
-        ///   possible that a zip entry can embed the timestamps in both forms, one
-        ///   form, or neither.  But, there are no guarantees that a program running on
-        ///   Mac or Linux will gracefully handle NTFS Formatted times, or that a
-        ///   non-DotNetZip-powered application running on Windows will be able to
-        ///   handle file times in Unix format. When in doubt, test.
-        /// </para>
-        ///
-        /// <para>
-        ///   Normally you will use the <see
-        ///   cref="ZipFile.EmitTimesInWindowsFormatWhenSaving">ZipFile.EmitTimesInWindowsFormatWhenSaving</see>
-        ///   property, to specify the behavior for all entries in a zip, rather than
-        ///   the property on each individual entry.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <seealso cref="SetEntryTimes(DateTime, DateTime, DateTime)"/>
-        /// <seealso cref="EmitTimesInUnixFormatWhenSaving"/>
-        /// <seealso cref="CreationTime"/>
-        /// <seealso cref="AccessedTime"/>
-        /// <seealso cref="ModifiedTime"/>
-        public bool EmitTimesInWindowsFormatWhenSaving
-        {
-            get
-            {
-                return _emitNtfsTimes;
-            }
-            set
-            {
-                _emitNtfsTimes = value;
-                _metadataChanged = true;
-            }
-        }
-
-        /// <summary>
-        ///   Specifies whether the Creation, Access, and Modified times for the given
-        ///   entry will be emitted in &quot;Unix(tm) format&quot; when the zip archive is saved.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   An application creating a zip archive can use this flag to explicitly
-        ///   specify that the file times for the entry should or should not be stored
-        ///   in the zip archive in the format used by Unix. By default this flag is
-        ///   <c>false</c>, meaning the Unix-format times are not stored in the zip
-        ///   archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   When adding an entry from a file or directory, the Creation (<see
-        ///   cref="CreationTime"/>), Access (<see cref="AccessedTime"/>), and Modified
-        ///   (<see cref="ModifiedTime"/>) times for the given entry are automatically
-        ///   set from the filesystem values. When adding an entry from a stream or
-        ///   string, all three values are implicitly set to DateTime.Now.  Applications
-        ///   can also explicitly set those times by calling <see
-        ///   cref="SetEntryTimes(DateTime, DateTime, DateTime)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
-        ///   zip specification</see> describes multiple ways to format these times in a
-        ///   zip file. One is the format Windows applications normally use: 100ns ticks
-        ///   since Jan 1, 1601 UTC.  The other is a format Unix applications typically
-        ///   use: seconds since Jan 1, 1970 UTC.  Each format can be stored in an
-        ///   "extra field" in the zip entry when saving the zip archive. The former
-        ///   uses an extra field with a Header Id of 0x000A, while the latter uses a
-        ///   header ID of 0x5455.
-        /// </para>
-        ///
-        /// <para>
-        ///   Not all tools and libraries can interpret these fields.  Windows
-        ///   compressed folders is one that can read the Windows Format timestamps,
-        ///   while I believe the <see href="http://www.info-zip.org/">Infozip</see>
-        ///   tools can read the Unix format timestamps. Although the time values are
-        ///   easily convertible, subject to a loss of precision, some tools and
-        ///   libraries may be able to read only one or the other. DotNetZip can read or
-        ///   write times in either or both formats.
-        /// </para>
-        ///
-        /// <para>
-        ///   The times stored are taken from <see cref="ModifiedTime"/>, <see
-        ///   cref="AccessedTime"/>, and <see cref="CreationTime"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is not mutually exclusive from the <see
-        ///   cref="ZipEntry.EmitTimesInWindowsFormatWhenSaving"/> property.  It is
-        ///   possible that a zip entry can embed the timestamps in both forms, one
-        ///   form, or neither.  But, there are no guarantees that a program running on
-        ///   Mac or Linux will gracefully handle NTFS Formatted times, or that a
-        ///   non-DotNetZip-powered application running on Windows will be able to
-        ///   handle file times in Unix format. When in doubt, test.
-        /// </para>
-        ///
-        /// <para>
-        ///   Normally you will use the <see
-        ///   cref="ZipFile.EmitTimesInUnixFormatWhenSaving">ZipFile.EmitTimesInUnixFormatWhenSaving</see>
-        ///   property, to specify the behavior for all entries, rather than the
-        ///   property on each individual entry.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="SetEntryTimes(DateTime, DateTime, DateTime)"/>
-        /// <seealso cref="EmitTimesInWindowsFormatWhenSaving"/>
-        /// <seealso cref="ZipFile.EmitTimesInUnixFormatWhenSaving"/>
-        /// <seealso cref="CreationTime"/>
-        /// <seealso cref="AccessedTime"/>
-        /// <seealso cref="ModifiedTime"/>
-        public bool EmitTimesInUnixFormatWhenSaving
-        {
-            get
-            {
-                return _emitUnixTimes;
-            }
-            set
-            {
-                _emitUnixTimes = value;
-                _metadataChanged = true;
-            }
-        }
-
-
-        /// <summary>
-        /// The type of timestamp attached to the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// This property is valid only for a ZipEntry that was read from a zip archive.
-        /// It indicates the type of timestamp attached to the entry.
-        /// </remarks>
-        ///
-        /// <seealso cref="EmitTimesInWindowsFormatWhenSaving"/>
-        /// <seealso cref="EmitTimesInUnixFormatWhenSaving"/>
-        internal ZipEntryTimestamp Timestamp
-        {
-            get
-            {
-                return _timestamp;
-            }
-        }
-
-        /// <summary>
-        ///   The file attributes for the entry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The <see cref="System.IO.FileAttributes">attributes</see> in NTFS include
-        ///   ReadOnly, Archive, Hidden, System, and Indexed.  When adding a
-        ///   <c>ZipEntry</c> to a ZipFile, these attributes are set implicitly when
-        ///   adding an entry from the filesystem.  When adding an entry from a stream
-        ///   or string, the Attributes are not set implicitly.  Regardless of the way
-        ///   an entry was added to a <c>ZipFile</c>, you can set the attributes
-        ///   explicitly if you like.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading a <c>ZipEntry</c> from a <c>ZipFile</c>, the attributes are
-        ///   set according to the data stored in the <c>ZipFile</c>. If you extract the
-        ///   entry from the archive to a filesystem file, DotNetZip will set the
-        ///   attributes on the resulting file accordingly.
-        /// </para>
-        ///
-        /// <para>
-        ///   The attributes can be set explicitly by the application.  For example the
-        ///   application may wish to set the <c>FileAttributes.ReadOnly</c> bit for all
-        ///   entries added to an archive, so that on unpack, this attribute will be set
-        ///   on the extracted file.  Any changes you make to this property are made
-        ///   permanent only when you call a <c>Save()</c> method on the <c>ZipFile</c>
-        ///   instance that contains the ZipEntry.
-        /// </para>
-        ///
-        /// <para>
-        ///   For example, an application may wish to zip up a directory and set the
-        ///   ReadOnly bit on every file in the archive, so that upon later extraction,
-        ///   the resulting files will be marked as ReadOnly.  Not every extraction tool
-        ///   respects these attributes, but if you unpack with DotNetZip, as for
-        ///   example in a self-extracting archive, then the attributes will be set as
-        ///   they are stored in the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   These attributes may not be interesting or useful if the resulting archive
-        ///   is extracted on a non-Windows platform.  How these attributes get used
-        ///   upon extraction depends on the platform and tool used.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is only partially supported in the Silverlight version
-        ///   of the library: applications can read attributes on entries within
-        ///   ZipFiles. But extracting entries within Silverlight will not set the
-        ///   attributes on the extracted files.
-        /// </para>
-        ///
-        /// </remarks>
-        public System.IO.FileAttributes Attributes
-        {
-            // workitem 7071
-            get { return (System.IO.FileAttributes)_ExternalFileAttrs; }
-            set
-            {
-                _ExternalFileAttrs = (int)value;
-                // Since the application is explicitly setting the attributes, overwriting
-                // whatever was there, we will explicitly set the Version made by field.
-                // workitem 7926 - "version made by" OS should be zero for compat with WinZip
-                _VersionMadeBy = (0 << 8) + 45;  // v4.5 of the spec
-                _metadataChanged = true;
-            }
-        }
-
-
-        /// <summary>
-        ///   The name of the filesystem file, referred to by the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///  <para>
-        ///    This property specifies the thing-to-be-zipped on disk, and is set only
-        ///    when the <c>ZipEntry</c> is being created from a filesystem file.  If the
-        ///    <c>ZipFile</c> is instantiated by reading an existing .zip archive, then
-        ///    the LocalFileName will be <c>null</c> (<c>Nothing</c> in VB).
-        ///  </para>
-        ///
-        ///  <para>
-        ///    When it is set, the value of this property may be different than <see
-        ///    cref="FileName"/>, which is the path used in the archive itself.  If you
-        ///    call <c>Zip.AddFile("foop.txt", AlternativeDirectory)</c>, then the path
-        ///    used for the <c>ZipEntry</c> within the zip archive will be different
-        ///    than this path.
-        ///  </para>
-        ///
-        ///  <para>
-        ///   If the entry is being added from a stream, then this is null (Nothing in VB).
-        ///  </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="FileName"/>
-        internal string LocalFileName
-        {
-            get { return _LocalFileName; }
-        }
-
-        /// <summary>
-        ///   The name of the file contained in the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This is the name of the entry in the <c>ZipFile</c> itself.  When creating
-        ///   a zip archive, if the <c>ZipEntry</c> has been created from a filesystem
-        ///   file, via a call to <see cref="ZipFile.AddFile(String,String)"/> or <see
-        ///   cref="ZipFile.AddItem(String,String)"/>, or a related overload, the value
-        ///   of this property is derived from the name of that file. The
-        ///   <c>FileName</c> property does not include drive letters, and may include a
-        ///   different directory path, depending on the value of the
-        ///   <c>directoryPathInArchive</c> parameter used when adding the entry into
-        ///   the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   In some cases there is no related filesystem file - for example when a
-        ///   <c>ZipEntry</c> is created using <see cref="ZipFile.AddEntry(string,
-        ///   string)"/> or one of the similar overloads.  In this case, the value of
-        ///   this property is derived from the fileName and the directory path passed
-        ///   to that method.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading a zip file, this property takes the value of the entry name
-        ///   as stored in the zip file. If you extract such an entry, the extracted
-        ///   file will take the name given by this property.
-        /// </para>
-        ///
-        /// <para>
-        ///   Applications can set this property when creating new zip archives or when
-        ///   reading existing archives. When setting this property, the actual value
-        ///   that is set will replace backslashes with forward slashes, in accordance
-        ///   with <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
-        ///   specification</see>, for compatibility with Unix(tm) and ... get
-        ///   this.... Amiga!
-        /// </para>
-        ///
-        /// <para>
-        ///   If an application reads a <c>ZipFile</c> via <see
-        ///   cref="ZipFile.Read(String)"/> or a related overload, and then explicitly
-        ///   sets the FileName on an entry contained within the <c>ZipFile</c>, and
-        ///   then calls <see cref="ZipFile.Save()"/>, the application will effectively
-        ///   rename the entry within the zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   If an application sets the value of <c>FileName</c>, then calls
-        ///   <c>Extract()</c> on the entry, the entry is extracted to a file using the
-        ///   newly set value as the filename.  The <c>FileName</c> value is made
-        ///   permanent in the zip archive only <em>after</em> a call to one of the
-        ///   <c>ZipFile.Save()</c> methods on the <c>ZipFile</c> that contains the
-        ///   ZipEntry.
-        /// </para>
-        ///
-        /// <para>
-        ///   If an application attempts to set the <c>FileName</c> to a value that
-        ///   would result in a duplicate entry in the <c>ZipFile</c>, an exception is
-        ///   thrown.
-        /// </para>
-        ///
-        /// <para>
-        ///   When a <c>ZipEntry</c> is contained within a <c>ZipFile</c>, applications
-        ///   cannot rename the entry within the context of a <c>foreach</c> (<c>For
-        ///   Each</c> in VB) loop, because of the way the <c>ZipFile</c> stores
-        ///   entries.  If you need to enumerate through all the entries and rename one
-        ///   or more of them, use <see
-        ///   cref="ZipFile.EntriesSorted">ZipFile.EntriesSorted</see> as the
-        ///   collection.  See also, <see
-        ///   cref="ZipFile.GetEnumerator()">ZipFile.GetEnumerator()</see>.
-        /// </para>
-        ///
-        /// </remarks>
-        public string FileName
-        {
-            get { return _FileNameInArchive; }
-            set
-            {
-                if (_container.ZipFile == null)
-                    throw new ZipException("Cannot rename; this is not supported in ZipOutputStream/ZipInputStream.");
-
-                // rename the entry!
-                if (String.IsNullOrEmpty(value)) throw new ZipException("The FileName must be non empty and non-null.");
-
-                var filename = ZipEntry.NameInArchive(value, null);
-                // workitem 8180
-                if (_FileNameInArchive == filename) return; // nothing to do
-
-                // workitem 8047 - when renaming, must remove old and then add a new entry
-                this._container.ZipFile.RemoveEntry(this);
-                this._container.ZipFile.InternalAddEntry(filename, this);
-
-                _FileNameInArchive = filename;
-                _container.ZipFile.NotifyEntryChanged();
-                _metadataChanged = true;
-            }
-        }
-
-
-        /// <summary>
-        /// The stream that provides content for the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The application can use this property to set the input stream for an
-        ///   entry on a just-in-time basis. Imagine a scenario where the application
-        ///   creates a <c>ZipFile</c> comprised of content obtained from hundreds of
-        ///   files, via calls to <c>AddFile()</c>. The DotNetZip library opens streams
-        ///   on these files on a just-in-time basis, only when writing the entry out to
-        ///   an external store within the scope of a <c>ZipFile.Save()</c> call.  Only
-        ///   one input stream is opened at a time, as each entry is being written out.
-        /// </para>
-        ///
-        /// <para>
-        ///   Now imagine a different application that creates a <c>ZipFile</c>
-        ///   with content obtained from hundreds of streams, added through <see
-        ///   cref="ZipFile.AddEntry(string, System.IO.Stream)"/>.  Normally the
-        ///   application would supply an open stream to that call.  But when large
-        ///   numbers of streams are being added, this can mean many open streams at one
-        ///   time, unnecessarily.
-        /// </para>
-        ///
-        /// <para>
-        ///   To avoid this, call <see cref="ZipFile.AddEntry(String, OpenDelegate,
-        ///   CloseDelegate)"/> and specify delegates that open and close the stream at
-        ///   the time of Save.
-        /// </para>
-        ///
-        ///
-        /// <para>
-        ///   Setting the value of this property when the entry was not added from a
-        ///   stream (for example, when the <c>ZipEntry</c> was added with <see
-        ///   cref="ZipFile.AddFile(String)"/> or <see
-        ///   cref="ZipFile.AddDirectory(String)"/>, or when the entry was added by
-        ///   reading an existing zip archive) will throw an exception.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        public Stream InputStream
-        {
-            get { return _sourceStream; }
-
-            set
-            {
-                if (this._Source != ZipEntrySource.Stream)
-                    throw new ZipException("You must not set the input stream for this entry.");
-
-                _sourceWasJitProvided = true;
-                _sourceStream = value;
-            }
-        }
-
-
-        /// <summary>
-        ///   A flag indicating whether the InputStream was provided Just-in-time.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When creating a zip archive, an application can obtain content for one or
-        ///   more of the <c>ZipEntry</c> instances from streams, using the <see
-        ///   cref="ZipFile.AddEntry(string, System.IO.Stream)"/> method.  At the time
-        ///   of calling that method, the application can supply null as the value of
-        ///   the stream parameter.  By doing so, the application indicates to the
-        ///   library that it will provide a stream for the entry on a just-in-time
-        ///   basis, at the time one of the <c>ZipFile.Save()</c> methods is called and
-        ///   the data for the various entries are being compressed and written out.
-        /// </para>
-        ///
-        /// <para>
-        ///   In this case, the application can set the <see cref="InputStream"/>
-        ///   property, typically within the SaveProgress event (event type: <see
-        ///   cref="ZipProgressEventType.Saving_BeforeWriteEntry"/>) for that entry.
-        /// </para>
-        ///
-        /// <para>
-        ///   The application will later want to call Close() and Dispose() on that
-        ///   stream.  In the SaveProgress event, when the event type is <see
-        ///   cref="ZipProgressEventType.Saving_AfterWriteEntry"/>, the application can
-        ///   do so.  This flag indicates that the stream has been provided by the
-        ///   application on a just-in-time basis and that it is the application's
-        ///   responsibility to call Close/Dispose on that stream.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="InputStream"/>
-        public bool InputStreamWasJitProvided
-        {
-            get { return _sourceWasJitProvided; }
-        }
-
-
-
-        /// <summary>
-        /// An enum indicating the source of the ZipEntry.
-        /// </summary>
-        internal ZipEntrySource Source
-        {
-            get { return _Source; }
-        }
-
-
-        /// <summary>
-        /// The version of the zip engine needed to read the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This is a readonly property, indicating the version of <a
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
-        ///   specification</a> that the extracting tool or library must support to
-        ///   extract the given entry.  Generally higher versions indicate newer
-        ///   features.  Older zip engines obviously won't know about new features, and
-        ///   won't be able to extract entries that depend on those newer features.
-        /// </para>
-        ///
-        /// <list type="table">
-        /// <listheader>
-        /// <term>value</term>
-        /// <description>Features</description>
-        /// </listheader>
-        ///
-        /// <item>
-        /// <term>20</term>
-        /// <description>a basic Zip Entry, potentially using PKZIP encryption.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>45</term>
-        /// <description>The ZIP64 extension is used on the entry.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>46</term>
-        /// <description> File is compressed using BZIP2 compression*</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>50</term>
-        /// <description> File is encrypted using PkWare's DES, 3DES, (broken) RC2 or RC4</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>51</term>
-        /// <description> File is encrypted using PKWare's AES encryption or corrected RC2 encryption.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>52</term>
-        /// <description> File is encrypted using corrected RC2-64 encryption**</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>61</term>
-        /// <description> File is encrypted using non-OAEP key wrapping***</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>63</term>
-        /// <description> File is compressed using LZMA, PPMd+, Blowfish, or Twofish</description>
-        /// </item>
-        ///
-        /// </list>
-        ///
-        /// <para>
-        ///   There are other values possible, not listed here. DotNetZip supports
-        ///   regular PKZip encryption, and ZIP64 extensions.  DotNetZip cannot extract
-        ///   entries that require a zip engine higher than 45.
-        /// </para>
-        ///
-        /// <para>
-        ///   This value is set upon reading an existing zip file, or after saving a zip
-        ///   archive.
-        /// </para>
-        /// </remarks>
-        public Int16 VersionNeeded
-        {
-            get { return _VersionNeeded; }
-        }
-
-        /// <summary>
-        /// The comment attached to the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Each entry in a zip file can optionally have a comment associated to
-        ///   it. The comment might be displayed by a zip tool during extraction, for
-        ///   example.
-        /// </para>
-        ///
-        /// <para>
-        ///   By default, the <c>Comment</c> is encoded in IBM437 code page. You can
-        ///   specify an alternative with <see cref="AlternateEncoding"/> and
-        ///  <see cref="AlternateEncodingUsage"/>.
-        /// </para>
-        /// </remarks>
-        /// <seealso cref="AlternateEncoding"/>
-        /// <seealso cref="AlternateEncodingUsage"/>
-        public string Comment
-        {
-            get { return _Comment; }
-            set
-            {
-                _Comment = value;
-                _metadataChanged = true;
-            }
-        }
-
-
-        /// <summary>
-        /// Indicates whether the entry requires ZIP64 extensions.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This property is null (Nothing in VB) until a <c>Save()</c> method on the
-        ///   containing <see cref="ZipFile"/> instance has been called. The property is
-        ///   non-null (<c>HasValue</c> is true) only after a <c>Save()</c> method has
-        ///   been called.
-        /// </para>
-        ///
-        /// <para>
-        ///   After the containing <c>ZipFile</c> has been saved, the Value of this
-        ///   property is true if any of the following three conditions holds: the
-        ///   uncompressed size of the entry is larger than 0xFFFFFFFF; the compressed
-        ///   size of the entry is larger than 0xFFFFFFFF; the relative offset of the
-        ///   entry within the zip archive is larger than 0xFFFFFFFF.  These quantities
-        ///   are not known until a <c>Save()</c> is attempted on the zip archive and
-        ///   the compression is applied.
-        /// </para>
-        ///
-        /// <para>
-        ///   If none of the three conditions holds, then the <c>Value</c> is false.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>Value</c> of false does not indicate that the entry, as saved in the
-        ///   zip archive, does not use ZIP64.  It merely indicates that ZIP64 is
-        ///   <em>not required</em>.  An entry may use ZIP64 even when not required if
-        ///   the <see cref="ZipFile.UseZip64WhenSaving"/> property on the containing
-        ///   <c>ZipFile</c> instance is set to <see cref="Zip64Option.Always"/>, or if
-        ///   the <see cref="ZipFile.UseZip64WhenSaving"/> property on the containing
-        ///   <c>ZipFile</c> instance is set to <see cref="Zip64Option.AsNecessary"/>
-        ///   and the output stream was not seekable.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="OutputUsedZip64"/>
-        public Nullable<bool> RequiresZip64
-        {
-            get
-            {
-                return _entryRequiresZip64;
-            }
-        }
-
-        /// <summary>
-        ///   Indicates whether the entry actually used ZIP64 extensions, as it was most
-        ///   recently written to the output file or stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This Nullable property is null (Nothing in VB) until a <c>Save()</c>
-        ///   method on the containing <see cref="ZipFile"/> instance has been
-        ///   called. <c>HasValue</c> is true only after a <c>Save()</c> method has been
-        ///   called.
-        /// </para>
-        ///
-        /// <para>
-        ///   The value of this property for a particular <c>ZipEntry</c> may change
-        ///   over successive calls to <c>Save()</c> methods on the containing ZipFile,
-        ///   even if the file that corresponds to the <c>ZipEntry</c> does not. This
-        ///   may happen if other entries contained in the <c>ZipFile</c> expand,
-        ///   causing the offset for this particular entry to exceed 0xFFFFFFFF.
-        /// </para>
-        /// </remarks>
-        /// <seealso cref="RequiresZip64"/>
-        public Nullable<bool> OutputUsedZip64
-        {
-            get { return _OutputUsesZip64; }
-        }
-
-
-        /// <summary>
-        ///   The bitfield for the entry as defined in the zip spec. You probably
-        ///   never need to look at this.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   You probably do not need to concern yourself with the contents of this
-        ///   property, but in case you do:
-        /// </para>
-        ///
-        /// <list type="table">
-        /// <listheader>
-        /// <term>bit</term>
-        /// <description>meaning</description>
-        /// </listheader>
-        ///
-        /// <item>
-        /// <term>0</term>
-        /// <description>set if encryption is used.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>1-2</term>
-        /// <description>
-        /// set to determine whether normal, max, fast deflation.  DotNetZip library
-        /// always leaves these bits unset when writing (indicating "normal"
-        /// deflation"), but can read an entry with any value here.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>3</term>
-        /// <description>
-        /// Indicates that the Crc32, Compressed and Uncompressed sizes are zero in the
-        /// local header.  This bit gets set on an entry during writing a zip file, when
-        /// it is saved to a non-seekable output stream.
-        /// </description>
-        /// </item>
-        ///
-        ///
-        /// <item>
-        /// <term>4</term>
-        /// <description>reserved for "enhanced deflating". This library doesn't do enhanced deflating.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>5</term>
-        /// <description>set to indicate the zip is compressed patched data.  This library doesn't do that.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>6</term>
-        /// <description>
-        /// set if PKWare's strong encryption is used (must also set bit 1 if bit 6 is
-        /// set). This bit is not set if WinZip's AES encryption is set.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>7</term>
-        /// <description>not used</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>8</term>
-        /// <description>not used</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>9</term>
-        /// <description>not used</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>10</term>
-        /// <description>not used</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>11</term>
-        /// <description>
-        /// Language encoding flag (EFS).  If this bit is set, the filename and comment
-        /// fields for this file must be encoded using UTF-8. This library currently
-        /// does not support UTF-8.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>12</term>
-        /// <description>Reserved by PKWARE for enhanced compression.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>13</term>
-        /// <description>
-        ///   Used when encrypting the Central Directory to indicate selected data
-        ///   values in the Local Header are masked to hide their actual values.  See
-        ///   the section in <a
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
-        ///   specification</a> describing the Strong Encryption Specification for
-        ///   details.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>14</term>
-        /// <description>Reserved by PKWARE.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>15</term>
-        /// <description>Reserved by PKWARE.</description>
-        /// </item>
-        ///
-        /// </list>
-        ///
-        /// </remarks>
-        public Int16 BitField
-        {
-            get { return _BitField; }
-        }
-
-        /// <summary>
-        ///   The compression method employed for this ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   <see href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">The
-        ///   Zip specification</see> allows a variety of compression methods.  This
-        ///   library supports just two: 0x08 = Deflate.  0x00 = Store (no compression),
-        ///   for reading or writing.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading an entry from an existing zipfile, the value you retrieve
-        ///   here indicates the compression method used on the entry by the original
-        ///   creator of the zip.  When writing a zipfile, you can specify either 0x08
-        ///   (Deflate) or 0x00 (None).  If you try setting something else, you will get
-        ///   an exception.
-        /// </para>
-        ///
-        /// <para>
-        ///   You may wish to set <c>CompressionMethod</c> to <c>CompressionMethod.None</c> (0)
-        ///   when zipping already-compressed data like a jpg, png, or mp3 file.
-        ///   This can save time and cpu cycles.
-        /// </para>
-        ///
-        /// <para>
-        ///   When setting this property on a <c>ZipEntry</c> that is read from an
-        ///   existing zip file, calling <c>ZipFile.Save()</c> will cause the new
-        ///   CompressionMethod to be used on the entry in the newly saved zip file.
-        /// </para>
-        ///
-        /// <para>
-        ///   Setting this property may have the side effect of modifying the
-        ///   <c>CompressionLevel</c> property. If you set the <c>CompressionMethod</c> to a
-        ///   value other than <c>None</c>, and <c>CompressionLevel</c> is previously
-        ///   set to <c>None</c>, then <c>CompressionLevel</c> will be set to
-        ///   <c>Default</c>.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="CompressionMethod"/>
-        ///
-        /// <example>
-        ///   In this example, the first entry added to the zip archive uses the default
-        ///   behavior - compression is used where it makes sense.  The second entry,
-        ///   the MP3 file, is added to the archive without being compressed.
-        /// <code>
-        /// using (ZipFile zip = new ZipFile(ZipFileToCreate))
-        /// {
-        ///   ZipEntry e1= zip.AddFile(@"notes\Readme.txt");
-        ///   ZipEntry e2= zip.AddFile(@"music\StopThisTrain.mp3");
-        ///   e2.CompressionMethod = CompressionMethod.None;
-        ///   zip.Save();
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile(ZipFileToCreate)
-        ///   zip.AddFile("notes\Readme.txt")
-        ///   Dim e2 as ZipEntry = zip.AddFile("music\StopThisTrain.mp3")
-        ///   e2.CompressionMethod = CompressionMethod.None
-        ///   zip.Save
-        /// End Using
-        /// </code>
-        /// </example>
-        internal CompressionMethod CompressionMethod
-        {
-            get { return (CompressionMethod)_CompressionMethod; }
-            set
-            {
-                if (value == (CompressionMethod)_CompressionMethod) return; // nothing to do.
-
-                if (value != CompressionMethod.None && value != CompressionMethod.Deflate
-#if BZIP
-                    && value != CompressionMethod.BZip2
-#endif
-                    )
-                    throw new InvalidOperationException("Unsupported compression method.");
-
-                // If the source is a zip archive and there was encryption on the
-                // entry, changing the compression method is not supported.
-                //                 if (this._Source == ZipEntrySource.ZipFile && _sourceIsEncrypted)
-                //                     throw new InvalidOperationException("Cannot change compression method on encrypted entries read from archives.");
-
-                _CompressionMethod = (Int16)value;
-
-                if (_CompressionMethod == (Int16)Ionic.Zip.CompressionMethod.None)
-                    _CompressionLevel = Ionic.Zlib.CompressionLevel.None;
-                else if (CompressionLevel == Ionic.Zlib.CompressionLevel.None)
-                    _CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
-
-                if (_container.ZipFile != null) _container.ZipFile.NotifyEntryChanged();
-                _restreamRequiredOnSave = true;
-            }
-        }
-
-
-        /// <summary>
-        ///   Sets the compression level to be used for the entry when saving the zip
-        ///   archive. This applies only for CompressionMethod = DEFLATE.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///  <para>
-        ///    When using the DEFLATE compression method, Varying the compression
-        ///    level used on entries can affect the size-vs-speed tradeoff when
-        ///    compression and decompressing data streams or files.
-        ///  </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>
-        ///
-        ///  <para>
-        ///    When setting this property on a <c>ZipEntry</c> that is read from an
-        ///    existing zip file, calling <c>ZipFile.Save()</c> will cause the new
-        ///    <c>CompressionLevel</c> to be used on the entry in the newly saved zip file.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    Setting this property may have the side effect of modifying the
-        ///    <c>CompressionMethod</c> property. If you set the <c>CompressionLevel</c>
-        ///    to a value other than <c>None</c>, <c>CompressionMethod</c> will be set
-        ///    to <c>Deflate</c>, if it was previously <c>None</c>.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    Setting this property has no effect if the <c>CompressionMethod</c> is something
-        ///    other than <c>Deflate</c> or <c>None</c>.
-        ///  </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="CompressionMethod"/>
-        public OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel CompressionLevel
-        {
-            get
-            {
-                return _CompressionLevel;
-            }
-            set
-            {
-                if (_CompressionMethod != (short)CompressionMethod.Deflate &&
-                    _CompressionMethod != (short)CompressionMethod.None)
-                    return ; // no effect
-
-                if (value == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.Default &&
-                    _CompressionMethod == (short)CompressionMethod.Deflate) return; // nothing to do
-                _CompressionLevel = value;
-
-                if (value == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.None &&
-                    _CompressionMethod == (short)CompressionMethod.None)
-                    return; // nothing more to do
-
-                if (_CompressionLevel == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.None)
-                    _CompressionMethod = (short)OfficeOpenXml.Packaging.Ionic.Zip.CompressionMethod.None;
-                else
-                    _CompressionMethod = (short)OfficeOpenXml.Packaging.Ionic.Zip.CompressionMethod.Deflate;
-
-                if (_container.ZipFile != null) _container.ZipFile.NotifyEntryChanged();
-                _restreamRequiredOnSave = true;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   The compressed size of the file, in bytes, within the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   When reading a <c>ZipFile</c>, this value is read in from the existing
-        ///   zip file. When creating or updating a <c>ZipFile</c>, the compressed
-        ///   size is computed during compression.  Therefore the value on a
-        ///   <c>ZipEntry</c> is valid after a call to <c>Save()</c> (or one of its
-        ///   overloads) in that case.
-        /// </remarks>
-        ///
-        /// <seealso cref="ZipEntry.UncompressedSize"/>
-        public Int64 CompressedSize
-        {
-            get { return _CompressedSize; }
-        }
-
-        /// <summary>
-        ///   The size of the file, in bytes, before compression, or after extraction.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   When reading a <c>ZipFile</c>, this value is read in from the existing
-        ///   zip file. When creating or updating a <c>ZipFile</c>, the uncompressed
-        ///   size is computed during compression.  Therefore the value on a
-        ///   <c>ZipEntry</c> is valid after a call to <c>Save()</c> (or one of its
-        ///   overloads) in that case.
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipEntry.CompressedSize"/>
-        public Int64 UncompressedSize
-        {
-            get { return _UncompressedSize; }
-        }
-
-        /// <summary>
-        /// The ratio of compressed size to uncompressed size of the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This is a ratio of the compressed size to the uncompressed size of the
-        ///   entry, expressed as a double in the range of 0 to 100+. A value of 100
-        ///   indicates no compression at all.  It could be higher than 100 when the
-        ///   compression algorithm actually inflates the data, as may occur for small
-        ///   files, or uncompressible data that is encrypted.
-        /// </para>
-        ///
-        /// <para>
-        ///   You could format it for presentation to a user via a format string of
-        ///   "{3,5:F0}%" to see it as a percentage.
-        /// </para>
-        ///
-        /// <para>
-        ///   If the size of the original uncompressed file is 0, implying a
-        ///   denominator of 0, the return value will be zero.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is valid after reading in an existing zip file, or after
-        ///   saving the <c>ZipFile</c> that contains the ZipEntry. You cannot know the
-        ///   effect of a compression transform until you try it.
-        /// </para>
-        ///
-        /// </remarks>
-        public Double CompressionRatio
-        {
-            get
-            {
-                if (UncompressedSize == 0) return 0;
-                return 100 * (1.0 - (1.0 * CompressedSize) / (1.0 * UncompressedSize));
-            }
-        }
-
-        /// <summary>
-        /// The 32-bit CRC (Cyclic Redundancy Check) on the contents of the ZipEntry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para> You probably don't need to concern yourself with this. It is used
-        /// internally by DotNetZip to verify files or streams upon extraction.  </para>
-        ///
-        /// <para> The value is a <see href="http://en.wikipedia.org/wiki/CRC32">32-bit
-        /// CRC</see> using 0xEDB88320 for the polynomial. This is the same CRC-32 used in
-        /// PNG, MPEG-2, and other protocols and formats.  It is a read-only property; when
-        /// creating a Zip archive, the CRC for each entry is set only after a call to
-        /// <c>Save()</c> on the containing ZipFile. When reading an existing zip file, the value
-        /// of this property reflects the stored CRC for the entry.  </para>
-        ///
-        /// </remarks>
-        public Int32 Crc
-        {
-            get { return _Crc32; }
-        }
-
-        /// <summary>
-        /// True if the entry is a directory (not a file).
-        /// This is a readonly property on the entry.
-        /// </summary>
-        public bool IsDirectory
-        {
-            get { return _IsDirectory; }
-        }
-
-        /// <summary>
-        /// A derived property that is <c>true</c> if the entry uses encryption.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This is a readonly property on the entry.  When reading a zip file,
-        ///   the value for the <c>ZipEntry</c> is determined by the data read
-        ///   from the zip file.  After saving a ZipFile, the value of this
-        ///   property for each <c>ZipEntry</c> indicates whether encryption was
-        ///   actually used (which will have been true if the <see
-        ///   cref="Password"/> was set and the <see cref="Encryption"/> property
-        ///   was something other than <see cref="EncryptionAlgorithm.None"/>.
-        /// </para>
-        /// </remarks>
-        public bool UsesEncryption
-        {
-            get { return (_Encryption_FromZipFile != EncryptionAlgorithm.None); }
-        }
-
-
-        /// <summary>
-        ///   Set this to specify which encryption algorithm to use for the entry when
-        ///   saving it to a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Set this property in order to encrypt the entry when the <c>ZipFile</c> is
-        ///   saved. When setting this property, you must also set a <see
-        ///   cref="Password"/> on the entry.  If you set a value other than <see
-        ///   cref="EncryptionAlgorithm.None"/> on this property and do not set a
-        ///   <c>Password</c> then the entry will not be encrypted. The <c>ZipEntry</c>
-        ///   data is encrypted as the <c>ZipFile</c> is saved, when you call <see
-        ///   cref="ZipFile.Save()"/> or one of its cousins on the containing
-        ///   <c>ZipFile</c> instance. You do not need to specify the <c>Encryption</c>
-        ///   when extracting entries from an archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   The Zip specification from PKWare defines a set of encryption algorithms,
-        ///   and the data formats for the zip archive that support them, and PKWare
-        ///   supports those algorithms in the tools it produces. Other vendors of tools
-        ///   and libraries, such as WinZip or Xceed, typically support <em>a
-        ///   subset</em> of the algorithms specified by PKWare. These tools can
-        ///   sometimes support additional different encryption algorithms and data
-        ///   formats, not specified by PKWare. The AES Encryption specified and
-        ///   supported by WinZip is the most popular example. This library supports a
-        ///   subset of the complete set of algorithms specified by PKWare and other
-        ///   vendors.
-        /// </para>
-        ///
-        /// <para>
-        ///   There is no common, ubiquitous multi-vendor standard for strong encryption
-        ///   within zip files. There is broad support for so-called "traditional" Zip
-        ///   encryption, sometimes called Zip 2.0 encryption, as <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">specified
-        ///   by PKWare</see>, but this encryption is considered weak and
-        ///   breakable. This library currently supports the Zip 2.0 "weak" encryption,
-        ///   and also a stronger WinZip-compatible AES encryption, using either 128-bit
-        ///   or 256-bit key strength. If you want DotNetZip to support an algorithm
-        ///   that is not currently supported, call the author of this library and maybe
-        ///   we can talk business.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <see cref="ZipFile"/> class also has a <see
-        ///   cref="ZipFile.Encryption"/> property.  In most cases you will use
-        ///   <em>that</em> property when setting encryption. This property takes
-        ///   precedence over any <c>Encryption</c> set on the <c>ZipFile</c> itself.
-        ///   Typically, you would use the per-entry Encryption when most entries in the
-        ///   zip archive use one encryption algorithm, and a few entries use a
-        ///   different one.  If all entries in the zip file use the same Encryption,
-        ///   then it is simpler to just set this property on the ZipFile itself, when
-        ///   creating a zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   Some comments on updating archives: If you read a <c>ZipFile</c>, you can
-        ///   modify the Encryption on an encrypted entry: you can remove encryption
-        ///   from an entry that was encrypted; you can encrypt an entry that was not
-        ///   encrypted previously; or, you can change the encryption algorithm.  The
-        ///   changes in encryption are not made permanent until you call Save() on the
-        ///   <c>ZipFile</c>.  To effect changes in encryption, the entry content is
-        ///   streamed through several transformations, depending on the modification
-        ///   the application has requested. For example if the entry is not encrypted
-        ///   and the application sets <c>Encryption</c> to <c>PkzipWeak</c>, then at
-        ///   the time of <c>Save()</c>, the original entry is read and decompressed,
-        ///   then re-compressed and encrypted.  Conversely, if the original entry is
-        ///   encrypted with <c>PkzipWeak</c> encryption, and the application sets the
-        ///   <c>Encryption</c> property to <c>WinZipAes128</c>, then at the time of
-        ///   <c>Save()</c>, the original entry is decrypted via PKZIP encryption and
-        ///   decompressed, then re-compressed and re-encrypted with AES.  This all
-        ///   happens automatically within the library, but it can be time-consuming for
-        ///   large entries.
-        /// </para>
-        ///
-        /// <para>
-        ///   Additionally, when updating archives, it is not possible to change the
-        ///   password when changing the encryption algorithm.  To change both the
-        ///   algorithm and the password, you need to Save() the zipfile twice.  First
-        ///   set the <c>Encryption</c> to None, then call <c>Save()</c>.  Then set the
-        ///   <c>Encryption</c> to the new value (not "None"), then call <c>Save()</c>
-        ///   once again.
-        /// </para>
-        ///
-        /// <para>
-        ///   The WinZip AES encryption algorithms are not supported on the .NET Compact
-        ///   Framework.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example creates a zip archive that uses encryption, and then extracts
-        ///   entries from the archive.  When creating the zip archive, the ReadMe.txt
-        ///   file is zipped without using a password or encryption.  The other file
-        ///   uses encryption.
-        /// </para>
-        /// <code>
-        /// // Create a zip archive with AES Encryption.
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.AddFile("ReadMe.txt")
-        ///     ZipEntry e1= zip.AddFile("2008-Regional-Sales-Report.pdf");
-        ///     e1.Encryption= EncryptionAlgorithm.WinZipAes256;
-        ///     e1.Password= "Top.Secret.No.Peeking!";
-        ///     zip.Save("EncryptedArchive.zip");
-        /// }
-        ///
-        /// // Extract a zip archive that uses AES Encryption.
-        /// // You do not need to specify the algorithm during extraction.
-        /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
-        /// {
-        ///     // Specify the password that is used during extraction, for
-        ///     // all entries that require a password:
-        ///     zip.Password= "Top.Secret.No.Peeking!";
-        ///     zip.ExtractAll("extractDirectory");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// ' Create a zip that uses Encryption.
-        /// Using zip As New ZipFile()
-        ///     zip.AddFile("ReadMe.txt")
-        ///     Dim e1 as ZipEntry
-        ///     e1= zip.AddFile("2008-Regional-Sales-Report.pdf")
-        ///     e1.Encryption= EncryptionAlgorithm.WinZipAes256
-        ///     e1.Password= "Top.Secret.No.Peeking!"
-        ///     zip.Save("EncryptedArchive.zip")
-        /// End Using
-        ///
-        /// ' Extract a zip archive that uses AES Encryption.
-        /// ' You do not need to specify the algorithm during extraction.
-        /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
-        ///     ' Specify the password that is used during extraction, for
-        ///     ' all entries that require a password:
-        ///     zip.Password= "Top.Secret.No.Peeking!"
-        ///     zip.ExtractAll("extractDirectory")
-        /// End Using
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <exception cref="System.InvalidOperationException">
-        /// Thrown in the setter if EncryptionAlgorithm.Unsupported is specified.
-        /// </exception>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipEntry.Password">ZipEntry.Password</seealso>
-        /// <seealso cref="Ionic.Zip.ZipFile.Encryption">ZipFile.Encryption</seealso>
-        internal EncryptionAlgorithm Encryption
-        {
-            get
-            {
-                return _Encryption;
-            }
-            set
-            {
-                if (value == _Encryption) return; // no change
-
-                if (value == EncryptionAlgorithm.Unsupported)
-                    throw new InvalidOperationException("You may not set Encryption to that value.");
-
-                // If the source is a zip archive and there was encryption
-                // on the entry, this will not work. <XXX>
-                //if (this._Source == ZipEntrySource.ZipFile && _sourceIsEncrypted)
-                //    throw new InvalidOperationException("You cannot change the encryption method on encrypted entries read from archives.");
-
-                _Encryption = value;
-                _restreamRequiredOnSave = true;
-                if (_container.ZipFile!=null)
-                    _container.ZipFile.NotifyEntryChanged();
-            }
-        }
-
-
-        /// <summary>
-        /// The Password to be used when encrypting a <c>ZipEntry</c> upon
-        /// <c>ZipFile.Save()</c>, or when decrypting an entry upon Extract().
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This is a write-only property on the entry. Set this to request that the
-        ///   entry be encrypted when writing the zip archive, or set it to specify the
-        ///   password to be used when extracting an existing entry that is encrypted.
-        /// </para>
-        ///
-        /// <para>
-        ///   The password set here is implicitly used to encrypt the entry during the
-        ///   <see cref="ZipFile.Save()"/> operation, or to decrypt during the <see
-        ///   cref="Extract()"/> or <see cref="OpenReader()"/> operation.  If you set
-        ///   the Password on a <c>ZipEntry</c> after calling <c>Save()</c>, there is no
-        ///   effect.
-        /// </para>
-        ///
-        /// <para>
-        ///   Consider setting the <see cref="Encryption"/> property when using a
-        ///   password. Answering concerns that the standard password protection
-        ///   supported by all zip tools is weak, WinZip has extended the ZIP
-        ///   specification with a way to use AES Encryption to protect entries in the
-        ///   Zip file. Unlike the "PKZIP 2.0" encryption specified in the PKZIP
-        ///   specification, <see href=
-        ///   "http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES
-        ///   Encryption</see> uses a standard, strong, tested, encryption
-        ///   algorithm. DotNetZip can create zip archives that use WinZip-compatible
-        ///   AES encryption, if you set the <see cref="Encryption"/> property. But,
-        ///   archives created that use AES encryption may not be readable by all other
-        ///   tools and libraries. For example, Windows Explorer cannot read a
-        ///   "compressed folder" (a zip file) that uses AES encryption, though it can
-        ///   read a zip file that uses "PKZIP encryption."
-        /// </para>
-        ///
-        /// <para>
-        ///   The <see cref="ZipFile"/> class also has a <see cref="ZipFile.Password"/>
-        ///   property.  This property takes precedence over any password set on the
-        ///   ZipFile itself.  Typically, you would use the per-entry Password when most
-        ///   entries in the zip archive use one password, and a few entries use a
-        ///   different password.  If all entries in the zip file use the same password,
-        ///   then it is simpler to just set this property on the ZipFile itself,
-        ///   whether creating a zip archive or extracting a zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   Some comments on updating archives: If you read a <c>ZipFile</c>, you
-        ///   cannot modify the password on any encrypted entry, except by extracting
-        ///   the entry with the original password (if any), removing the original entry
-        ///   via <see cref="ZipFile.RemoveEntry(ZipEntry)"/>, and then adding a new
-        ///   entry with a new Password.
-        /// </para>
-        ///
-        /// <para>
-        ///   For example, suppose you read a <c>ZipFile</c>, and there is an encrypted
-        ///   entry.  Setting the Password property on that <c>ZipEntry</c> and then
-        ///   calling <c>Save()</c> on the <c>ZipFile</c> does not update the password
-        ///   on that entry in the archive.  Neither is an exception thrown. Instead,
-        ///   what happens during the <c>Save()</c> is the existing entry is copied
-        ///   through to the new zip archive, in its original encrypted form. Upon
-        ///   re-reading that archive, the entry can be decrypted with its original
-        ///   password.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you read a ZipFile, and there is an un-encrypted entry, you can set the
-        ///   <c>Password</c> on the entry and then call Save() on the ZipFile, and get
-        ///   encryption on that entry.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example creates a zip file with two entries, and then extracts the
-        ///   entries from the zip file.  When creating the zip file, the two files are
-        ///   added to the zip file using password protection. Each entry uses a
-        ///   different password.  During extraction, each file is extracted with the
-        ///   appropriate password.
-        /// </para>
-        /// <code>
-        /// // create a file with encryption
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     ZipEntry entry;
-        ///     entry= zip.AddFile("Declaration.txt");
-        ///     entry.Password= "123456!";
-        ///     entry = zip.AddFile("Report.xls");
-        ///     entry.Password= "1Secret!";
-        ///     zip.Save("EncryptedArchive.zip");
-        /// }
-        ///
-        /// // extract entries that use encryption
-        /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
-        /// {
-        ///     ZipEntry entry;
-        ///     entry = zip["Declaration.txt"];
-        ///     entry.Password = "123456!";
-        ///     entry.Extract("extractDir");
-        ///     entry = zip["Report.xls"];
-        ///     entry.Password = "1Secret!";
-        ///     entry.Extract("extractDir");
-        /// }
-        ///
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     Dim entry as ZipEntry
-        ///     entry= zip.AddFile("Declaration.txt")
-        ///     entry.Password= "123456!"
-        ///     entry = zip.AddFile("Report.xls")
-        ///     entry.Password= "1Secret!"
-        ///     zip.Save("EncryptedArchive.zip")
-        /// End Using
-        ///
-        ///
-        /// ' extract entries that use encryption
-        /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
-        ///     Dim entry as ZipEntry
-        ///     entry = zip("Declaration.txt")
-        ///     entry.Password = "123456!"
-        ///     entry.Extract("extractDir")
-        ///     entry = zip("Report.xls")
-        ///     entry.Password = "1Secret!"
-        ///     entry.Extract("extractDir")
-        /// End Using
-        ///
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipEntry.Encryption"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.Password">ZipFile.Password</seealso>
-        public string Password
-        {
-            set
-            {
-                _Password = value;
-                if (_Password == null)
-                {
-                    _Encryption = EncryptionAlgorithm.None;
-                }
-                else
-                {
-                    // We're setting a non-null password.
-
-                    // For entries obtained from a zip file that are encrypted, we cannot
-                    // simply restream (recompress, re-encrypt) the file data, because we
-                    // need the old password in order to decrypt the data, and then we
-                    // need the new password to encrypt.  So, setting the password is
-                    // never going to work on an entry that is stored encrypted in a zipfile.
-
-                    // But it is not en error to set the password, obviously: callers will
-                    // set the password in order to Extract encrypted archives.
-
-                    // If the source is a zip archive and there was previously no encryption
-                    // on the entry, then we must re-stream the entry in order to encrypt it.
-                    if (this._Source == ZipEntrySource.ZipFile && !_sourceIsEncrypted)
-                        _restreamRequiredOnSave = true;
-
-                    if (Encryption == EncryptionAlgorithm.None)
-                    {
-                        _Encryption = EncryptionAlgorithm.PkzipWeak;
-                    }
-                }
-            }
-            private get { return _Password; }
-        }
-
-
-
-        internal bool IsChanged
-        {
-            get
-            {
-                return _restreamRequiredOnSave | _metadataChanged;
-            }
-        }
-
-
-        /// <summary>
-        /// The action the library should take when extracting a file that already exists.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     This property affects the behavior of the Extract methods (one of the
-        ///     <c>Extract()</c> or <c>ExtractWithPassword()</c> overloads), when
-        ///     extraction would would overwrite an existing filesystem file. If you do
-        ///     not set this property, the library throws an exception when extracting
-        ///     an entry would overwrite an existing file.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     This property has no effect when extracting to a stream, or when the file to be
-        ///     extracted does not already exist.
-        ///   </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="Ionic.Zip.ZipFile.ExtractExistingFile"/>
-        ///
-        /// <example>
-        ///   This example shows how to set the <c>ExtractExistingFile</c> property in
-        ///   an <c>ExtractProgress</c> event, in response to user input. The
-        ///   <c>ExtractProgress</c> event is invoked if and only if the
-        ///   <c>ExtractExistingFile</c> property was previously set to
-        ///   <c>ExtractExistingFileAction.InvokeExtractProgressEvent</c>.
-        /// <code lang="C#">
-        /// public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
-        /// {
-        ///     if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
-        ///         Console.WriteLine("extract {0} ", e.CurrentEntry.FileName);
-        ///
-        ///     else if (e.EventType == ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite)
-        ///     {
-        ///         ZipEntry entry = e.CurrentEntry;
-        ///         string response = null;
-        ///         // Ask the user if he wants overwrite the file
-        ///         do
-        ///         {
-        ///             Console.Write("Overwrite {0} in {1} ? (y/n/C) ", entry.FileName, e.ExtractLocation);
-        ///             response = Console.ReadLine();
-        ///             Console.WriteLine();
-        ///
-        ///         } while (response != null &amp;&amp; response[0]!='Y' &amp;&amp;
-        ///                  response[0]!='N' &amp;&amp; response[0]!='C');
-        ///
-        ///         if  (response[0]=='C')
-        ///             e.Cancel = true;
-        ///         else if (response[0]=='Y')
-        ///             entry.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
-        ///         else
-        ///             entry.ExtractExistingFile= ExtractExistingFileAction.DoNotOverwrite;
-        ///     }
-        /// }
-        /// </code>
-        /// </example>
-        internal ExtractExistingFileAction ExtractExistingFile
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   The action to take when an error is encountered while
-        ///   opening or reading files as they are saved into a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///  <para>
-        ///     Errors can occur within a call to <see
-        ///     cref="ZipFile.Save()">ZipFile.Save</see>, as the various files contained
-        ///     in a ZipFile are being saved into the zip archive.  During the
-        ///     <c>Save</c>, DotNetZip will perform a <c>File.Open</c> on the file
-        ///     associated to the ZipEntry, and then will read the entire contents of
-        ///     the file as it is zipped. Either the open or the Read may fail, because
-        ///     of lock conflicts or other reasons.  Using this property, you can
-        ///     specify the action to take when such errors occur.
-        ///  </para>
-        ///
-        ///  <para>
-        ///     Typically you will NOT set this property on individual ZipEntry
-        ///     instances.  Instead, you will set the <see
-        ///     cref="ZipFile.ZipErrorAction">ZipFile.ZipErrorAction</see> property on
-        ///     the ZipFile instance, before adding any entries to the
-        ///     <c>ZipFile</c>. If you do this, errors encountered on behalf of any of
-        ///     the entries in the ZipFile will be handled the same way.
-        ///  </para>
-        ///
-        ///  <para>
-        ///     But, if you use a <see cref="ZipFile.ZipError"/> handler, you will want
-        ///     to set this property on the <c>ZipEntry</c> within the handler, to
-        ///     communicate back to DotNetZip what you would like to do with the
-        ///     particular error.
-        ///  </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="Ionic.Zip.ZipFile.ZipErrorAction"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ZipError"/>
-        internal ZipErrorAction ZipErrorAction
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        /// Indicates whether the entry was included in the most recent save.
-        /// </summary>
-        /// <remarks>
-        /// An entry can be excluded or skipped from a save if there is an error
-        /// opening or reading the entry.
-        /// </remarks>
-        /// <seealso cref="ZipErrorAction"/>
-        internal bool IncludedInMostRecentSave
-        {
-            get
-            {
-                return !_skippedDuringSave;
-            }
-        }
-
-
-        /// <summary>
-        ///   A callback that allows the application to specify the compression to use
-        ///   for a given entry that is about to be added to the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See <see cref="ZipFile.SetCompression" />
-        /// </para>
-        /// </remarks>
-        public SetCompressionCallback SetCompression
-        {
-            get;
-            set;
-        }
-
-
-
-        /// <summary>
-        ///   Set to indicate whether to use UTF-8 encoding for filenames and comments.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   If this flag is set, the comment and filename for the entry will be
-        ///   encoded with UTF-8, as described in <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
-        ///   specification</see>, if necessary. "Necessary" means, the filename or
-        ///   entry comment (if any) cannot be reflexively encoded and decoded using the
-        ///   default code page, IBM437.
-        /// </para>
-        ///
-        /// <para>
-        ///   Setting this flag to true is equivalent to setting <see
-        ///   cref="ProvisionalAlternateEncoding"/> to <c>System.Text.Encoding.UTF8</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This flag has no effect or relation to the text encoding used within the
-        ///   file itself.
-        /// </para>
-        ///
-        /// </remarks>
-        [Obsolete("Beginning with v1.9.1.6 of DotNetZip, this property is obsolete.  It will be removed in a future version of the library. Your applications should  use AlternateEncoding and AlternateEncodingUsage instead.")]
-        public bool UseUnicodeAsNecessary
-        {
-            get
-            {
-                return (AlternateEncoding == System.Text.Encoding.GetEncoding("UTF-8")) &&
-                    (AlternateEncodingUsage == ZipOption.AsNecessary);
-            }
-            set
-            {
-                if (value)
-                {
-                    AlternateEncoding = System.Text.Encoding.GetEncoding("UTF-8");
-                    AlternateEncodingUsage = ZipOption.AsNecessary;
-
-                }
-                else
-                {
-                    AlternateEncoding = Ionic.Zip.ZipFile.DefaultEncoding;
-                    AlternateEncodingUsage = ZipOption.Never;
-                }
-            }
-        }
-
-        /// <summary>
-        ///   The text encoding to use for the FileName and Comment on this ZipEntry,
-        ///   when the default encoding is insufficient.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Don't use this property.  See <see cref='AlternateEncoding'/>.
-        /// </para>
-        ///
-        /// </remarks>
-        [Obsolete("This property is obsolete since v1.9.1.6. Use AlternateEncoding and AlternateEncodingUsage instead.", true)]
-        public System.Text.Encoding ProvisionalAlternateEncoding
-        {
-            get; set;
-        }
-
-        /// <summary>
-        ///   Specifies the alternate text encoding used by this ZipEntry
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The default text encoding used in Zip files for encoding filenames and
-        ///     comments is IBM437, which is something like a superset of ASCII.  In
-        ///     cases where this is insufficient, applications can specify an
-        ///     alternate encoding.
-        ///   </para>
-        ///   <para>
-        ///     When creating a zip file, the usage of the alternate encoding is
-        ///     governed by the <see cref="AlternateEncodingUsage"/> property.
-        ///     Typically you would set both properties to tell DotNetZip to employ an
-        ///     encoding that is not IBM437 in the zipfile you are creating.
-        ///   </para>
-        ///   <para>
-        ///     Keep in mind that because the ZIP specification states that the only
-        ///     valid encodings to use are IBM437 and UTF-8, if you use something
-        ///     other than that, then zip tools and libraries may not be able to
-        ///     successfully read the zip archive you generate.
-        ///   </para>
-        ///   <para>
-        ///     The zip specification states that applications should presume that
-        ///     IBM437 is in use, except when a special bit is set, which indicates
-        ///     UTF-8. There is no way to specify an arbitrary code page, within the
-        ///     zip file itself. When you create a zip file encoded with gb2312 or
-        ///     ibm861 or anything other than IBM437 or UTF-8, then the application
-        ///     that reads the zip file needs to "know" which code page to use. In
-        ///     some cases, the code page used when reading is chosen implicitly. For
-        ///     example, WinRar uses the ambient code page for the host desktop
-        ///     operating system. The pitfall here is that if you create a zip in
-        ///     Copenhagen and send it to Tokyo, the reader of the zipfile may not be
-        ///     able to decode successfully.
-        ///   </para>
-        /// </remarks>
-        /// <example>
-        ///   This example shows how to create a zipfile encoded with a
-        ///   language-specific encoding:
-        /// <code>
-        ///   using (var zip = new ZipFile())
-        ///   {
-        ///      zip.AlternateEnoding = System.Text.Encoding.GetEncoding("ibm861");
-        ///      zip.AlternateEnodingUsage = ZipOption.Always;
-        ///      zip.AddFileS(arrayOfFiles);
-        ///      zip.Save("Myarchive-Encoded-in-IBM861.zip");
-        ///   }
-        /// </code>
-        /// </example>
-        /// <seealso cref="ZipFile.AlternateEncodingUsage" />
-        public System.Text.Encoding AlternateEncoding
-        {
-            get; set;
-        }
-
-
-        /// <summary>
-        ///   Describes if and when this instance should apply
-        ///   AlternateEncoding to encode the FileName and Comment, when
-        ///   saving.
-        /// </summary>
-        /// <seealso cref="ZipFile.AlternateEncoding" />
-        internal ZipOption AlternateEncodingUsage
-        {
-            get; set;
-        }
-
-
-        // /// <summary>
-        // /// The text encoding actually used for this ZipEntry.
-        // /// </summary>
-        // ///
-        // /// <remarks>
-        // ///
-        // /// <para>
-        // ///   This read-only property describes the encoding used by the
-        // ///   <c>ZipEntry</c>.  If the entry has been read in from an existing ZipFile,
-        // ///   then it may take the value UTF-8, if the entry is coded to specify UTF-8.
-        // ///   If the entry does not specify UTF-8, the typical case, then the encoding
-        // ///   used is whatever the application specified in the call to
-        // ///   <c>ZipFile.Read()</c>. If the application has used one of the overloads of
-        // ///   <c>ZipFile.Read()</c> that does not accept an encoding parameter, then the
-        // ///   encoding used is IBM437, which is the default encoding described in the
-        // ///   ZIP specification.  </para>
-        // ///
-        // /// <para>
-        // ///   If the entry is being created, then the value of ActualEncoding is taken
-        // ///   according to the logic described in the documentation for <see
-        // ///   cref="ZipFile.ProvisionalAlternateEncoding" />.  </para>
-        // ///
-        // /// <para>
-        // ///   An application might be interested in retrieving this property to see if
-        // ///   an entry read in from a file has used Unicode (UTF-8).  </para>
-        // ///
-        // /// </remarks>
-        // ///
-        // /// <seealso cref="ZipFile.ProvisionalAlternateEncoding" />
-        // public System.Text.Encoding ActualEncoding
-        // {
-        //     get
-        //     {
-        //         return _actualEncoding;
-        //     }
-        // }
-
-
-
-
-        internal static string NameInArchive(String filename, string directoryPathInArchive)
-        {
-            string result = null;
-            if (directoryPathInArchive == null)
-                result = filename;
-
-            else
-            {
-                if (String.IsNullOrEmpty(directoryPathInArchive))
-                {
-                    result = Path.GetFileName(filename);
-                }
-                else
-                {
-                    // explicitly specify a pathname for this file
-                    result = Path.Combine(directoryPathInArchive, Path.GetFileName(filename));
-                }
-            }
-
-            //result = Path.GetFullPath(result);
-            result = SharedUtilities.NormalizePathForUseInZipFile(result);
-
-            return result;
-        }
-
-        // workitem 9073
-        internal static ZipEntry CreateFromNothing(String nameInArchive)
-        {
-            return Create(nameInArchive, ZipEntrySource.None, null, null);
-        }
-
-        internal static ZipEntry CreateFromFile(String filename, string nameInArchive)
-        {
-            return Create(nameInArchive, ZipEntrySource.FileSystem, filename, null);
-        }
-
-        internal static ZipEntry CreateForStream(String entryName, Stream s)
-        {
-            return Create(entryName, ZipEntrySource.Stream, s, null);
-        }
-
-        internal static ZipEntry CreateForWriter(String entryName, WriteDelegate d)
-        {
-            return Create(entryName, ZipEntrySource.WriteDelegate, d, null);
-        }
-
-        internal static ZipEntry CreateForJitStreamProvider(string nameInArchive, OpenDelegate opener, CloseDelegate closer)
-        {
-            return Create(nameInArchive, ZipEntrySource.JitStream, opener, closer);
-        }
-
-        internal static ZipEntry CreateForZipOutputStream(string nameInArchive)
-        {
-            return Create(nameInArchive, ZipEntrySource.ZipOutputStream, null, null);
-        }
-
-
-        private static ZipEntry Create(string nameInArchive, ZipEntrySource source, Object arg1, Object arg2)
-        {
-            if (String.IsNullOrEmpty(nameInArchive))
-                throw new Ionic.Zip.ZipException("The entry name must be non-null and non-empty.");
-
-            ZipEntry entry = new ZipEntry();
-
-            // workitem 7071
-            // workitem 7926 - "version made by" OS should be zero for compat with WinZip
-            entry._VersionMadeBy = (0 << 8) + 45; // indicates the attributes are FAT Attributes, and v4.5 of the spec
-            entry._Source = source;
-            entry._Mtime = entry._Atime = entry._Ctime = DateTime.UtcNow;
-
-            if (source == ZipEntrySource.Stream)
-            {
-                entry._sourceStream = (arg1 as Stream);         // may  or may not be null
-            }
-            else if (source == ZipEntrySource.WriteDelegate)
-            {
-                entry._WriteDelegate = (arg1 as WriteDelegate); // may  or may not be null
-            }
-            else if (source == ZipEntrySource.JitStream)
-            {
-                entry._OpenDelegate = (arg1 as OpenDelegate);   // may  or may not be null
-                entry._CloseDelegate = (arg2 as CloseDelegate); // may  or may not be null
-            }
-            else if (source == ZipEntrySource.ZipOutputStream)
-            {
-            }
-            // workitem 9073
-            else if (source == ZipEntrySource.None)
-            {
-                // make this a valid value, for later.
-                entry._Source = ZipEntrySource.FileSystem;
-            }
-            else
-            {
-                String filename = (arg1 as String);   // must not be null
-
-                if (String.IsNullOrEmpty(filename))
-                    throw new Ionic.Zip.ZipException("The filename must be non-null and non-empty.");
-
-                try
-                {
-                    // The named file may or may not exist at this time.  For
-                    // example, when adding a directory by name.  We test existence
-                    // when necessary: when saving the ZipFile, or when getting the
-                    // attributes, and so on.
-
-#if NETCF
-                    // workitem 6878
-                    // Ionic.Zip.SharedUtilities.AdjustTime_Win32ToDotNet
-                    entry._Mtime = File.GetLastWriteTime(filename).ToUniversalTime();
-                    entry._Ctime = File.GetCreationTime(filename).ToUniversalTime();
-                    entry._Atime = File.GetLastAccessTime(filename).ToUniversalTime();
-
-                    // workitem 7071
-                    // can only get attributes of files that exist.
-                    if (File.Exists(filename) || Directory.Exists(filename))
-                        entry._ExternalFileAttrs = (int)NetCfFile.GetAttributes(filename);
-
-#elif SILVERLIGHT
-                    entry._Mtime =
-                        entry._Ctime =
-                        entry._Atime = System.DateTime.UtcNow;
-                    entry._ExternalFileAttrs = (int)0;
-#else
-                    // workitem 6878??
-                    entry._Mtime = File.GetLastWriteTime(filename).ToUniversalTime();
-                    entry._Ctime = File.GetCreationTime(filename).ToUniversalTime();
-                    entry._Atime = File.GetLastAccessTime(filename).ToUniversalTime();
-
-                    // workitem 7071
-                    // can only get attributes on files that exist.
-                    if (File.Exists(filename) || Directory.Exists(filename))
-                        entry._ExternalFileAttrs = (int)File.GetAttributes(filename);
-
-#endif
-                    entry._ntfsTimesAreSet = true;
-
-                    entry._LocalFileName = Path.GetFullPath(filename); // workitem 8813
-
-                }
-                catch (System.IO.PathTooLongException ptle)
-                {
-                    // workitem 14035
-                    var msg = String.Format("The path is too long, filename={0}",
-                                            filename);
-                    throw new ZipException(msg, ptle);
-                }
-
-            }
-
-            entry._LastModified = entry._Mtime;
-            entry._FileNameInArchive = SharedUtilities.NormalizePathForUseInZipFile(nameInArchive);
-            // We don't actually slurp in the file data until the caller invokes Write on this entry.
-
-            return entry;
-        }
-
-
-
-
-        internal void MarkAsDirectory()
-        {
-            _IsDirectory = true;
-            // workitem 6279
-            if (!_FileNameInArchive.EndsWith("/"))
-                _FileNameInArchive += "/";
-        }
-
-
-
-        /// <summary>
-        ///   Indicates whether an entry is marked as a text file. Be careful when
-        ///   using on this property. Unless you have a good reason, you should
-        ///   probably ignore this property.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The ZIP format includes a provision for specifying whether an entry in
-        ///   the zip archive is a text or binary file.  This property exposes that
-        ///   metadata item. Be careful when using this property: It's not clear
-        ///   that this property as a firm meaning, across tools and libraries.
-        /// </para>
-        ///
-        /// <para>
-        ///   To be clear, when reading a zip file, the property value may or may
-        ///   not be set, and its value may or may not be valid.  Not all entries
-        ///   that you may think of as "text" entries will be so marked, and entries
-        ///   marked as "text" are not guaranteed in any way to be text entries.
-        ///   Whether the value is set and set correctly depends entirely on the
-        ///   application that produced the zip file.
-        /// </para>
-        ///
-        /// <para>
-        ///   There are many zip tools available, and when creating zip files, some
-        ///   of them "respect" the IsText metadata field, and some of them do not.
-        ///   Unfortunately, even when an application tries to do "the right thing",
-        ///   it's not always clear what "the right thing" is.
-        /// </para>
-        ///
-        /// <para>
-        ///   There's no firm definition of just what it means to be "a text file",
-        ///   and the zip specification does not help in this regard. Twenty years
-        ///   ago, text was ASCII, each byte was less than 127. IsText meant, all
-        ///   bytes in the file were less than 127.  These days, it is not the case
-        ///   that all text files have all bytes less than 127.  Any unicode file
-        ///   may have bytes that are above 0x7f.  The zip specification has nothing
-        ///   to say on this topic. Therefore, it's not clear what IsText really
-        ///   means.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property merely tells a reading application what is stored in the
-        ///   metadata for an entry, without guaranteeing its validity or its
-        ///   meaning.
-        /// </para>
-        ///
-        /// <para>
-        ///   When DotNetZip is used to create a zipfile, it attempts to set this
-        ///   field "correctly." For example, if a file ends in ".txt", this field
-        ///   will be set. Your application may override that default setting.  When
-        ///   writing a zip file, you must set the property before calling
-        ///   <c>Save()</c> on the ZipFile.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading a zip file, a more general way to decide just what kind
-        ///   of file is contained in a particular entry is to use the file type
-        ///   database stored in the operating system.  The operating system stores
-        ///   a table that says, a file with .jpg extension is a JPG image file, a
-        ///   file with a .xml extension is an XML document, a file with a .txt is a
-        ///   pure ASCII text document, and so on.  To get this information on
-        ///   Windows, <see
-        ///   href="http://www.codeproject.com/KB/cs/GetFileTypeAndIcon.aspx"> you
-        ///   need to read and parse the registry.</see> </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code>
-        /// using (var zip = new ZipFile())
-        /// {
-        ///     var e = zip.UpdateFile("Descriptions.mme", "");
-        ///     e.IsText = true;
-        ///     zip.Save(zipPath);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     Dim e2 as ZipEntry = zip.AddFile("Descriptions.mme", "")
-        ///     e.IsText= True
-        ///     zip.Save(zipPath)
-        /// End Using
-        /// </code>
-        /// </example>
-        public bool IsText
-        {
-            // workitem 7801
-            get { return _IsText; }
-            set { _IsText = value; }
-        }
-
-
-
-        /// <summary>Provides a string representation of the instance.</summary>
-        /// <returns>a string representation of the instance.</returns>
-        public override String ToString()
-        {
-            return String.Format("ZipEntry::{0}", FileName);
-        }
-
-
-        internal Stream ArchiveStream
-        {
-            get
-            {
-                if (_archiveStream == null)
-                {
-                    if (_container.ZipFile != null)
-                    {
-                        var zf = _container.ZipFile;
-                        zf.Reset(false);
-                        _archiveStream = zf.StreamForDiskNumber(_diskNumber);
-                    }
-                    else
-                    {
-                        _archiveStream = _container.ZipOutputStream.OutputStream;
-                    }
-                }
-                return _archiveStream;
-            }
-        }
-
-
-        private void SetFdpLoh()
-        {
-            // The value for FileDataPosition has not yet been set.
-            // Therefore, seek to the local header, and figure the start of file data.
-            // workitem 8098: ok (restore)
-            long origPosition = this.ArchiveStream.Position;
-            try
-            {
-                this.ArchiveStream.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-            }
-            catch (System.IO.IOException exc1)
-            {
-                string description = String.Format("Exception seeking  entry({0}) offset(0x{1:X8}) len(0x{2:X8})",
-                                                   this.FileName, this._RelativeOffsetOfLocalHeader,
-                                                   this.ArchiveStream.Length);
-                throw new BadStateException(description, exc1);
-            }
-
-            byte[] block = new byte[30];
-            this.ArchiveStream.Read(block, 0, block.Length);
-
-            // At this point we could verify the contents read from the local header
-            // with the contents read from the central header.  We could, but don't need to.
-            // So we won't.
-
-            Int16 filenameLength = (short)(block[26] + block[27] * 256);
-            Int16 extraFieldLength = (short)(block[28] + block[29] * 256);
-
-            // Console.WriteLine("  pos  0x{0:X8} ({0})", this.ArchiveStream.Position);
-            // Console.WriteLine("  seek 0x{0:X8} ({0})", filenameLength + extraFieldLength);
-
-            this.ArchiveStream.Seek(filenameLength + extraFieldLength, SeekOrigin.Current);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
-            this._LengthOfHeader = 30 + extraFieldLength + filenameLength +
-                GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
-
-            // Console.WriteLine("  ROLH  0x{0:X8} ({0})", _RelativeOffsetOfLocalHeader);
-            // Console.WriteLine("  LOH   0x{0:X8} ({0})", _LengthOfHeader);
-            // workitem 8098: ok (arithmetic)
-            this.__FileDataPosition = _RelativeOffsetOfLocalHeader + _LengthOfHeader;
-            // Console.WriteLine("  FDP   0x{0:X8} ({0})", __FileDataPosition);
-
-            // restore file position:
-            // workitem 8098: ok (restore)
-            this.ArchiveStream.Seek(origPosition, SeekOrigin.Begin);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-        }
-
-
-
-#if AESCRYPTO
-        private static int GetKeyStrengthInBits(EncryptionAlgorithm a)
-        {
-            if (a == EncryptionAlgorithm.WinZipAes256) return 256;
-            else if (a == EncryptionAlgorithm.WinZipAes128) return 128;
-            return -1;
-        }
-#endif
-
-        internal static int GetLengthOfCryptoHeaderBytes(EncryptionAlgorithm a)
-        {
-            //if ((_BitField & 0x01) != 0x01) return 0;
-            if (a == EncryptionAlgorithm.None) return 0;
-
-#if AESCRYPTO
-            if (a == EncryptionAlgorithm.WinZipAes128 ||
-                a == EncryptionAlgorithm.WinZipAes256)
-            {
-                int KeyStrengthInBits = GetKeyStrengthInBits(a);
-                int sizeOfSaltAndPv = ((KeyStrengthInBits / 8 / 2) + 2);
-                return sizeOfSaltAndPv;
-            }
-#endif
-            if (a == EncryptionAlgorithm.PkzipWeak)
-                return 12;
-            throw new ZipException("internal error");
-        }
-
-
-        internal long FileDataPosition
-        {
-            get
-            {
-                if (__FileDataPosition == -1)
-                    SetFdpLoh();
-
-                return __FileDataPosition;
-            }
-        }
-
-        private int LengthOfHeader
-        {
-            get
-            {
-                if (_LengthOfHeader == 0)
-                    SetFdpLoh();
-
-                return _LengthOfHeader;
-            }
-        }
-
-
-
-        private ZipCrypto _zipCrypto_forExtract;
-        private ZipCrypto _zipCrypto_forWrite;
-#if AESCRYPTO
-        private WinZipAesCrypto _aesCrypto_forExtract;
-        private WinZipAesCrypto _aesCrypto_forWrite;
-        private Int16 _WinZipAesMethod;
-#endif
-
-        internal DateTime _LastModified;
-        private DateTime _Mtime, _Atime, _Ctime;  // workitem 6878: NTFS quantities
-        private bool _ntfsTimesAreSet;
-        private bool _emitNtfsTimes = true;
-        private bool _emitUnixTimes;  // by default, false
-        private bool _TrimVolumeFromFullyQualifiedPaths = true;  // by default, trim them.
-        internal string _LocalFileName;
-        private string _FileNameInArchive;
-        internal Int16 _VersionNeeded;
-        internal Int16 _BitField;
-        internal Int16 _CompressionMethod;
-        private Int16 _CompressionMethod_FromZipFile;
-        private Ionic.Zlib.CompressionLevel _CompressionLevel;
-        internal string _Comment;
-        private bool _IsDirectory;
-        private byte[] _CommentBytes;
-        internal Int64 _CompressedSize;
-        internal Int64 _CompressedFileDataSize; // CompressedSize less 12 bytes for the encryption header, if any
-        internal Int64 _UncompressedSize;
-        internal Int32 _TimeBlob;
-        private bool _crcCalculated;
-        internal Int32 _Crc32;
-        internal byte[] _Extra;
-        private bool _metadataChanged;
-        private bool _restreamRequiredOnSave;
-        private bool _sourceIsEncrypted;
-        private bool _skippedDuringSave;
-        private UInt32 _diskNumber;
-
-        private static System.Text.Encoding ibm437 = System.Text.Encoding.ASCII;
-        //private System.Text.Encoding _provisionalAlternateEncoding = System.Text.Encoding.ASCII;
-        private System.Text.Encoding _actualEncoding;
-
-        internal ZipContainer _container;
-
-        private long __FileDataPosition = -1;
-        private byte[] _EntryHeader;
-        internal Int64 _RelativeOffsetOfLocalHeader;
-        private Int64 _future_ROLH;
-        private Int64 _TotalEntrySize;
-        private int _LengthOfHeader;
-        private int _LengthOfTrailer;
-        internal bool _InputUsesZip64;
-        private UInt32 _UnsupportedAlgorithmId;
-
-        internal string _Password;
-        internal ZipEntrySource _Source;
-        internal EncryptionAlgorithm _Encryption;
-        internal EncryptionAlgorithm _Encryption_FromZipFile;
-        internal byte[] _WeakEncryptionHeader;
-        internal Stream _archiveStream;
-        private Stream _sourceStream;
-        private Nullable<Int64> _sourceStreamOriginalPosition;
-        private bool _sourceWasJitProvided;
-        private bool _ioOperationCanceled;
-        private bool _presumeZip64;
-        private Nullable<bool> _entryRequiresZip64;
-        private Nullable<bool> _OutputUsesZip64;
-        private bool _IsText; // workitem 7801
-        private ZipEntryTimestamp _timestamp;
-
-        private static System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-        private static System.DateTime _win32Epoch = System.DateTime.FromFileTimeUtc(0L);
-        private static System.DateTime _zeroHour = new System.DateTime(1, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
-        private WriteDelegate _WriteDelegate;
-        private OpenDelegate _OpenDelegate;
-        private CloseDelegate _CloseDelegate;
-
-
-        // summary
-        // The default size of the IO buffer for ZipEntry instances. Currently it is 8192 bytes.
-        // summary
-        //public const int IO_BUFFER_SIZE_DEFAULT = 8192; // 0x8000; // 0x4400
-
-    }
-
-
-
-    /// <summary>
-    ///   An enum that specifies the type of timestamp available on the ZipEntry.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///
-    /// <para>
-    ///   The last modified time of a file can be stored in multiple ways in
-    ///   a zip file, and they are not mutually exclusive:
-    /// </para>
-    ///
-    /// <list type="bullet">
-    ///   <item>
-    ///     In the so-called "DOS" format, which has a 2-second precision. Values
-    ///     are rounded to the nearest even second. For example, if the time on the
-    ///     file is 12:34:43, then it will be stored as 12:34:44. This first value
-    ///     is accessible via the <c>LastModified</c> property. This value is always
-    ///     present in the metadata for each zip entry.  In some cases the value is
-    ///     invalid, or zero.
-    ///   </item>
-    ///
-    ///   <item>
-    ///     In the so-called "Windows" or "NTFS" format, as an 8-byte integer
-    ///     quantity expressed as the number of 1/10 milliseconds (in other words
-    ///     the number of 100 nanosecond units) since January 1, 1601 (UTC).  This
-    ///     format is how Windows represents file times.  This time is accessible
-    ///     via the <c>ModifiedTime</c> property.
-    ///   </item>
-    ///
-    ///   <item>
-    ///     In the "Unix" format, a 4-byte quantity specifying the number of seconds since
-    ///     January 1, 1970 UTC.
-    ///   </item>
-    ///
-    ///   <item>
-    ///     In an older format, now deprecated but still used by some current
-    ///     tools. This format is also a 4-byte quantity specifying the number of
-    ///     seconds since January 1, 1970 UTC.
-    ///   </item>
-    ///
-    /// </list>
-    ///
-    /// <para>
-    ///   This bit field describes which of the formats were found in a <c>ZipEntry</c> that was read.
-    /// </para>
-    ///
-    /// </remarks>
-    [Flags]
-    internal enum ZipEntryTimestamp
-    {
-        /// <summary>
-        /// Default value.
-        /// </summary>
-        None = 0,
-
-        /// <summary>
-        /// A DOS timestamp with 2-second precision.
-        /// </summary>
-        DOS = 1,
-
-        /// <summary>
-        /// A Windows timestamp with 100-ns precision.
-        /// </summary>
-        Windows = 2,
-
-        /// <summary>
-        /// A Unix timestamp with 1-second precision.
-        /// </summary>
-        Unix = 4,
-
-        /// <summary>
-        /// A Unix timestamp with 1-second precision, stored in InfoZip v1 format.  This
-        /// format is outdated and is supported for reading archives only.
-        /// </summary>
-        InfoZip1 = 8,
-    }
-
-
-
-    /// <summary>
-    ///   The method of compression to use for a particular ZipEntry.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///   <see
-    ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWare's
-    ///   ZIP Specification</see> describes a number of distinct
-    ///   cmopression methods that can be used within a zip
-    ///   file. DotNetZip supports a subset of them.
-    /// </remarks>
-    internal enum CompressionMethod
-    {
-        /// <summary>
-        /// No compression at all. For COM environments, the value is 0 (zero).
-        /// </summary>
-        None = 0,
-
-        /// <summary>
-        ///   DEFLATE compression, as described in <see
-        ///   href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC
-        ///   1951</see>.  This is the "normal" compression used in zip
-        ///   files. For COM environments, the value is 8.
-        /// </summary>
-        Deflate = 8,
-
-#if BZIP
-        /// <summary>
-        ///   BZip2 compression, a compression algorithm developed by Julian Seward.
-        ///   For COM environments, the value is 12.
-        /// </summary>
-        BZip2 = 12,
-#endif
-    }
-
-
-#if NETCF
-    internal class NetCfFile
-    {
-        public static int SetTimes(string filename, DateTime ctime, DateTime atime, DateTime mtime)
-        {
-            IntPtr hFile  = (IntPtr) CreateFileCE(filename,
-                                                  (uint)0x40000000L, // (uint)FileAccess.Write,
-                                                  (uint)0x00000002L, // (uint)FileShare.Write,
-                                                  0,
-                                                  (uint) 3,  // == open existing
-                                                  (uint)0, // flagsAndAttributes
-                                                  0);
-
-            if((int)hFile == -1)
-            {
-                // workitem 7944: don't throw on failure to set file times
-                // throw new ZipException("CreateFileCE Failed");
-                return Interop.Marshal.GetLastWin32Error();
-            }
-
-            SetFileTime(hFile,
-                        BitConverter.GetBytes(ctime.ToFileTime()),
-                        BitConverter.GetBytes(atime.ToFileTime()),
-                        BitConverter.GetBytes(mtime.ToFileTime()));
-
-            CloseHandle(hFile);
-            return 0;
-        }
-
-
-        public static int SetLastWriteTime(string filename, DateTime mtime)
-        {
-            IntPtr hFile  = (IntPtr) CreateFileCE(filename,
-                                                  (uint)0x40000000L, // (uint)FileAccess.Write,
-                                                  (uint)0x00000002L, // (uint)FileShare.Write,
-                                                  0,
-                                                  (uint) 3,  // == open existing
-                                                  (uint)0, // flagsAndAttributes
-                                                  0);
-
-            if((int)hFile == -1)
-            {
-                // workitem 7944: don't throw on failure to set file time
-                // throw new ZipException(String.Format("CreateFileCE Failed ({0})",
-                //                                      Interop.Marshal.GetLastWin32Error()));
-                return Interop.Marshal.GetLastWin32Error();
-            }
-
-            SetFileTime(hFile, null, null,
-                        BitConverter.GetBytes(mtime.ToFileTime()));
-
-            CloseHandle(hFile);
-            return 0;
-        }
-
-
-        [Interop.DllImport("coredll.dll", EntryPoint="CreateFile", SetLastError=true)]
-        internal static extern int CreateFileCE(string lpFileName,
-                                                uint dwDesiredAccess,
-                                                uint dwShareMode,
-                                                int lpSecurityAttributes,
-                                                uint dwCreationDisposition,
-                                                uint dwFlagsAndAttributes,
-                                                int hTemplateFile);
-
-
-        [Interop.DllImport("coredll", EntryPoint="GetFileAttributes", SetLastError=true)]
-        internal static extern uint GetAttributes(string lpFileName);
-
-        [Interop.DllImport("coredll", EntryPoint="SetFileAttributes", SetLastError=true)]
-        internal static extern bool SetAttributes(string lpFileName, uint dwFileAttributes);
-
-        [Interop.DllImport("coredll", EntryPoint="SetFileTime", SetLastError=true)]
-        internal static extern bool SetFileTime(IntPtr hFile, byte[] lpCreationTime, byte[] lpLastAccessTime, byte[] lpLastWriteTime);
-
-        [Interop.DllImport("coredll.dll", SetLastError=true)]
-        internal static extern bool CloseHandle(IntPtr hObject);
-
-    }
-#endif
-
-
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipEntrySource.cs b/EPPlus/Packaging/DotNetZip/ZipEntrySource.cs
deleted file mode 100644
index eb90a18..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipEntrySource.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// ZipEntrySource.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: <2009-November-19 11:18:42>
-//
-// ------------------------------------------------------------------
-//
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    /// An enum that specifies the source of the ZipEntry. 
-    /// </summary>
-    internal enum ZipEntrySource
-    {
-        /// <summary>
-        /// Default value.  Invalid on a bonafide ZipEntry.
-        /// </summary>
-        None = 0,
-
-        /// <summary>
-        /// The entry was instantiated by calling AddFile() or another method that 
-        /// added an entry from the filesystem.
-        /// </summary>
-        FileSystem,
-
-        /// <summary>
-        /// The entry was instantiated via <see cref="Ionic.Zip.ZipFile.AddEntry(string,string)"/> or
-        /// <see cref="Ionic.Zip.ZipFile.AddEntry(string,System.IO.Stream)"/> .
-        /// </summary>
-        Stream,
-
-        /// <summary>
-        /// The ZipEntry was instantiated by reading a zipfile.
-        /// </summary>
-        ZipFile,
-        
-        /// <summary>
-        /// The content for the ZipEntry will be or was provided by the WriteDelegate.
-        /// </summary>
-        WriteDelegate,
-        
-        /// <summary>
-        /// The content for the ZipEntry will be obtained from the stream dispensed by the <c>OpenDelegate</c>.
-        /// The entry was instantiated via <see cref="Ionic.Zip.ZipFile.AddEntry(string,OpenDelegate,CloseDelegate)"/>.
-        /// </summary>
-        JitStream,
-        
-        /// <summary>
-        /// The content for the ZipEntry will be or was obtained from a <c>ZipOutputStream</c>.
-        /// </summary>
-        ZipOutputStream,
-    }
-    
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/ZipErrorAction.cs b/EPPlus/Packaging/DotNetZip/ZipErrorAction.cs
deleted file mode 100644
index f8894dd..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipErrorAction.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-// ZipErrorAction.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: <2009-September-01 18:43:20>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZipErrorAction enum, which provides
-// an action to take when errors occur when opening or reading
-// files to be added to a zip file. 
-// 
-// ------------------------------------------------------------------
-
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    /// An enum providing the options when an error occurs during opening or reading
-    /// of a file or directory that is being saved to a zip file. 
-    /// </summary>
-    ///
-    /// <remarks>
-    ///  <para>
-    ///    This enum describes the actions that the library can take when an error occurs
-    ///    opening or reading a file, as it is being saved into a Zip archive. 
-    ///  </para>
-    ///
-    ///  <para>
-    ///     In some cases an error will occur when DotNetZip tries to open a file to be
-    ///     added to the zip archive.  In other cases, an error might occur after the
-    ///     file has been successfully opened, while DotNetZip is reading the file.
-    ///  </para>
-    /// 
-    ///  <para>
-    ///    The first problem might occur when calling AddDirectory() on a directory
-    ///    that contains a Clipper .dbf file; the file is locked by Clipper and
-    ///    cannot be opened by another process. An example of the second problem is
-    ///    the ERROR_LOCK_VIOLATION that results when a file is opened by another
-    ///    process, but not locked, and a range lock has been taken on the file.
-    ///    Microsoft Outlook takes range locks on .PST files.
-    ///  </para>
-    /// </remarks>
-    internal enum ZipErrorAction
-    {
-        /// <summary>
-        /// Throw an exception when an error occurs while zipping.  This is the default
-        /// behavior.  (For COM clients, this is a 0 (zero).)
-        /// </summary>
-        Throw,
-
-        /// <summary>
-        /// When an error occurs during zipping, for example a file cannot be opened,
-        /// skip the file causing the error, and continue zipping.  (For COM clients,
-        /// this is a 1.)
-        /// </summary>
-        Skip,
-        
-        /// <summary>
-        /// When an error occurs during zipping, for example a file cannot be opened,
-        /// retry the operation that caused the error. Be careful with this option. If
-        /// the error is not temporary, the library will retry forever.  (For COM
-        /// clients, this is a 2.)
-        /// </summary>
-        Retry,
-
-        /// <summary>
-        /// When an error occurs, invoke the zipError event.  The event type used is
-        /// <see cref="ZipProgressEventType.Error_Saving"/>.  A typical use of this option:
-        /// a GUI application may wish to pop up a dialog to allow the user to view the
-        /// error that occurred, and choose an appropriate action.  After your
-        /// processing in the error event, if you want to skip the file, set <see
-        /// cref="ZipEntry.ZipErrorAction"/> on the
-        /// <c>ZipProgressEventArgs.CurrentEntry</c> to <c>Skip</c>.  If you want the
-        /// exception to be thrown, set <c>ZipErrorAction</c> on the <c>CurrentEntry</c>
-        /// to <c>Throw</c>.  If you want to cancel the zip, set
-        /// <c>ZipProgressEventArgs.Cancel</c> to true.  Cancelling differs from using
-        /// Skip in that a cancel will not save any further entries, if there are any.
-        /// (For COM clients, the value of this enum is a 3.)
-        /// </summary>
-        InvokeErrorEvent,
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.AddUpdate.cs b/EPPlus/Packaging/DotNetZip/ZipFile.AddUpdate.cs
deleted file mode 100644
index 46e9588..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.AddUpdate.cs
+++ /dev/null
@@ -1,2182 +0,0 @@
-// ZipFile.AddUpdate.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-November-01 13:56:58>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for Adding and Updating entries in
-// the ZipFile.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal partial class ZipFile
-    {
-        /// <summary>
-        ///   Adds an item, either a file or a directory, to a zip file archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method is handy if you are adding things to zip archive and don't
-        ///   want to bother distinguishing between directories or files.  Any files are
-        ///   added as single entries.  A directory added through this method is added
-        ///   recursively: all files and subdirectories contained within the directory
-        ///   are added to the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   The name of the item may be a relative path or a fully-qualified
-        ///   path. Remember, the items contained in <c>ZipFile</c> instance get written
-        ///   to the disk only when you call <see cref="ZipFile.Save()"/> or a similar
-        ///   save method.
-        /// </para>
-        ///
-        /// <para>
-        ///   The directory name used for the file within the archive is the same
-        ///   as the directory name (potentially a relative path) specified in the
-        ///   <paramref name="fileOrDirectoryName"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddFile(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string)"/>
-        ///
-        /// <overloads>This method has two overloads.</overloads>
-        /// <param name="fileOrDirectoryName">
-        /// the name of the file or directory to add.</param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddItem(string fileOrDirectoryName)
-        {
-            return AddItem(fileOrDirectoryName, null);
-        }
-
-
-        /// <summary>
-        ///   Adds an item, either a file or a directory, to a zip file archive,
-        ///   explicitly specifying the directory path to be used in the archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   If adding a directory, the add is recursive on all files and
-        ///   subdirectories contained within it.
-        /// </para>
-        /// <para>
-        ///   The name of the item may be a relative path or a fully-qualified path.
-        ///   The item added by this call to the <c>ZipFile</c> is not read from the
-        ///   disk nor written to the zip file archive until the application calls
-        ///   Save() on the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This version of the method allows the caller to explicitly specify the
-        ///   directory path to be used in the archive, which would override the
-        ///   "natural" path of the filesystem file.
-        /// </para>
-        ///
-        /// <para>
-        ///   Encryption will be used on the file data if the <c>Password</c> has
-        ///   been set on the <c>ZipFile</c> object, prior to calling this method.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="System.IO.FileNotFoundException">
-        ///   Thrown if the file or directory passed in does not exist.
-        /// </exception>
-        ///
-        /// <param name="fileOrDirectoryName">the name of the file or directory to add.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   The name of the directory path to use within the zip archive.  This path
-        ///   need not refer to an extant directory in the current filesystem.  If the
-        ///   files within the zip are later extracted, this is the path used for the
-        ///   extracted file.  Passing <c>null</c> (<c>Nothing</c> in VB) will use the
-        ///   path on the fileOrDirectoryName.  Passing the empty string ("") will
-        ///   insert the item at the root path within the archive.
-        /// </param>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddFile(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string, string)"/>
-        ///
-        /// <example>
-        ///   This example shows how to zip up a set of files into a flat hierarchy,
-        ///   regardless of where in the filesystem the files originated. The resulting
-        ///   zip archive will contain a toplevel directory named "flat", which itself
-        ///   will contain files Readme.txt, MyProposal.docx, and Image1.jpg.  A
-        ///   subdirectory under "flat" called SupportFiles will contain all the files
-        ///   in the "c:\SupportFiles" directory on disk.
-        ///
-        /// <code>
-        /// String[] itemnames= {
-        ///   "c:\\fixedContent\\Readme.txt",
-        ///   "MyProposal.docx",
-        ///   "c:\\SupportFiles",  // a directory
-        ///   "images\\Image1.jpg"
-        /// };
-        ///
-        /// try
-        /// {
-        ///   using (ZipFile zip = new ZipFile())
-        ///   {
-        ///     for (int i = 1; i &lt; itemnames.Length; i++)
-        ///     {
-        ///       // will add Files or Dirs, recurses and flattens subdirectories
-        ///       zip.AddItem(itemnames[i],"flat");
-        ///     }
-        ///     zip.Save(ZipToCreate);
-        ///   }
-        /// }
-        /// catch (System.Exception ex1)
-        /// {
-        ///   System.Console.Error.WriteLine("exception: {0}", ex1);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        ///   Dim itemnames As String() = _
-        ///     New String() { "c:\fixedContent\Readme.txt", _
-        ///                    "MyProposal.docx", _
-        ///                    "SupportFiles", _
-        ///                    "images\Image1.jpg" }
-        ///   Try
-        ///       Using zip As New ZipFile
-        ///           Dim i As Integer
-        ///           For i = 1 To itemnames.Length - 1
-        ///               ' will add Files or Dirs, recursing and flattening subdirectories.
-        ///               zip.AddItem(itemnames(i), "flat")
-        ///           Next i
-        ///           zip.Save(ZipToCreate)
-        ///       End Using
-        ///   Catch ex1 As Exception
-        ///       Console.Error.WriteLine("exception: {0}", ex1.ToString())
-        ///   End Try
-        /// </code>
-        /// </example>
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddItem(String fileOrDirectoryName, String directoryPathInArchive)
-        {
-            if (File.Exists(fileOrDirectoryName))
-                return AddFile(fileOrDirectoryName, directoryPathInArchive);
-
-            if (Directory.Exists(fileOrDirectoryName))
-                return AddDirectory(fileOrDirectoryName, directoryPathInArchive);
-
-            throw new FileNotFoundException(String.Format("That file or directory ({0}) does not exist!",
-                                                          fileOrDirectoryName));
-        }
-
-        /// <summary>
-        ///   Adds a File to a Zip file archive.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This call collects metadata for the named file in the filesystem,
-        ///   including the file attributes and the timestamp, and inserts that metadata
-        ///   into the resulting ZipEntry.  Only when the application calls Save() on
-        ///   the <c>ZipFile</c>, does DotNetZip read the file from the filesystem and
-        ///   then write the content to the zip file archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   This method will throw an exception if an entry with the same name already
-        ///   exists in the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   In this example, three files are added to a Zip archive. The ReadMe.txt
-        ///   file will be placed in the root of the archive. The .png file will be
-        ///   placed in a folder within the zip called photos\personal.  The pdf file
-        ///   will be included into a folder within the zip called Desktop.
-        /// </para>
-        /// <code>
-        ///    try
-        ///    {
-        ///      using (ZipFile zip = new ZipFile())
-        ///      {
-        ///        zip.AddFile("c:\\photos\\personal\\7440-N49th.png");
-        ///        zip.AddFile("c:\\Desktop\\2008-Regional-Sales-Report.pdf");
-        ///        zip.AddFile("ReadMe.txt");
-        ///
-        ///        zip.Save("Package.zip");
-        ///      }
-        ///    }
-        ///    catch (System.Exception ex1)
-        ///    {
-        ///      System.Console.Error.WriteLine("exception: " + ex1);
-        ///    }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        ///  Try
-        ///       Using zip As ZipFile = New ZipFile
-        ///           zip.AddFile("c:\photos\personal\7440-N49th.png")
-        ///           zip.AddFile("c:\Desktop\2008-Regional-Sales-Report.pdf")
-        ///           zip.AddFile("ReadMe.txt")
-        ///           zip.Save("Package.zip")
-        ///       End Using
-        ///   Catch ex1 As Exception
-        ///       Console.Error.WriteLine("exception: {0}", ex1.ToString)
-        ///   End Try
-        /// </code>
-        /// </example>
-        ///
-        /// <overloads>This method has two overloads.</overloads>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddItem(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string)"/>
-        ///
-        /// <param name="fileName">
-        ///   The name of the file to add. It should refer to a file in the filesystem.
-        ///   The name of the file may be a relative path or a fully-qualified path.
-        /// </param>
-        /// <returns>The <c>ZipEntry</c> corresponding to the File added.</returns>
-        public ZipEntry AddFile(string fileName)
-        {
-            return AddFile(fileName, null);
-        }
-
-
-
-
-
-        /// <summary>
-        ///   Adds a File to a Zip file archive, potentially overriding the path to be
-        ///   used within the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The file added by this call to the <c>ZipFile</c> is not written to the
-        ///   zip file archive until the application calls Save() on the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This method will throw an exception if an entry with the same name already
-        ///   exists in the <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This version of the method allows the caller to explicitly specify the
-        ///   directory path to be used in the archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   In this example, three files are added to a Zip archive. The ReadMe.txt
-        ///   file will be placed in the root of the archive. The .png file will be
-        ///   placed in a folder within the zip called images.  The pdf file will be
-        ///   included into a folder within the zip called files\docs, and will be
-        ///   encrypted with the given password.
-        /// </para>
-        /// <code>
-        /// try
-        /// {
-        ///   using (ZipFile zip = new ZipFile())
-        ///   {
-        ///     // the following entry will be inserted at the root in the archive.
-        ///     zip.AddFile("c:\\datafiles\\ReadMe.txt", "");
-        ///     // this image file will be inserted into the "images" directory in the archive.
-        ///     zip.AddFile("c:\\photos\\personal\\7440-N49th.png", "images");
-        ///     // the following will result in a password-protected file called
-        ///     // files\\docs\\2008-Regional-Sales-Report.pdf  in the archive.
-        ///     zip.Password = "EncryptMe!";
-        ///     zip.AddFile("c:\\Desktop\\2008-Regional-Sales-Report.pdf", "files\\docs");
-        ///     zip.Save("Archive.zip");
-        ///   }
-        /// }
-        /// catch (System.Exception ex1)
-        /// {
-        ///   System.Console.Error.WriteLine("exception: {0}", ex1);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        ///   Try
-        ///       Using zip As ZipFile = New ZipFile
-        ///           ' the following entry will be inserted at the root in the archive.
-        ///           zip.AddFile("c:\datafiles\ReadMe.txt", "")
-        ///           ' this image file will be inserted into the "images" directory in the archive.
-        ///           zip.AddFile("c:\photos\personal\7440-N49th.png", "images")
-        ///           ' the following will result in a password-protected file called
-        ///           ' files\\docs\\2008-Regional-Sales-Report.pdf  in the archive.
-        ///           zip.Password = "EncryptMe!"
-        ///           zip.AddFile("c:\Desktop\2008-Regional-Sales-Report.pdf", "files\documents")
-        ///           zip.Save("Archive.zip")
-        ///       End Using
-        ///   Catch ex1 As Exception
-        ///       Console.Error.WriteLine("exception: {0}", ex1)
-        ///   End Try
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddItem(string,string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string,string)"/>
-        ///
-        /// <param name="fileName">
-        ///   The name of the file to add.  The name of the file may be a relative path
-        ///   or a fully-qualified path.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the fileName.
-        ///   This path may, or may not, correspond to a real directory in the current
-        ///   filesystem.  If the files within the zip are later extracted, this is the
-        ///   path used for the extracted file.  Passing <c>null</c> (<c>Nothing</c> in
-        ///   VB) will use the path on the fileName, if any.  Passing the empty string
-        ///   ("") will insert the item at the root path within the archive.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> corresponding to the file added.</returns>
-        public ZipEntry AddFile(string fileName, String directoryPathInArchive)
-        {
-            string nameInArchive = ZipEntry.NameInArchive(fileName, directoryPathInArchive);
-            ZipEntry ze = ZipEntry.CreateFromFile(fileName, nameInArchive);
-            if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", fileName);
-            return _InternalAddEntry(ze);
-        }
-
-
-        /// <summary>
-        ///   This method removes a collection of entries from the <c>ZipFile</c>.
-        /// </summary>
-        ///
-        /// <param name="entriesToRemove">
-        ///   A collection of ZipEntry instances from this zip file to be removed. For
-        ///   example, you can pass in an array of ZipEntry instances; or you can call
-        ///   SelectEntries(), and then add or remove entries from that
-        ///   ICollection&lt;ZipEntry&gt; (ICollection(Of ZipEntry) in VB), and pass
-        ///   that ICollection to this method.
-        /// </param>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.SelectEntries(String)" />
-        /// <seealso cref="Ionic.Zip.ZipFile.RemoveSelectedEntries(String)" />
-        public void RemoveEntries(System.Collections.Generic.ICollection<ZipEntry> entriesToRemove)
-        {
-            if (entriesToRemove == null)
-                throw new ArgumentNullException("entriesToRemove");
-
-            foreach (ZipEntry e in entriesToRemove)
-            {
-                this.RemoveEntry(e);
-            }
-        }
-
-
-        /// <summary>
-        ///   This method removes a collection of entries from the <c>ZipFile</c>, by name.
-        /// </summary>
-        ///
-        /// <param name="entriesToRemove">
-        ///   A collection of strings that refer to names of entries to be removed
-        ///   from the <c>ZipFile</c>.  For example, you can pass in an array or a
-        ///   List of Strings that provide the names of entries to be removed.
-        /// </param>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.SelectEntries(String)" />
-        /// <seealso cref="Ionic.Zip.ZipFile.RemoveSelectedEntries(String)" />
-        public void RemoveEntries(System.Collections.Generic.ICollection<String> entriesToRemove)
-        {
-            if (entriesToRemove == null)
-                throw new ArgumentNullException("entriesToRemove");
-
-            foreach (String e in entriesToRemove)
-            {
-                this.RemoveEntry(e);
-            }
-        }
-
-
-        /// <summary>
-        ///   This method adds a set of files to the <c>ZipFile</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Use this method to add a set of files to the zip archive, in one call.
-        ///   For example, a list of files received from
-        ///   <c>System.IO.Directory.GetFiles()</c> can be added to a zip archive in one
-        ///   call.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to each
-        ///   ZipEntry added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="fileNames">
-        ///   The collection of names of the files to add. Each string should refer to a
-        ///   file in the filesystem. The name of the file may be a relative path or a
-        ///   fully-qualified path.
-        /// </param>
-        ///
-        /// <example>
-        ///   This example shows how to create a zip file, and add a few files into it.
-        /// <code>
-        /// String ZipFileToCreate = "archive1.zip";
-        /// String DirectoryToZip = "c:\\reports";
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///   // Store all files found in the top level directory, into the zip archive.
-        ///   String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
-        ///   zip.AddFiles(filenames);
-        ///   zip.Save(ZipFileToCreate);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim ZipFileToCreate As String = "archive1.zip"
-        /// Dim DirectoryToZip As String = "c:\reports"
-        /// Using zip As ZipFile = New ZipFile
-        ///     ' Store all files found in the top level directory, into the zip archive.
-        ///     Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
-        ///     zip.AddFiles(filenames)
-        ///     zip.Save(ZipFileToCreate)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddSelectedFiles(String, String)" />
-        public void AddFiles(System.Collections.Generic.IEnumerable<String> fileNames)
-        {
-            this.AddFiles(fileNames, null);
-        }
-
-
-        /// <summary>
-        ///   Adds or updates a set of files in the <c>ZipFile</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Any files that already exist in the archive are updated. Any files that
-        ///   don't yet exist in the archive are added.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to each
-        ///   ZipEntry added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="fileNames">
-        ///   The collection of names of the files to update. Each string should refer to a file in
-        ///   the filesystem. The name of the file may be a relative path or a fully-qualified path.
-        /// </param>
-        ///
-        public void UpdateFiles(System.Collections.Generic.IEnumerable<String> fileNames)
-        {
-            this.UpdateFiles(fileNames, null);
-        }
-
-
-        /// <summary>
-        ///   Adds a set of files to the <c>ZipFile</c>, using the
-        ///   specified directory path in the archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Any directory structure that may be present in the
-        ///   filenames contained in the list is "flattened" in the
-        ///   archive.  Each file in the list is added to the archive in
-        ///   the specified top-level directory.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see
-        ///   cref="Encryption"/>, <see cref="Password"/>, <see
-        ///   cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see
-        ///   cref="ExtractExistingFile"/>, <see
-        ///   cref="ZipErrorAction"/>, and <see
-        ///   cref="CompressionLevel"/>, their respective values at the
-        ///   time of this call will be applied to each ZipEntry added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="fileNames">
-        ///   The names of the files to add. Each string should refer to
-        ///   a file in the filesystem.  The name of the file may be a
-        ///   relative path or a fully-qualified path.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the file name.
-        ///   Th is path may, or may not, correspond to a real directory in the current
-        ///   filesystem.  If the files within the zip are later extracted, this is the
-        ///   path used for the extracted file.  Passing <c>null</c> (<c>Nothing</c> in
-        ///   VB) will use the path on each of the <c>fileNames</c>, if any.  Passing
-        ///   the empty string ("") will insert the item at the root path within the
-        ///   archive.
-        /// </param>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddSelectedFiles(String, String)" />
-        public void AddFiles(System.Collections.Generic.IEnumerable<String> fileNames, String directoryPathInArchive)
-        {
-            AddFiles(fileNames, false, directoryPathInArchive);
-        }
-
-
-
-        /// <summary>
-        ///   Adds a set of files to the <c>ZipFile</c>, using the specified directory
-        ///   path in the archive, and preserving the full directory structure in the
-        ///   filenames.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Think of the <paramref name="directoryPathInArchive"/> as a "root" or
-        ///   base directory used in the archive for the files that get added.  when
-        ///   <paramref name="preserveDirHierarchy"/> is true, the hierarchy of files
-        ///   found in the filesystem will be placed, with the hierarchy intact,
-        ///   starting at that root in the archive. When <c>preserveDirHierarchy</c>
-        ///   is false, the path hierarchy of files is flattned, and the flattened
-        ///   set of files gets placed in the root within the archive as specified in
-        ///   <c>directoryPathInArchive</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to each
-        ///   ZipEntry added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="fileNames">
-        ///   The names of the files to add. Each string should refer to a file in the
-        ///   filesystem.  The name of the file may be a relative path or a
-        ///   fully-qualified path.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use as a prefix for each entry name.
-        ///   This path may, or may not, correspond to a real directory in the current
-        ///   filesystem.  If the files within the zip are later extracted, this is the
-        ///   path used for the extracted file.  Passing <c>null</c> (<c>Nothing</c> in
-        ///   VB) will use the path on each of the <c>fileNames</c>, if any.  Passing
-        ///   the empty string ("") will insert the item at the root path within the
-        ///   archive.
-        /// </param>
-        ///
-        /// <param name="preserveDirHierarchy">
-        ///   whether the entries in the zip archive will reflect the directory
-        ///   hierarchy that is present in the various filenames.  For example, if
-        ///   <paramref name="fileNames"/> includes two paths,
-        ///   \Animalia\Chordata\Mammalia\Info.txt and
-        ///   \Plantae\Magnoliophyta\Dicotyledon\Info.txt, then calling this method
-        ///   with <paramref name="preserveDirHierarchy"/> = <c>false</c> will
-        ///   result in an exception because of a duplicate entry name, while
-        ///   calling this method with <paramref name="preserveDirHierarchy"/> =
-        ///   <c>true</c> will result in the full direcory paths being included in
-        ///   the entries added to the ZipFile.
-        /// </param>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddSelectedFiles(String, String)" />
-        public void AddFiles(System.Collections.Generic.IEnumerable<String> fileNames,
-                             bool preserveDirHierarchy,
-                             String directoryPathInArchive)
-        {
-            if (fileNames == null)
-                throw new ArgumentNullException("fileNames");
-
-            _addOperationCanceled = false;
-            OnAddStarted();
-            if (preserveDirHierarchy)
-            {
-                foreach (var f in fileNames)
-                {
-                    if (_addOperationCanceled) break;
-                    if (directoryPathInArchive != null)
-                    {
-                        //string s = SharedUtilities.NormalizePath(Path.Combine(directoryPathInArchive, Path.GetDirectoryName(f)));
-                        string s = Path.GetFullPath(Path.Combine(directoryPathInArchive, Path.GetDirectoryName(f)));
-                        this.AddFile(f, s);
-                    }
-                    else
-                        this.AddFile(f, null);
-                }
-            }
-            else
-            {
-                foreach (var f in fileNames)
-                {
-                    if (_addOperationCanceled) break;
-                    this.AddFile(f, directoryPathInArchive);
-                }
-            }
-            if (!_addOperationCanceled)
-                OnAddCompleted();
-        }
-
-
-        /// <summary>
-        ///   Adds or updates a set of files to the <c>ZipFile</c>, using the specified
-        ///   directory path in the archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Any files that already exist in the archive are updated. Any files that
-        ///   don't yet exist in the archive are added.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to each
-        ///   ZipEntry added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="fileNames">
-        ///   The names of the files to add or update. Each string should refer to a
-        ///   file in the filesystem.  The name of the file may be a relative path or a
-        ///   fully-qualified path.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the file name.
-        ///   This path may, or may not, correspond to a real directory in the current
-        ///   filesystem.  If the files within the zip are later extracted, this is the
-        ///   path used for the extracted file.  Passing <c>null</c> (<c>Nothing</c> in
-        ///   VB) will use the path on each of the <c>fileNames</c>, if any.  Passing
-        ///   the empty string ("") will insert the item at the root path within the
-        ///   archive.
-        /// </param>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddSelectedFiles(String, String)" />
-        public void UpdateFiles(System.Collections.Generic.IEnumerable<String> fileNames, String directoryPathInArchive)
-        {
-            if (fileNames == null)
-                throw new ArgumentNullException("fileNames");
-
-            OnAddStarted();
-            foreach (var f in fileNames)
-                this.UpdateFile(f, directoryPathInArchive);
-            OnAddCompleted();
-        }
-
-
-
-
-        /// <summary>
-        ///   Adds or Updates a File in a Zip file archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method adds a file to a zip archive, or, if the file already exists
-        ///   in the zip archive, this method Updates the content of that given filename
-        ///   in the zip archive.  The <c>UpdateFile</c> method might more accurately be
-        ///   called "AddOrUpdateFile".
-        /// </para>
-        ///
-        /// <para>
-        ///   Upon success, there is no way for the application to learn whether the file
-        ///   was added versus updated.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example shows how to Update an existing entry in a zipfile. The first
-        ///   call to UpdateFile adds the file to the newly-created zip archive.  The
-        ///   second call to UpdateFile updates the content for that file in the zip
-        ///   archive.
-        ///
-        /// <code>
-        /// using (ZipFile zip1 = new ZipFile())
-        /// {
-        ///   // UpdateFile might more accurately be called "AddOrUpdateFile"
-        ///   zip1.UpdateFile("MyDocuments\\Readme.txt");
-        ///   zip1.UpdateFile("CustomerList.csv");
-        ///   zip1.Comment = "This zip archive has been created.";
-        ///   zip1.Save("Content.zip");
-        /// }
-        ///
-        /// using (ZipFile zip2 = ZipFile.Read("Content.zip"))
-        /// {
-        ///   zip2.UpdateFile("Updates\\Readme.txt");
-        ///   zip2.Comment = "This zip archive has been updated: The Readme.txt file has been changed.";
-        ///   zip2.Save();
-        /// }
-        ///
-        /// </code>
-        /// <code lang="VB">
-        ///   Using zip1 As New ZipFile
-        ///       ' UpdateFile might more accurately be called "AddOrUpdateFile"
-        ///       zip1.UpdateFile("MyDocuments\Readme.txt")
-        ///       zip1.UpdateFile("CustomerList.csv")
-        ///       zip1.Comment = "This zip archive has been created."
-        ///       zip1.Save("Content.zip")
-        ///   End Using
-        ///
-        ///   Using zip2 As ZipFile = ZipFile.Read("Content.zip")
-        ///       zip2.UpdateFile("Updates\Readme.txt")
-        ///       zip2.Comment = "This zip archive has been updated: The Readme.txt file has been changed."
-        ///       zip2.Save
-        ///   End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddFile(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateDirectory(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string)"/>
-        ///
-        /// <param name="fileName">
-        ///   The name of the file to add or update. It should refer to a file in the
-        ///   filesystem.  The name of the file may be a relative path or a
-        ///   fully-qualified path.
-        /// </param>
-        ///
-        /// <returns>
-        ///   The <c>ZipEntry</c> corresponding to the File that was added or updated.
-        /// </returns>
-        public ZipEntry UpdateFile(string fileName)
-        {
-            return UpdateFile(fileName, null);
-        }
-
-
-
-        /// <summary>
-        ///   Adds or Updates a File in a Zip file archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method adds a file to a zip archive, or, if the file already exists
-        ///   in the zip archive, this method Updates the content of that given filename
-        ///   in the zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   This version of the method allows the caller to explicitly specify the
-        ///   directory path to be used in the archive.  The entry to be added or
-        ///   updated is found by using the specified directory path, combined with the
-        ///   basename of the specified filename.
-        /// </para>
-        ///
-        /// <para>
-        ///   Upon success, there is no way for the application to learn if the file was
-        ///   added versus updated.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddFile(string,string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateDirectory(string,string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string,string)"/>
-        ///
-        /// <param name="fileName">
-        ///   The name of the file to add or update. It should refer to a file in the
-        ///   filesystem.  The name of the file may be a relative path or a
-        ///   fully-qualified path.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the
-        ///   <c>fileName</c>.  This path may, or may not, correspond to a real
-        ///   directory in the current filesystem.  If the files within the zip are
-        ///   later extracted, this is the path used for the extracted file.  Passing
-        ///   <c>null</c> (<c>Nothing</c> in VB) will use the path on the
-        ///   <c>fileName</c>, if any.  Passing the empty string ("") will insert the
-        ///   item at the root path within the archive.
-        /// </param>
-        ///
-        /// <returns>
-        ///   The <c>ZipEntry</c> corresponding to the File that was added or updated.
-        /// </returns>
-        public ZipEntry UpdateFile(string fileName, String directoryPathInArchive)
-        {
-            // ideally this would all be transactional!
-            var key = ZipEntry.NameInArchive(fileName, directoryPathInArchive);
-            if (this[key] != null)
-                this.RemoveEntry(key);
-            return this.AddFile(fileName, directoryPathInArchive);
-        }
-
-
-
-
-
-        /// <summary>
-        ///   Add or update a directory in a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   If the specified directory does not exist in the archive, then this method
-        ///   is equivalent to calling <c>AddDirectory()</c>.  If the specified
-        ///   directory already exists in the archive, then this method updates any
-        ///   existing entries, and adds any new entries. Any entries that are in the
-        ///   zip archive but not in the specified directory, are left alone.  In other
-        ///   words, the contents of the zip file will be a union of the previous
-        ///   contents and the new files.
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string)"/>
-        ///
-        /// <param name="directoryName">
-        ///   The path to the directory to be added to the zip archive, or updated in
-        ///   the zip archive.
-        /// </param>
-        ///
-        /// <returns>
-        /// The <c>ZipEntry</c> corresponding to the Directory that was added or updated.
-        /// </returns>
-        public ZipEntry UpdateDirectory(string directoryName)
-        {
-            return UpdateDirectory(directoryName, null);
-        }
-
-
-        /// <summary>
-        ///   Add or update a directory in the zip archive at the specified root
-        ///   directory in the archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   If the specified directory does not exist in the archive, then this method
-        ///   is equivalent to calling <c>AddDirectory()</c>.  If the specified
-        ///   directory already exists in the archive, then this method updates any
-        ///   existing entries, and adds any new entries. Any entries that are in the
-        ///   zip archive but not in the specified directory, are left alone.  In other
-        ///   words, the contents of the zip file will be a union of the previous
-        ///   contents and the new files.
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string,string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string,string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string,string)"/>
-        ///
-        /// <param name="directoryName">
-        ///   The path to the directory to be added to the zip archive, or updated
-        ///   in the zip archive.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the
-        ///   <c>directoryName</c>.  This path may, or may not, correspond to a real
-        ///   directory in the current filesystem.  If the files within the zip are
-        ///   later extracted, this is the path used for the extracted file.  Passing
-        ///   <c>null</c> (<c>Nothing</c> in VB) will use the path on the
-        ///   <c>directoryName</c>, if any.  Passing the empty string ("") will insert
-        ///   the item at the root path within the archive.
-        /// </param>
-        ///
-        /// <returns>
-        ///   The <c>ZipEntry</c> corresponding to the Directory that was added or updated.
-        /// </returns>
-        public ZipEntry UpdateDirectory(string directoryName, String directoryPathInArchive)
-        {
-            return this.AddOrUpdateDirectoryImpl(directoryName, directoryPathInArchive, AddOrUpdateAction.AddOrUpdate);
-        }
-
-
-
-
-
-        /// <summary>
-        ///   Add or update a file or directory in the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This is useful when the application is not sure or does not care if the
-        ///   item to be added is a file or directory, and does not know or does not
-        ///   care if the item already exists in the <c>ZipFile</c>. Calling this method
-        ///   is equivalent to calling <c>RemoveEntry()</c> if an entry by the same name
-        ///   already exists, followed calling by <c>AddItem()</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddItem(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateDirectory(string)"/>
-        ///
-        /// <param name="itemName">
-        ///  the path to the file or directory to be added or updated.
-        /// </param>
-        public void UpdateItem(string itemName)
-        {
-            UpdateItem(itemName, null);
-        }
-
-
-        /// <summary>
-        ///   Add or update a file or directory.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method is useful when the application is not sure or does not care if
-        ///   the item to be added is a file or directory, and does not know or does not
-        ///   care if the item already exists in the <c>ZipFile</c>. Calling this method
-        ///   is equivalent to calling <c>RemoveEntry()</c>, if an entry by that name
-        ///   exists, and then calling <c>AddItem()</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This version of the method allows the caller to explicitly specify the
-        ///   directory path to be used for the item being added to the archive.  The
-        ///   entry or entries that are added or updated will use the specified
-        ///   <c>DirectoryPathInArchive</c>. Extracting the entry from the archive will
-        ///   result in a file stored in that directory path.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddItem(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateDirectory(string, string)"/>
-        ///
-        /// <param name="itemName">
-        ///   The path for the File or Directory to be added or updated.
-        /// </param>
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the
-        ///   <c>itemName</c>.  This path may, or may not, correspond to a real
-        ///   directory in the current filesystem.  If the files within the zip are
-        ///   later extracted, this is the path used for the extracted file.  Passing
-        ///   <c>null</c> (<c>Nothing</c> in VB) will use the path on the
-        ///   <c>itemName</c>, if any.  Passing the empty string ("") will insert the
-        ///   item at the root path within the archive.
-        /// </param>
-        public void UpdateItem(string itemName, string directoryPathInArchive)
-        {
-            if (File.Exists(itemName))
-                UpdateFile(itemName, directoryPathInArchive);
-
-            else if (Directory.Exists(itemName))
-                UpdateDirectory(itemName, directoryPathInArchive);
-
-            else
-                throw new FileNotFoundException(String.Format("That file or directory ({0}) does not exist!", itemName));
-        }
-
-
-
-
-        /// <summary>
-        ///   Adds a named entry into the zip archive, taking content for the entry
-        ///   from a string.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Calling this method creates an entry using the given fileName and
-        ///   directory path within the archive.  There is no need for a file by the
-        ///   given name to exist in the filesystem; the name is used within the zip
-        ///   archive only. The content for the entry is encoded using the default text
-        ///   encoding for the machine, or on Silverlight, using UTF-8.
-        /// </remarks>
-        ///
-        /// <param name="content">
-        ///   The content of the file, should it be extracted from the zip.
-        /// </param>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use for the entry within the archive.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        ///
-        /// <example>
-        ///
-        /// This example shows how to add an entry to the zipfile, using a string as
-        /// content for that entry.
-        ///
-        /// <code lang="C#">
-        /// string Content = "This string will be the content of the Readme.txt file in the zip archive.";
-        /// using (ZipFile zip1 = new ZipFile())
-        /// {
-        ///   zip1.AddFile("MyDocuments\\Resume.doc", "files");
-        ///   zip1.AddEntry("Readme.txt", Content);
-        ///   zip1.Comment = "This zip file was created at " + System.DateTime.Now.ToString("G");
-        ///   zip1.Save("Content.zip");
-        /// }
-        ///
-        /// </code>
-        /// <code lang="VB">
-        /// Public Sub Run()
-        ///   Dim Content As String = "This string will be the content of the Readme.txt file in the zip archive."
-        ///   Using zip1 As ZipFile = New ZipFile
-        ///     zip1.AddEntry("Readme.txt", Content)
-        ///     zip1.AddFile("MyDocuments\Resume.doc", "files")
-        ///     zip1.Comment = ("This zip file was created at " &amp; DateTime.Now.ToString("G"))
-        ///     zip1.Save("Content.zip")
-        ///   End Using
-        /// End Sub
-        /// </code>
-        /// </example>
-        public ZipEntry AddEntry(string entryName, string content)
-        {
-#if SILVERLIGHT
-            return AddEntry(entryName, content, System.Text.Encoding.UTF8);
-#else
-            return AddEntry(entryName, content, System.Text.Encoding.Default);
-#endif
-        }
-
-
-
-        /// <summary>
-        ///   Adds a named entry into the zip archive, taking content for the entry
-        ///   from a string, and using the specified text encoding.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Calling this method creates an entry using the given fileName and
-        ///   directory path within the archive.  There is no need for a file by the
-        ///   given name to exist in the filesystem; the name is used within the zip
-        ///   archive only.
-        /// </para>
-        ///
-        /// <para>
-        ///   The content for the entry, a string value, is encoded using the given
-        ///   text encoding. A BOM (byte-order-mark) is emitted into the file, if the
-        ///   Encoding parameter is set for that.
-        /// </para>
-        ///
-        /// <para>
-        ///   Most Encoding classes support a constructor that accepts a boolean,
-        ///   indicating whether to emit a BOM or not. For example see <see
-        ///   cref="System.Text.UTF8Encoding(bool)"/>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="content">
-        ///   The content of the file, should it be extracted from the zip.
-        /// </param>
-        ///
-        /// <param name="encoding">
-        ///   The text encoding to use when encoding the string. Be aware: This is
-        ///   distinct from the text encoding used to encode the fileName, as specified
-        ///   in <see cref="ProvisionalAlternateEncoding" />.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        ///
-        public ZipEntry AddEntry(string entryName, string content, System.Text.Encoding encoding)
-        {
-            // cannot employ a using clause here.  We need the stream to
-            // persist after exit from this method.
-            var ms = new MemoryStream();
-
-            // cannot use a using clause here; StreamWriter takes
-            // ownership of the stream and Disposes it before we are ready.
-            var sw = new StreamWriter(ms, encoding);
-            sw.Write(content);
-            sw.Flush();
-
-            // reset to allow reading later
-            ms.Seek(0, SeekOrigin.Begin);
-
-            return AddEntry(entryName, ms);
-
-            // must not dispose the MemoryStream - it will be used later.
-        }
-
-
-        /// <summary>
-        ///   Create an entry in the <c>ZipFile</c> using the given <c>Stream</c>
-        ///   as input.  The entry will have the given filename.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The application should provide an open, readable stream; in this case it
-        ///   will be read during the call to <see cref="ZipFile.Save()"/> or one of
-        ///   its overloads.
-        /// </para>
-        ///
-        /// <para>
-        ///   The passed stream will be read from its current position. If
-        ///   necessary, callers should set the position in the stream before
-        ///   calling AddEntry(). This might be appropriate when using this method
-        ///   with a MemoryStream, for example.
-        /// </para>
-        ///
-        /// <para>
-        ///   In cases where a large number of streams will be added to the
-        ///   <c>ZipFile</c>, the application may wish to avoid maintaining all of the
-        ///   streams open simultaneously.  To handle this situation, the application
-        ///   should use the <see cref="AddEntry(string, OpenDelegate, CloseDelegate)"/>
-        ///   overload.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example adds a single entry to a <c>ZipFile</c> via a <c>Stream</c>.
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// String zipToCreate = "Content.zip";
-        /// String fileNameInArchive = "Content-From-Stream.bin";
-        /// using (System.IO.Stream streamToRead = MyStreamOpener())
-        /// {
-        ///   using (ZipFile zip = new ZipFile())
-        ///   {
-        ///     ZipEntry entry= zip.AddEntry(fileNameInArchive, streamToRead);
-        ///     zip.AddFile("Readme.txt");
-        ///     zip.Save(zipToCreate);  // the stream is read implicitly here
-        ///   }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim zipToCreate As String = "Content.zip"
-        /// Dim fileNameInArchive As String = "Content-From-Stream.bin"
-        /// Using streamToRead as System.IO.Stream = MyStreamOpener()
-        ///   Using zip As ZipFile = New ZipFile()
-        ///     Dim entry as ZipEntry = zip.AddEntry(fileNameInArchive, streamToRead)
-        ///     zip.AddFile("Readme.txt")
-        ///     zip.Save(zipToCreate)  '' the stream is read implicitly, here
-        ///   End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateEntry(string, System.IO.Stream)"/>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, which is shown in the zip file for the added
-        ///   entry.
-        /// </param>
-        /// <param name="stream">
-        ///   The input stream from which to grab content for the file
-        /// </param>
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddEntry(string entryName, Stream stream)
-        {
-            ZipEntry ze = ZipEntry.CreateForStream(entryName, stream);
-            ze.SetEntryTimes(DateTime.Now,DateTime.Now,DateTime.Now);
-            if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", entryName);
-            return _InternalAddEntry(ze);
-        }
-
-
-
-        /// <summary>
-        ///   Add a ZipEntry for which content is written directly by the application.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   When the application needs to write the zip entry data, use this
-        ///   method to add the ZipEntry. For example, in the case that the
-        ///   application wishes to write the XML representation of a DataSet into
-        ///   a ZipEntry, the application can use this method to do so.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// <para>
-        ///   About progress events: When using the WriteDelegate, DotNetZip does
-        ///   not issue any SaveProgress events with <c>EventType</c> = <see
-        ///   cref="ZipProgressEventType.Saving_EntryBytesRead">
-        ///   Saving_EntryBytesRead</see>. (This is because it is the
-        ///   application's code that runs in WriteDelegate - there's no way for
-        ///   DotNetZip to know when to issue a EntryBytesRead event.)
-        ///   Applications that want to update a progress bar or similar status
-        ///   indicator should do so from within the WriteDelegate
-        ///   itself. DotNetZip will issue the other SaveProgress events,
-        ///   including <see cref="ZipProgressEventType.Saving_Started">
-        ///   Saving_Started</see>,
-        ///   <see cref="ZipProgressEventType.Saving_BeforeWriteEntry">
-        ///   Saving_BeforeWriteEntry</see>, and <see
-        ///   cref="ZipProgressEventType.Saving_AfterWriteEntry">
-        ///   Saving_AfterWriteEntry</see>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Note: When you use PKZip encryption, it's normally necessary to
-        ///   compute the CRC of the content to be encrypted, before compressing or
-        ///   encrypting it. Therefore, when using PKZip encryption with a
-        ///   WriteDelegate, the WriteDelegate CAN BE called twice: once to compute
-        ///   the CRC, and the second time to potentially compress and
-        ///   encrypt. Surprising, but true. This is because PKWARE specified that
-        ///   the encryption initialization data depends on the CRC.
-        ///   If this happens, for each call of the delegate, your
-        ///   application must stream the same entry data in its entirety. If your
-        ///   application writes different data during the second call, it will
-        ///   result in a corrupt zip file.
-        /// </para>
-        ///
-        /// <para>
-        ///   The double-read behavior happens with all types of entries, not only
-        ///   those that use WriteDelegate. It happens if you add an entry from a
-        ///   filesystem file, or using a string, or a stream, or an opener/closer
-        ///   pair. But in those cases, DotNetZip takes care of reading twice; in
-        ///   the case of the WriteDelegate, the application code gets invoked
-        ///   twice. Be aware.
-        /// </para>
-        ///
-        /// <para>
-        ///   As you can imagine, this can cause performance problems for large
-        ///   streams, and it can lead to correctness problems when you use a
-        ///   <c>WriteDelegate</c>. This is a pretty big pitfall.  There are two
-        ///   ways to avoid it.  First, and most preferred: don't use PKZIP
-        ///   encryption.  If you use the WinZip AES encryption, this problem
-        ///   doesn't occur, because the encryption protocol doesn't require the CRC
-        ///   up front. Second: if you do choose to use PKZIP encryption, write out
-        ///   to a non-seekable stream (like standard output, or the
-        ///   Response.OutputStream in an ASP.NET application).  In this case,
-        ///   DotNetZip will use an alternative encryption protocol that does not
-        ///   rely on the CRC of the content.  This also implies setting bit 3 in
-        ///   the zip entry, which still presents problems for some zip tools.
-        /// </para>
-        ///
-        /// <para>
-        ///   In the future I may modify DotNetZip to *always* use bit 3 when PKZIP
-        ///   encryption is in use.  This seems like a win overall, but there will
-        ///   be some work involved.  If you feel strongly about it, visit the
-        ///   DotNetZip forums and vote up <see
-        ///   href="http://dotnetzip.codeplex.com/workitem/13686">the Workitem
-        ///   tracking this issue</see>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="entryName">the name of the entry to add</param>
-        /// <param name="writer">the delegate which will write the entry content</param>
-        /// <returns>the ZipEntry added</returns>
-        ///
-        /// <example>
-        ///
-        ///   This example shows an application filling a DataSet, then saving the
-        ///   contents of that DataSet as XML, into a ZipEntry in a ZipFile, using an
-        ///   anonymous delegate in C#. The DataSet XML is never saved to a disk file.
-        ///
-        /// <code lang="C#">
-        /// var c1= new System.Data.SqlClient.SqlConnection(connstring1);
-        /// var da = new System.Data.SqlClient.SqlDataAdapter()
-        ///     {
-        ///         SelectCommand=  new System.Data.SqlClient.SqlCommand(strSelect, c1)
-        ///     };
-        ///
-        /// DataSet ds1 = new DataSet();
-        /// da.Fill(ds1, "Invoices");
-        ///
-        /// using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
-        /// {
-        ///     zip.AddEntry(zipEntryName, (name,stream) => ds1.WriteXml(stream) );
-        ///     zip.Save(zipFileName);
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        ///
-        /// This example uses an anonymous method in C# as the WriteDelegate to provide
-        /// the data for the ZipEntry. The example is a bit contrived - the
-        /// <c>AddFile()</c> method is a simpler way to insert the contents of a file
-        /// into an entry in a zip file. On the other hand, if there is some sort of
-        /// processing or transformation of the file contents required before writing,
-        /// the application could use the <c>WriteDelegate</c> to do it, in this way.
-        ///
-        /// <code lang="C#">
-        /// using (var input = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ))
-        /// {
-        ///     using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
-        ///     {
-        ///         zip.AddEntry(zipEntryName, (name,output) =>
-        ///             {
-        ///                 byte[] buffer = new byte[BufferSize];
-        ///                 int n;
-        ///                 while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
-        ///                 {
-        ///                     // could transform the data here...
-        ///                     output.Write(buffer, 0, n);
-        ///                     // could update a progress bar here
-        ///                 }
-        ///             });
-        ///
-        ///         zip.Save(zipFileName);
-        ///     }
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        ///
-        /// This example uses a named delegate in VB to write data for the given
-        /// ZipEntry (VB9 does not have anonymous delegates). The example here is a bit
-        /// contrived - a simpler way to add the contents of a file to a ZipEntry is to
-        /// simply use the appropriate <c>AddFile()</c> method.  The key scenario for
-        /// which the <c>WriteDelegate</c> makes sense is saving a DataSet, in XML
-        /// format, to the zip file. The DataSet can write XML to a stream, and the
-        /// WriteDelegate is the perfect place to write into the zip file.  There may be
-        /// other data structures that can write to a stream, but cannot be read as a
-        /// stream.  The <c>WriteDelegate</c> would be appropriate for those cases as
-        /// well.
-        ///
-        /// <code lang="VB">
-        /// Private Sub WriteEntry (ByVal name As String, ByVal output As Stream)
-        ///     Using input As FileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
-        ///         Dim n As Integer = -1
-        ///         Dim buffer As Byte() = New Byte(BufferSize){}
-        ///         Do While n &lt;&gt; 0
-        ///             n = input.Read(buffer, 0, buffer.Length)
-        ///             output.Write(buffer, 0, n)
-        ///         Loop
-        ///     End Using
-        /// End Sub
-        ///
-        /// Public Sub Run()
-        ///     Using zip = New ZipFile
-        ///         zip.AddEntry(zipEntryName, New WriteDelegate(AddressOf WriteEntry))
-        ///         zip.Save(zipFileName)
-        ///     End Using
-        /// End Sub
-        /// </code>
-        /// </example>
-        public ZipEntry AddEntry(string entryName, WriteDelegate writer)
-        {
-            ZipEntry ze = ZipEntry.CreateForWriter(entryName, writer);
-            if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", entryName);
-            return _InternalAddEntry(ze);
-        }
-
-
-        /// <summary>
-        ///   Add an entry, for which the application will provide a stream
-        ///   containing the entry data, on a just-in-time basis.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   In cases where the application wishes to open the stream that
-        ///   holds the content for the ZipEntry, on a just-in-time basis, the
-        ///   application can use this method.  The application provides an
-        ///   opener delegate that will be called by the DotNetZip library to
-        ///   obtain a readable stream that can be read to get the bytes for
-        ///   the given entry.  Typically, this delegate opens a stream.
-        ///   Optionally, the application can provide a closer delegate as
-        ///   well, which will be called by DotNetZip when all bytes have been
-        ///   read from the entry.
-        /// </para>
-        ///
-        /// <para>
-        ///   These delegates are called from within the scope of the call to
-        ///   ZipFile.Save().
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example uses anonymous methods in C# to open and close the
-        ///   source stream for the content for a zip entry.
-        ///
-        /// <code lang="C#">
-        /// using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
-        /// {
-        ///     zip.AddEntry(zipEntryName,
-        ///                  (name) =>  File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ),
-        ///                  (name, stream) =>  stream.Close()
-        ///                  );
-        ///
-        ///     zip.Save(zipFileName);
-        /// }
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <example>
-        ///
-        ///   This example uses delegates in VB.NET to open and close the
-        ///   the source stream for the content for a zip entry.  VB 9.0 lacks
-        ///   support for "Sub" lambda expressions, and so the CloseDelegate must
-        ///   be an actual, named Sub.
-        ///
-        /// <code lang="VB">
-        ///
-        /// Function MyStreamOpener(ByVal entryName As String) As Stream
-        ///     '' This simply opens a file.  You probably want to do somethinig
-        ///     '' more involved here: open a stream to read from a database,
-        ///     '' open a stream on an HTTP connection, and so on.
-        ///     Return File.OpenRead(entryName)
-        /// End Function
-        ///
-        /// Sub MyStreamCloser(entryName As String, stream As Stream)
-        ///     stream.Close()
-        /// End Sub
-        ///
-        /// Public Sub Run()
-        ///     Dim dirToZip As String = "fodder"
-        ///     Dim zipFileToCreate As String = "Archive.zip"
-        ///     Dim opener As OpenDelegate = AddressOf MyStreamOpener
-        ///     Dim closer As CloseDelegate = AddressOf MyStreamCloser
-        ///     Dim numFilestoAdd As Int32 = 4
-        ///     Using zip As ZipFile = New ZipFile
-        ///         Dim i As Integer
-        ///         For i = 0 To numFilesToAdd - 1
-        ///             zip.AddEntry(String.Format("content-{0:000}.txt"), opener, closer)
-        ///         Next i
-        ///         zip.Save(zipFileToCreate)
-        ///     End Using
-        /// End Sub
-        ///
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="entryName">the name of the entry to add</param>
-        /// <param name="opener">
-        ///  the delegate that will be invoked by ZipFile.Save() to get the
-        ///  readable stream for the given entry. ZipFile.Save() will call
-        ///  read on this stream to obtain the data for the entry. This data
-        ///  will then be compressed and written to the newly created zip
-        ///  file.
-        /// </param>
-        /// <param name="closer">
-        ///  the delegate that will be invoked to close the stream. This may
-        ///  be null (Nothing in VB), in which case no call is makde to close
-        ///  the stream.
-        /// </param>
-        /// <returns>the ZipEntry added</returns>
-        ///
-        public ZipEntry AddEntry(string entryName, OpenDelegate opener, CloseDelegate closer)
-        {
-            ZipEntry ze = ZipEntry.CreateForJitStreamProvider(entryName, opener, closer);
-            ze.SetEntryTimes(DateTime.Now,DateTime.Now,DateTime.Now);
-            if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", entryName);
-            return _InternalAddEntry(ze);
-        }
-
-
-
-        private ZipEntry _InternalAddEntry(ZipEntry ze)
-        {
-            // stamp all the props onto the entry
-            ze._container = new ZipContainer(this);
-            ze.CompressionMethod = this.CompressionMethod;
-            ze.CompressionLevel = this.CompressionLevel;
-            ze.ExtractExistingFile = this.ExtractExistingFile;
-            ze.ZipErrorAction = this.ZipErrorAction;
-            ze.SetCompression = this.SetCompression;
-            ze.AlternateEncoding = this.AlternateEncoding;
-            ze.AlternateEncodingUsage = this.AlternateEncodingUsage;
-            ze.Password = this._Password;
-            ze.Encryption = this.Encryption;
-            ze.EmitTimesInWindowsFormatWhenSaving = this._emitNtfsTimes;
-            ze.EmitTimesInUnixFormatWhenSaving = this._emitUnixTimes;
-            //string key = DictionaryKeyForEntry(ze);
-            InternalAddEntry(ze.FileName,ze);
-            AfterAddEntry(ze);
-            return ze;
-        }
-
-
-
-
-        /// <summary>
-        ///   Updates the given entry in the <c>ZipFile</c>, using the given
-        ///   string as content for the <c>ZipEntry</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Calling this method is equivalent to removing the <c>ZipEntry</c> for
-        ///   the given file name and directory path, if it exists, and then calling
-        ///   <see cref="AddEntry(String,String)" />.  See the documentation for
-        ///   that method for further explanation. The string content is encoded
-        ///   using the default encoding for the machine, or on Silverlight, using
-        ///   UTF-8. This encoding is distinct from the encoding used for the
-        ///   filename itself.  See <see cref="AlternateEncoding"/>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="content">
-        ///   The content of the file, should it be extracted from the zip.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        ///
-        public ZipEntry UpdateEntry(string entryName, string content)
-        {
-#if SILVERLIGHT
-            return UpdateEntry(entryName, content, System.Text.Encoding.UTF8);
-#else
-            return UpdateEntry(entryName, content, System.Text.Encoding.Default);
-#endif
-        }
-
-
-        /// <summary>
-        ///   Updates the given entry in the <c>ZipFile</c>, using the given string as
-        ///   content for the <c>ZipEntry</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Calling this method is equivalent to removing the <c>ZipEntry</c> for the
-        ///   given file name and directory path, if it exists, and then calling <see
-        ///   cref="AddEntry(String,String, System.Text.Encoding)" />.  See the
-        ///   documentation for that method for further explanation.
-        /// </remarks>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="content">
-        ///   The content of the file, should it be extracted from the zip.
-        /// </param>
-        ///
-        /// <param name="encoding">
-        ///   The text encoding to use when encoding the string. Be aware: This is
-        ///   distinct from the text encoding used to encode the filename. See <see
-        ///   cref="AlternateEncoding" />.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        ///
-        public ZipEntry UpdateEntry(string entryName, string content, System.Text.Encoding encoding)
-        {
-            RemoveEntryForUpdate(entryName);
-            return AddEntry(entryName, content, encoding);
-        }
-
-
-
-        /// <summary>
-        ///   Updates the given entry in the <c>ZipFile</c>, using the given delegate
-        ///   as the source for content for the <c>ZipEntry</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Calling this method is equivalent to removing the <c>ZipEntry</c> for the
-        ///   given file name and directory path, if it exists, and then calling <see
-        ///   cref="AddEntry(String,WriteDelegate)" />.  See the
-        ///   documentation for that method for further explanation.
-        /// </remarks>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="writer">the delegate which will write the entry content.</param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        ///
-        public ZipEntry UpdateEntry(string entryName, WriteDelegate writer)
-        {
-            RemoveEntryForUpdate(entryName);
-            return AddEntry(entryName, writer);
-        }
-
-
-
-        /// <summary>
-        ///   Updates the given entry in the <c>ZipFile</c>, using the given delegates
-        ///   to open and close the stream that provides the content for the <c>ZipEntry</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Calling this method is equivalent to removing the <c>ZipEntry</c> for the
-        ///   given file name and directory path, if it exists, and then calling <see
-        ///   cref="AddEntry(String,OpenDelegate, CloseDelegate)" />.  See the
-        ///   documentation for that method for further explanation.
-        /// </remarks>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="opener">
-        ///  the delegate that will be invoked to open the stream
-        /// </param>
-        /// <param name="closer">
-        ///  the delegate that will be invoked to close the stream
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added or updated.</returns>
-        ///
-        public ZipEntry UpdateEntry(string entryName, OpenDelegate opener, CloseDelegate closer)
-        {
-            RemoveEntryForUpdate(entryName);
-            return AddEntry(entryName, opener, closer);
-        }
-
-
-        /// <summary>
-        ///   Updates the given entry in the <c>ZipFile</c>, using the given stream as
-        ///   input, and the given filename and given directory Path.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Calling the method is equivalent to calling <c>RemoveEntry()</c> if an
-        ///   entry by the same name already exists, and then calling <c>AddEntry()</c>
-        ///   with the given <c>fileName</c> and stream.
-        /// </para>
-        ///
-        /// <para>
-        ///   The stream must be open and readable during the call to
-        ///   <c>ZipFile.Save</c>.  You can dispense the stream on a just-in-time basis
-        ///   using the <see cref="ZipEntry.InputStream"/> property. Check the
-        ///   documentation of that property for more information.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to the
-        ///   <c>ZipEntry</c> added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddEntry(string, System.IO.Stream)"/>
-        /// <seealso cref="ZipEntry.InputStream"/>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="stream">The input stream from which to read file data.</param>
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry UpdateEntry(string entryName, Stream stream)
-        {
-            RemoveEntryForUpdate(entryName);
-            return AddEntry(entryName, stream);
-        }
-
-
-        private void RemoveEntryForUpdate(string entryName)
-        {
-            if (String.IsNullOrEmpty(entryName))
-                throw new ArgumentNullException("entryName");
-
-            string directoryPathInArchive = null;
-            if (entryName.IndexOf('\\') != -1)
-            {
-                directoryPathInArchive = Path.GetDirectoryName(entryName);
-                entryName = Path.GetFileName(entryName);
-            }
-            var key = ZipEntry.NameInArchive(entryName, directoryPathInArchive);
-            if (this[key] != null)
-                this.RemoveEntry(key);
-        }
-
-
-
-
-        /// <summary>
-        ///   Add an entry into the zip archive using the given filename and
-        ///   directory path within the archive, and the given content for the
-        ///   file. No file is created in the filesystem.
-        /// </summary>
-        ///
-        /// <param name="byteContent">The data to use for the entry.</param>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddEntry(string entryName, byte[] byteContent)
-        {
-            if (byteContent == null) throw new ArgumentException("bad argument", "byteContent");
-            var ms = new MemoryStream(byteContent);
-            return AddEntry(entryName, ms);
-        }
-
-
-        /// <summary>
-        ///   Updates the given entry in the <c>ZipFile</c>, using the given byte
-        ///   array as content for the entry.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Calling this method is equivalent to removing the <c>ZipEntry</c>
-        ///   for the given filename and directory path, if it exists, and then
-        ///   calling <see cref="AddEntry(String,byte[])" />.  See the
-        ///   documentation for that method for further explanation.
-        /// </remarks>
-        ///
-        /// <param name="entryName">
-        ///   The name, including any path, to use within the archive for the entry.
-        /// </param>
-        ///
-        /// <param name="byteContent">The content to use for the <c>ZipEntry</c>.</param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        ///
-        public ZipEntry UpdateEntry(string entryName, byte[] byteContent)
-        {
-            RemoveEntryForUpdate(entryName);
-            return AddEntry(entryName, byteContent);
-        }
-
-
-//         private string DictionaryKeyForEntry(ZipEntry ze1)
-//         {
-//             var filename = SharedUtilities.NormalizePathForUseInZipFile(ze1.FileName);
-//             return filename;
-//         }
-
-
-        /// <summary>
-        ///   Adds the contents of a filesystem directory to a Zip file archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The name of the directory may be a relative path or a fully-qualified
-        ///   path. Any files within the named directory are added to the archive.  Any
-        ///   subdirectories within the named directory are also added to the archive,
-        ///   recursively.
-        /// </para>
-        ///
-        /// <para>
-        ///   Top-level entries in the named directory will appear as top-level entries
-        ///   in the zip archive.  Entries in subdirectories in the named directory will
-        ///   result in entries in subdirectories in the zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you want the entries to appear in a containing directory in the zip
-        ///   archive itself, then you should call the AddDirectory() overload that
-        ///   allows you to explicitly specify a directory path for use in the archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to each
-        ///   ZipEntry added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddItem(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddFile(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateDirectory(string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string, string)"/>
-        ///
-        /// <overloads>This method has 2 overloads.</overloads>
-        ///
-        /// <param name="directoryName">The name of the directory to add.</param>
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddDirectory(string directoryName)
-        {
-            return AddDirectory(directoryName, null);
-        }
-
-
-        /// <summary>
-        ///   Adds the contents of a filesystem directory to a Zip file archive,
-        ///   overriding the path to be used for entries in the archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The name of the directory may be a relative path or a fully-qualified
-        ///   path. The add operation is recursive, so that any files or subdirectories
-        ///   within the name directory are also added to the archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   Top-level entries in the named directory will appear as top-level entries
-        ///   in the zip archive.  Entries in subdirectories in the named directory will
-        ///   result in entries in subdirectories in the zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   For <c>ZipFile</c> properties including <see cref="Encryption"/>, <see
-        ///   cref="Password"/>, <see cref="SetCompression"/>, <see
-        ///   cref="ProvisionalAlternateEncoding"/>, <see cref="ExtractExistingFile"/>,
-        ///   <see cref="ZipErrorAction"/>, and <see cref="CompressionLevel"/>, their
-        ///   respective values at the time of this call will be applied to each
-        ///   ZipEntry added.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   In this code, calling the ZipUp() method with a value of "c:\reports" for
-        ///   the directory parameter will result in a zip file structure in which all
-        ///   entries are contained in a toplevel "reports" directory.
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// public void ZipUp(string targetZip, string directory)
-        /// {
-        ///   using (var zip = new ZipFile())
-        ///   {
-        ///     zip.AddDirectory(directory, System.IO.Path.GetFileName(directory));
-        ///     zip.Save(targetZip);
-        ///   }
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddItem(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddFile(string, string)"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.UpdateDirectory(string, string)"/>
-        ///
-        /// <param name="directoryName">The name of the directory to add.</param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to override any path in the
-        ///   DirectoryName.  This path may, or may not, correspond to a real directory
-        ///   in the current filesystem.  If the zip is later extracted, this is the
-        ///   path used for the extracted file or directory.  Passing <c>null</c>
-        ///   (<c>Nothing</c> in VB) or the empty string ("") will insert the items at
-        ///   the root path within the archive.
-        /// </param>
-        ///
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddDirectory(string directoryName, string directoryPathInArchive)
-        {
-            return AddOrUpdateDirectoryImpl(directoryName, directoryPathInArchive, AddOrUpdateAction.AddOnly);
-        }
-
-
-        /// <summary>
-        ///   Creates a directory in the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Use this when you want to create a directory in the archive but there is
-        ///   no corresponding filesystem representation for that directory.
-        /// </para>
-        ///
-        /// <para>
-        ///   You will probably not need to do this in your code. One of the only times
-        ///   you will want to do this is if you want an empty directory in the zip
-        ///   archive.  The reason: if you add a file to a zip archive that is stored
-        ///   within a multi-level directory, all of the directory tree is implicitly
-        ///   created in the zip archive.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="directoryNameInArchive">
-        ///   The name of the directory to create in the archive.
-        /// </param>
-        /// <returns>The <c>ZipEntry</c> added.</returns>
-        public ZipEntry AddDirectoryByName(string directoryNameInArchive)
-        {
-            // workitem 9073
-            ZipEntry dir = ZipEntry.CreateFromNothing(directoryNameInArchive);
-            dir._container = new ZipContainer(this);
-            dir.MarkAsDirectory();
-            dir.AlternateEncoding = this.AlternateEncoding;  // workitem 8984
-            dir.AlternateEncodingUsage = this.AlternateEncodingUsage;
-            dir.SetEntryTimes(DateTime.Now,DateTime.Now,DateTime.Now);
-            dir.EmitTimesInWindowsFormatWhenSaving = _emitNtfsTimes;
-            dir.EmitTimesInUnixFormatWhenSaving = _emitUnixTimes;
-            dir._Source = ZipEntrySource.Stream;
-            //string key = DictionaryKeyForEntry(dir);
-            InternalAddEntry(dir.FileName,dir);
-            AfterAddEntry(dir);
-            return dir;
-        }
-
-
-
-        private ZipEntry AddOrUpdateDirectoryImpl(string directoryName,
-                                                  string rootDirectoryPathInArchive,
-                                                  AddOrUpdateAction action)
-        {
-            if (rootDirectoryPathInArchive == null)
-            {
-                rootDirectoryPathInArchive = "";
-            }
-
-            return AddOrUpdateDirectoryImpl(directoryName, rootDirectoryPathInArchive, action, true, 0);
-        }
-
-
-        internal void InternalAddEntry(String name, ZipEntry entry)
-        {
-            _entries.Add(name, entry);
-            _zipEntriesAsList = null;
-            _contentsChanged = true;
-        }
-
-
-
-        private ZipEntry AddOrUpdateDirectoryImpl(string directoryName,
-                                                  string rootDirectoryPathInArchive,
-                                                  AddOrUpdateAction action,
-                                                  bool recurse,
-                                                  int level)
-        {
-            if (Verbose)
-                StatusMessageTextWriter.WriteLine("{0} {1}...",
-                                                  (action == AddOrUpdateAction.AddOnly) ? "adding" : "Adding or updating",
-                                                  directoryName);
-
-            if (level == 0)
-            {
-                _addOperationCanceled = false;
-                OnAddStarted();
-            }
-
-            // workitem 13371
-            if (_addOperationCanceled)
-                return null;
-
-            string dirForEntries = rootDirectoryPathInArchive;
-            ZipEntry baseDir = null;
-
-            if (level > 0)
-            {
-                int f = directoryName.Length;
-                for (int i = level; i > 0; i--)
-                    f = directoryName.LastIndexOfAny("/\\".ToCharArray(), f - 1, f - 1);
-
-                dirForEntries = directoryName.Substring(f + 1);
-                dirForEntries = Path.Combine(rootDirectoryPathInArchive, dirForEntries);
-            }
-
-            // if not top level, or if the root is non-empty, then explicitly add the directory
-            if (level > 0 || rootDirectoryPathInArchive != "")
-            {
-                baseDir = ZipEntry.CreateFromFile(directoryName, dirForEntries);
-                baseDir._container = new ZipContainer(this);
-                baseDir.AlternateEncoding = this.AlternateEncoding;  // workitem 6410
-                baseDir.AlternateEncodingUsage = this.AlternateEncodingUsage;
-                baseDir.MarkAsDirectory();
-                baseDir.EmitTimesInWindowsFormatWhenSaving = _emitNtfsTimes;
-                baseDir.EmitTimesInUnixFormatWhenSaving = _emitUnixTimes;
-
-                // add the directory only if it does not exist.
-                // It's not an error if it already exists.
-                if (!_entries.ContainsKey(baseDir.FileName))
-                {
-                    InternalAddEntry(baseDir.FileName,baseDir);
-                    AfterAddEntry(baseDir);
-                }
-                dirForEntries = baseDir.FileName;
-            }
-
-            if (!_addOperationCanceled)
-            {
-
-                String[] filenames = Directory.GetFiles(directoryName);
-
-                if (recurse)
-                {
-                    // add the files:
-                    foreach (String filename in filenames)
-                    {
-                        if (_addOperationCanceled) break;
-                        if (action == AddOrUpdateAction.AddOnly)
-                            AddFile(filename, dirForEntries);
-                        else
-                            UpdateFile(filename, dirForEntries);
-                    }
-
-                    if (!_addOperationCanceled)
-                    {
-                        // add the subdirectories:
-                        String[] dirnames = Directory.GetDirectories(directoryName);
-                        foreach (String dir in dirnames)
-                        {
-                            // workitem 8617: Optionally traverse reparse points
-#if SILVERLIGHT
-#elif NETCF
-                            FileAttributes fileAttrs = (FileAttributes) NetCfFile.GetAttributes(dir);
-#else
-                            FileAttributes fileAttrs = System.IO.File.GetAttributes(dir);
-#endif
-                            if (this.AddDirectoryWillTraverseReparsePoints
-#if !SILVERLIGHT
-                                || ((fileAttrs & FileAttributes.ReparsePoint) == 0)
-#endif
-                                )
-                                AddOrUpdateDirectoryImpl(dir, rootDirectoryPathInArchive, action, recurse, level + 1);
-
-                        }
-
-                    }
-                }
-            }
-
-            if (level == 0)
-                OnAddCompleted();
-
-            return baseDir;
-        }
-
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.Check.cs b/EPPlus/Packaging/DotNetZip/ZipFile.Check.cs
deleted file mode 100644
index 3870556..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.Check.cs
+++ /dev/null
@@ -1,352 +0,0 @@
-// ZipFile.Check.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-31 14:40:50>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for doing Checks on zip files.
-// These are not necessary to include in the Reduced or CF
-// version of the library.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal partial class ZipFile
-    {
-        /// <summary>
-        ///   Checks a zip file to see if its directory is consistent.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   In cases of data error, the directory within a zip file can get out
-        ///   of synch with the entries in the zip file.  This method checks the
-        ///   given zip file and returns true if this has occurred.
-        /// </para>
-        ///
-        /// <para> This method may take a long time to run for large zip files.  </para>
-        ///
-        /// <para>
-        ///   This method is not supported in the Reduced or Compact Framework
-        ///   versions of DotNetZip.
-        /// </para>
-        ///
-        /// <para>
-        ///   Developers using COM can use the <see
-        ///   cref="ComHelper.CheckZip(String)">ComHelper.CheckZip(String)</see>
-        ///   method.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="zipFileName">The filename to of the zip file to check.</param>
-        ///
-        /// <returns>true if the named zip file checks OK. Otherwise, false. </returns>
-        ///
-        /// <seealso cref="FixZipDirectory(string)"/>
-        /// <seealso cref="CheckZip(string,bool,System.IO.TextWriter)"/>
-        public static bool CheckZip(string zipFileName)
-        {
-            return CheckZip(zipFileName, false, null);
-        }
-
-
-        /// <summary>
-        ///   Checks a zip file to see if its directory is consistent,
-        ///   and optionally fixes the directory if necessary.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   In cases of data error, the directory within a zip file can get out of
-        ///   synch with the entries in the zip file.  This method checks the given
-        ///   zip file, and returns true if this has occurred. It also optionally
-        ///   fixes the zipfile, saving the fixed copy in <em>Name</em>_Fixed.zip.
-        /// </para>
-        ///
-        /// <para>
-        ///   This method may take a long time to run for large zip files.  It
-        ///   will take even longer if the file actually needs to be fixed, and if
-        ///   <c>fixIfNecessary</c> is true.
-        /// </para>
-        ///
-        /// <para>
-        ///   This method is not supported in the Reduced or Compact
-        ///   Framework versions of DotNetZip.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="zipFileName">The filename to of the zip file to check.</param>
-        ///
-        /// <param name="fixIfNecessary">If true, the method will fix the zip file if
-        ///     necessary.</param>
-        ///
-        /// <param name="writer">
-        /// a TextWriter in which messages generated while checking will be written.
-        /// </param>
-        ///
-        /// <returns>true if the named zip is OK; false if the file needs to be fixed.</returns>
-        ///
-        /// <seealso cref="CheckZip(string)"/>
-        /// <seealso cref="FixZipDirectory(string)"/>
-        public static bool CheckZip(string zipFileName, bool fixIfNecessary,
-                                    TextWriter writer)
-
-        {
-            ZipFile zip1 = null, zip2 = null;
-            bool isOk = true;
-            try
-            {
-                zip1 = new ZipFile();
-                zip1.FullScan = true;
-                zip1.Initialize(zipFileName);
-
-                zip2 = ZipFile.Read(zipFileName);
-
-                foreach (var e1 in zip1)
-                {
-                    foreach (var e2 in zip2)
-                    {
-                        if (e1.FileName == e2.FileName)
-                        {
-                            if (e1._RelativeOffsetOfLocalHeader != e2._RelativeOffsetOfLocalHeader)
-                            {
-                                isOk = false;
-                                if (writer != null)
-                                writer.WriteLine("{0}: mismatch in RelativeOffsetOfLocalHeader  (0x{1:X16} != 0x{2:X16})",
-                                                        e1.FileName, e1._RelativeOffsetOfLocalHeader,
-                                                        e2._RelativeOffsetOfLocalHeader);
-                            }
-                            if (e1._CompressedSize != e2._CompressedSize)
-                            {
-                                isOk = false;
-                                if (writer != null)
-                                writer.WriteLine("{0}: mismatch in CompressedSize  (0x{1:X16} != 0x{2:X16})",
-                                                        e1.FileName, e1._CompressedSize,
-                                                        e2._CompressedSize);
-                            }
-                            if (e1._UncompressedSize != e2._UncompressedSize)
-                            {
-                                isOk = false;
-                                if (writer != null)
-                                writer.WriteLine("{0}: mismatch in UncompressedSize  (0x{1:X16} != 0x{2:X16})",
-                                                        e1.FileName, e1._UncompressedSize,
-                                                        e2._UncompressedSize);
-                            }
-                            if (e1.CompressionMethod != e2.CompressionMethod)
-                            {
-                                isOk = false;
-                                if (writer != null)
-                                writer.WriteLine("{0}: mismatch in CompressionMethod  (0x{1:X4} != 0x{2:X4})",
-                                                        e1.FileName, e1.CompressionMethod,
-                                                        e2.CompressionMethod);
-                            }
-                            if (e1.Crc != e2.Crc)
-                            {
-                                isOk = false;
-                                if (writer != null)
-                                writer.WriteLine("{0}: mismatch in Crc32  (0x{1:X4} != 0x{2:X4})",
-                                                        e1.FileName, e1.Crc,
-                                                        e2.Crc);
-                            }
-
-                            // found a match, so stop the inside loop
-                            break;
-                        }
-                    }
-                }
-
-                zip2.Dispose();
-                zip2 = null;
-
-                if (!isOk && fixIfNecessary)
-                {
-                    string newFileName = Path.GetFileNameWithoutExtension(zipFileName);
-                    newFileName = System.String.Format("{0}_fixed.zip", newFileName);
-                    zip1.Save(newFileName);
-                }
-            }
-            finally
-            {
-                if (zip1 != null) zip1.Dispose();
-                if (zip2 != null) zip2.Dispose();
-            }
-            return isOk;
-        }
-
-
-
-        /// <summary>
-        ///   Rewrite the directory within a zipfile.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   In cases of data error, the directory in a zip file can get out of
-        ///   synch with the entries in the zip file.  This method attempts to fix
-        ///   the zip file if this has occurred.
-        /// </para>
-        ///
-        /// <para> This can take a long time for large zip files. </para>
-        ///
-        /// <para> This won't work if the zip file uses a non-standard
-        /// code page - neither IBM437 nor UTF-8. </para>
-        ///
-        /// <para>
-        ///   This method is not supported in the Reduced or Compact Framework
-        ///   versions of DotNetZip.
-        /// </para>
-        ///
-        /// <para>
-        ///   Developers using COM can use the <see
-        ///   cref="ComHelper.FixZipDirectory(String)">ComHelper.FixZipDirectory(String)</see>
-        ///   method.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="zipFileName">The filename to of the zip file to fix.</param>
-        ///
-        /// <seealso cref="CheckZip(string)"/>
-        /// <seealso cref="CheckZip(string,bool,System.IO.TextWriter)"/>
-        public static void FixZipDirectory(string zipFileName)
-        {
-            using (var zip = new ZipFile())
-            {
-                zip.FullScan = true;
-                zip.Initialize(zipFileName);
-                zip.Save(zipFileName);
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Verify the password on a zip file.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     Keep in mind that passwords in zipfiles are applied to
-        ///     zip entries, not to the entire zip file. So testing a
-        ///     zipfile for a particular password doesn't work in the
-        ///     general case. On the other hand, it's often the case
-        ///     that a single password will be used on all entries in a
-        ///     zip file. This method works for that case.
-        ///   </para>
-        ///   <para>
-        ///     There is no way to check a password without doing the
-        ///     decryption. So this code decrypts and extracts the given
-        ///     zipfile into <see cref="System.IO.Stream.Null"/>
-        ///   </para>
-        /// </remarks>
-        ///
-        /// <param name="zipFileName">The filename to of the zip file to fix.</param>
-        ///
-        /// <param name="password">The password to check.</param>
-        ///
-        /// <returns>a bool indicating whether the password matches.</returns>
-        public static bool CheckZipPassword(string zipFileName, string password)
-        {
-            // workitem 13664
-            bool success = false;
-            try
-            {
-                using (ZipFile zip1 = ZipFile.Read(zipFileName))
-                {
-                    foreach (var e in zip1)
-                    {
-                        if (!e.IsDirectory && e.UsesEncryption)
-                        {
-                            e.ExtractWithPassword(System.IO.Stream.Null, password);
-                        }
-                    }
-                }
-                success = true;
-            }
-            catch(Ionic.Zip.BadPasswordException) { }
-            return success;
-        }
-
-
-        /// <summary>
-        ///   Provides a human-readable string with information about the ZipFile.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     The information string contains 10 lines or so, about each ZipEntry,
-        ///     describing whether encryption is in use, the compressed and uncompressed
-        ///     length of the entry, the offset of the entry, and so on. As a result the
-        ///     information string can be very long for zip files that contain many
-        ///     entries.
-        ///   </para>
-        ///   <para>
-        ///     This information is mostly useful for diagnostic purposes.
-        ///   </para>
-        /// </remarks>
-        public string Info
-        {
-            get
-            {
-                var builder = new System.Text.StringBuilder();
-                builder.Append(string.Format("          ZipFile: {0}\n", this.Name));
-                if (!string.IsNullOrEmpty(this._Comment))
-                {
-                    builder.Append(string.Format("          Comment: {0}\n", this._Comment));
-                }
-                if (this._versionMadeBy != 0)
-                {
-                    builder.Append(string.Format("  version made by: 0x{0:X4}\n", this._versionMadeBy));
-                }
-                if (this._versionNeededToExtract != 0)
-                {
-                    builder.Append(string.Format("needed to extract: 0x{0:X4}\n", this._versionNeededToExtract));
-                }
-
-                builder.Append(string.Format("       uses ZIP64: {0}\n", this.InputUsesZip64));
-
-                builder.Append(string.Format("     disk with CD: {0}\n", this._diskNumberWithCd));
-                if (this._OffsetOfCentralDirectory == 0xFFFFFFFF)
-                    builder.Append(string.Format("      CD64 offset: 0x{0:X16}\n", this._OffsetOfCentralDirectory64));
-                else
-                    builder.Append(string.Format("        CD offset: 0x{0:X8}\n", this._OffsetOfCentralDirectory));
-                builder.Append("\n");
-                foreach (ZipEntry entry in this._entries.Values)
-                {
-                    builder.Append(entry.Info);
-                }
-                return builder.ToString();
-            }
-        }
-
-
-    }
-
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.Events.cs b/EPPlus/Packaging/DotNetZip/ZipFile.Events.cs
deleted file mode 100644
index 573e076..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.Events.cs
+++ /dev/null
@@ -1,1219 +0,0 @@
-// ZipFile.Events.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008, 2009, 2011 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-09 08:42:35>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for issuing events from the ZipFile class.
-//
-// ------------------------------------------------------------------
-//
-
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal partial class ZipFile
-    {
-        private string ArchiveNameForEvent
-        {
-            get
-            {
-                return (_name != null) ? _name : "(stream)";
-            }
-        }
-
-        #region Save
-
-        /// <summary>
-        ///   An event handler invoked when a Save() starts, before and after each
-        ///   entry has been written to the archive, when a Save() completes, and
-        ///   during other Save events.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Depending on the particular event, different properties on the <see
-        ///   cref="SaveProgressEventArgs"/> parameter are set.  The following
-        ///   table summarizes the available EventTypes and the conditions under
-        ///   which this event handler is invoked with a
-        ///   <c>SaveProgressEventArgs</c> with the given EventType.
-        /// </para>
-        ///
-        /// <list type="table">
-        /// <listheader>
-        /// <term>value of EntryType</term>
-        /// <description>Meaning and conditions</description>
-        /// </listheader>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_Started</term>
-        /// <description>Fired when ZipFile.Save() begins.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_BeforeSaveEntry</term>
-        /// <description>
-        ///   Fired within ZipFile.Save(), just before writing data for each
-        ///   particular entry.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_AfterSaveEntry</term>
-        /// <description>
-        ///   Fired within ZipFile.Save(), just after having finished writing data
-        ///   for each particular entry.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_Completed</term>
-        /// <description>Fired when ZipFile.Save() has completed.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_AfterSaveTempArchive</term>
-        /// <description>
-        ///   Fired after the temporary file has been created.  This happens only
-        ///   when saving to a disk file.  This event will not be invoked when
-        ///   saving to a stream.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_BeforeRenameTempArchive</term>
-        /// <description>
-        ///   Fired just before renaming the temporary file to the permanent
-        ///   location.  This happens only when saving to a disk file.  This event
-        ///   will not be invoked when saving to a stream.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_AfterRenameTempArchive</term>
-        /// <description>
-        ///   Fired just after renaming the temporary file to the permanent
-        ///   location.  This happens only when saving to a disk file.  This event
-        ///   will not be invoked when saving to a stream.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_AfterCompileSelfExtractor</term>
-        /// <description>
-        ///   Fired after a self-extracting archive has finished compiling.  This
-        ///   EventType is used only within SaveSelfExtractor().
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Saving_BytesRead</term>
-        /// <description>
-        ///   Set during the save of a particular entry, to update progress of the
-        ///   Save().  When this EventType is set, the BytesTransferred is the
-        ///   number of bytes that have been read from the source stream.  The
-        ///   TotalBytesToTransfer is the number of bytes in the uncompressed
-        ///   file.
-        /// </description>
-        /// </item>
-        ///
-        /// </list>
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///    This example uses an anonymous method to handle the
-        ///    SaveProgress event, by updating a progress bar.
-        ///
-        /// <code lang="C#">
-        /// progressBar1.Value = 0;
-        /// progressBar1.Max = listbox1.Items.Count;
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///    // listbox1 contains a list of filenames
-        ///    zip.AddFiles(listbox1.Items);
-        ///
-        ///    // do the progress bar:
-        ///    zip.SaveProgress += (sender, e) => {
-        ///       if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) {
-        ///          progressBar1.PerformStep();
-        ///       }
-        ///    };
-        ///
-        ///    zip.Save(fs);
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        ///   This example uses a named method as the
-        ///   <c>SaveProgress</c> event handler, to update the user, in a
-        ///   console-based application.
-        ///
-        /// <code lang="C#">
-        /// static bool justHadByteUpdate= false;
-        /// public static void SaveProgress(object sender, SaveProgressEventArgs e)
-        /// {
-        ///     if (e.EventType == ZipProgressEventType.Saving_Started)
-        ///         Console.WriteLine("Saving: {0}", e.ArchiveName);
-        ///
-        ///     else if (e.EventType == ZipProgressEventType.Saving_Completed)
-        ///     {
-        ///         justHadByteUpdate= false;
-        ///         Console.WriteLine();
-        ///         Console.WriteLine("Done: {0}", e.ArchiveName);
-        ///     }
-        ///
-        ///     else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
-        ///     {
-        ///         if (justHadByteUpdate)
-        ///             Console.WriteLine();
-        ///         Console.WriteLine("  Writing: {0} ({1}/{2})",
-        ///                           e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal);
-        ///         justHadByteUpdate= false;
-        ///     }
-        ///
-        ///     else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
-        ///     {
-        ///         if (justHadByteUpdate)
-        ///             Console.SetCursorPosition(0, Console.CursorTop);
-        ///          Console.Write("     {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
-        ///                       e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
-        ///         justHadByteUpdate= true;
-        ///     }
-        /// }
-        ///
-        /// public static ZipUp(string targetZip, string directory)
-        /// {
-        ///   using (var zip = new ZipFile()) {
-        ///     zip.SaveProgress += SaveProgress;
-        ///     zip.AddDirectory(directory);
-        ///     zip.Save(targetZip);
-        ///   }
-        /// }
-        ///
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Public Sub ZipUp(ByVal targetZip As String, ByVal directory As String)
-        ///     Using zip As ZipFile = New ZipFile
-        ///         AddHandler zip.SaveProgress, AddressOf MySaveProgress
-        ///         zip.AddDirectory(directory)
-        ///         zip.Save(targetZip)
-        ///     End Using
-        /// End Sub
-        ///
-        /// Private Shared justHadByteUpdate As Boolean = False
-        ///
-        /// Public Shared Sub MySaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
-        ///     If (e.EventType Is ZipProgressEventType.Saving_Started) Then
-        ///         Console.WriteLine("Saving: {0}", e.ArchiveName)
-        ///
-        ///     ElseIf (e.EventType Is ZipProgressEventType.Saving_Completed) Then
-        ///         justHadByteUpdate = False
-        ///         Console.WriteLine
-        ///         Console.WriteLine("Done: {0}", e.ArchiveName)
-        ///
-        ///     ElseIf (e.EventType Is ZipProgressEventType.Saving_BeforeWriteEntry) Then
-        ///         If justHadByteUpdate Then
-        ///             Console.WriteLine
-        ///         End If
-        ///         Console.WriteLine("  Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal)
-        ///         justHadByteUpdate = False
-        ///
-        ///     ElseIf (e.EventType Is ZipProgressEventType.Saving_EntryBytesRead) Then
-        ///         If justHadByteUpdate Then
-        ///             Console.SetCursorPosition(0, Console.CursorTop)
-        ///         End If
-        ///         Console.Write("     {0}/{1} ({2:N0}%)", e.BytesTransferred, _
-        ///                       e.TotalBytesToTransfer, _
-        ///                       (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
-        ///         justHadByteUpdate = True
-        ///     End If
-        /// End Sub
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        ///
-        /// This is a more complete example of using the SaveProgress
-        /// events in a Windows Forms application, with a
-        /// Thread object.
-        ///
-        /// <code lang="C#">
-        /// delegate void SaveEntryProgress(SaveProgressEventArgs e);
-        /// delegate void ButtonClick(object sender, EventArgs e);
-        ///
-        /// internal class WorkerOptions
-        /// {
-        ///     public string ZipName;
-        ///     public string Folder;
-        ///     public string Encoding;
-        ///     public string Comment;
-        ///     public int ZipFlavor;
-        ///     public Zip64Option Zip64;
-        /// }
-        ///
-        /// private int _progress2MaxFactor;
-        /// private bool _saveCanceled;
-        /// private long _totalBytesBeforeCompress;
-        /// private long _totalBytesAfterCompress;
-        /// private Thread _workerThread;
-        ///
-        ///
-        /// private void btnZipup_Click(object sender, EventArgs e)
-        /// {
-        ///     KickoffZipup();
-        /// }
-        ///
-        /// private void btnCancel_Click(object sender, EventArgs e)
-        /// {
-        ///     if (this.lblStatus.InvokeRequired)
-        ///     {
-        ///         this.lblStatus.Invoke(new ButtonClick(this.btnCancel_Click), new object[] { sender, e });
-        ///     }
-        ///     else
-        ///     {
-        ///         _saveCanceled = true;
-        ///         lblStatus.Text = "Canceled...";
-        ///         ResetState();
-        ///     }
-        /// }
-        ///
-        /// private void KickoffZipup()
-        /// {
-        ///     _folderName = tbDirName.Text;
-        ///
-        ///     if (_folderName == null || _folderName == "") return;
-        ///     if (this.tbZipName.Text == null || this.tbZipName.Text == "") return;
-        ///
-        ///     // check for existence of the zip file:
-        ///     if (System.IO.File.Exists(this.tbZipName.Text))
-        ///     {
-        ///         var dlgResult = MessageBox.Show(String.Format("The file you have specified ({0}) already exists." +
-        ///                                                       "  Do you want to overwrite this file?", this.tbZipName.Text),
-        ///                                         "Confirmation is Required", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
-        ///         if (dlgResult != DialogResult.Yes) return;
-        ///         System.IO.File.Delete(this.tbZipName.Text);
-        ///     }
-        ///
-        ///      _saveCanceled = false;
-        ///     _nFilesCompleted = 0;
-        ///     _totalBytesAfterCompress = 0;
-        ///     _totalBytesBeforeCompress = 0;
-        ///     this.btnOk.Enabled = false;
-        ///     this.btnOk.Text = "Zipping...";
-        ///     this.btnCancel.Enabled = true;
-        ///     lblStatus.Text = "Zipping...";
-        ///
-        ///     var options = new WorkerOptions
-        ///     {
-        ///         ZipName = this.tbZipName.Text,
-        ///         Folder = _folderName,
-        ///         Encoding = "ibm437"
-        ///     };
-        ///
-        ///     if (this.comboBox1.SelectedIndex != 0)
-        ///     {
-        ///         options.Encoding = this.comboBox1.SelectedItem.ToString();
-        ///     }
-        ///
-        ///     if (this.radioFlavorSfxCmd.Checked)
-        ///         options.ZipFlavor = 2;
-        ///     else if (this.radioFlavorSfxGui.Checked)
-        ///         options.ZipFlavor = 1;
-        ///     else options.ZipFlavor = 0;
-        ///
-        ///     if (this.radioZip64AsNecessary.Checked)
-        ///         options.Zip64 = Zip64Option.AsNecessary;
-        ///     else if (this.radioZip64Always.Checked)
-        ///         options.Zip64 = Zip64Option.Always;
-        ///     else options.Zip64 = Zip64Option.Never;
-        ///
-        ///     options.Comment = String.Format("Encoding:{0} || Flavor:{1} || ZIP64:{2}\r\nCreated at {3} || {4}\r\n",
-        ///                 options.Encoding,
-        ///                 FlavorToString(options.ZipFlavor),
-        ///                 options.Zip64.ToString(),
-        ///                 System.DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"),
-        ///                 this.Text);
-        ///
-        ///     if (this.tbComment.Text != TB_COMMENT_NOTE)
-        ///         options.Comment += this.tbComment.Text;
-        ///
-        ///     _workerThread = new Thread(this.DoSave);
-        ///     _workerThread.Name = "Zip Saver thread";
-        ///     _workerThread.Start(options);
-        ///     this.Cursor = Cursors.WaitCursor;
-        ///  }
-        ///
-        ///
-        /// private void DoSave(Object p)
-        /// {
-        ///     WorkerOptions options = p as WorkerOptions;
-        ///     try
-        ///     {
-        ///         using (var zip1 = new ZipFile())
-        ///         {
-        ///             zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(options.Encoding);
-        ///             zip1.Comment = options.Comment;
-        ///             zip1.AddDirectory(options.Folder);
-        ///             _entriesToZip = zip1.EntryFileNames.Count;
-        ///             SetProgressBars();
-        ///             zip1.SaveProgress += this.zip1_SaveProgress;
-        ///
-        ///             zip1.UseZip64WhenSaving = options.Zip64;
-        ///
-        ///             if (options.ZipFlavor == 1)
-        ///                 zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.WinFormsApplication);
-        ///             else if (options.ZipFlavor == 2)
-        ///                 zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.ConsoleApplication);
-        ///             else
-        ///                 zip1.Save(options.ZipName);
-        ///         }
-        ///     }
-        ///     catch (System.Exception exc1)
-        ///     {
-        ///         MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message));
-        ///         btnCancel_Click(null, null);
-        ///     }
-        /// }
-        ///
-        ///
-        ///
-        /// void zip1_SaveProgress(object sender, SaveProgressEventArgs e)
-        /// {
-        ///     switch (e.EventType)
-        ///     {
-        ///         case ZipProgressEventType.Saving_AfterWriteEntry:
-        ///             StepArchiveProgress(e);
-        ///             break;
-        ///         case ZipProgressEventType.Saving_EntryBytesRead:
-        ///             StepEntryProgress(e);
-        ///             break;
-        ///         case ZipProgressEventType.Saving_Completed:
-        ///             SaveCompleted();
-        ///             break;
-        ///         case ZipProgressEventType.Saving_AfterSaveTempArchive:
-        ///             // this event only occurs when saving an SFX file
-        ///             TempArchiveSaved();
-        ///             break;
-        ///     }
-        ///     if (_saveCanceled)
-        ///         e.Cancel = true;
-        /// }
-        ///
-        ///
-        ///
-        /// private void StepArchiveProgress(SaveProgressEventArgs e)
-        /// {
-        ///     if (this.progressBar1.InvokeRequired)
-        ///     {
-        ///         this.progressBar1.Invoke(new SaveEntryProgress(this.StepArchiveProgress), new object[] { e });
-        ///     }
-        ///     else
-        ///     {
-        ///         if (!_saveCanceled)
-        ///         {
-        ///             _nFilesCompleted++;
-        ///             this.progressBar1.PerformStep();
-        ///             _totalBytesAfterCompress += e.CurrentEntry.CompressedSize;
-        ///             _totalBytesBeforeCompress += e.CurrentEntry.UncompressedSize;
-        ///
-        ///             // reset the progress bar for the entry:
-        ///             this.progressBar2.Value = this.progressBar2.Maximum = 1;
-        ///
-        ///             this.Update();
-        ///         }
-        ///     }
-        /// }
-        ///
-        ///
-        /// private void StepEntryProgress(SaveProgressEventArgs e)
-        /// {
-        ///     if (this.progressBar2.InvokeRequired)
-        ///     {
-        ///         this.progressBar2.Invoke(new SaveEntryProgress(this.StepEntryProgress), new object[] { e });
-        ///     }
-        ///     else
-        ///     {
-        ///         if (!_saveCanceled)
-        ///         {
-        ///             if (this.progressBar2.Maximum == 1)
-        ///             {
-        ///                 // reset
-        ///                 Int64 max = e.TotalBytesToTransfer;
-        ///                 _progress2MaxFactor = 0;
-        ///                 while (max > System.Int32.MaxValue)
-        ///                 {
-        ///                     max /= 2;
-        ///                     _progress2MaxFactor++;
-        ///                 }
-        ///                 this.progressBar2.Maximum = (int)max;
-        ///                 lblStatus.Text = String.Format("{0} of {1} files...({2})",
-        ///                     _nFilesCompleted + 1, _entriesToZip, e.CurrentEntry.FileName);
-        ///             }
-        ///
-        ///              int xferred = e.BytesTransferred >> _progress2MaxFactor;
-        ///
-        ///              this.progressBar2.Value = (xferred >= this.progressBar2.Maximum)
-        ///                 ? this.progressBar2.Maximum
-        ///                 : xferred;
-        ///
-        ///              this.Update();
-        ///         }
-        ///     }
-        /// }
-        ///
-        /// private void SaveCompleted()
-        /// {
-        ///     if (this.lblStatus.InvokeRequired)
-        ///     {
-        ///         this.lblStatus.Invoke(new MethodInvoker(this.SaveCompleted));
-        ///     }
-        ///     else
-        ///     {
-        ///         lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original.",
-        ///             _nFilesCompleted, (100.00 * _totalBytesAfterCompress) / _totalBytesBeforeCompress);
-        ///          ResetState();
-        ///     }
-        /// }
-        ///
-        /// private void ResetState()
-        /// {
-        ///     this.btnCancel.Enabled = false;
-        ///     this.btnOk.Enabled = true;
-        ///     this.btnOk.Text = "Zip it!";
-        ///     this.progressBar1.Value = 0;
-        ///     this.progressBar2.Value = 0;
-        ///     this.Cursor = Cursors.Default;
-        ///     if (!_workerThread.IsAlive)
-        ///         _workerThread.Join();
-        /// }
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
-        internal event EventHandler<SaveProgressEventArgs> SaveProgress;
-
-
-        internal bool OnSaveBlock(ZipEntry entry, Int64 bytesXferred, Int64 totalBytesToXfer)
-        {
-            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
-            if (sp != null)
-            {
-                var e = SaveProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
-                                                         bytesXferred, totalBytesToXfer);
-                sp(this, e);
-                if (e.Cancel)
-                    _saveOperationCanceled = true;
-            }
-            return _saveOperationCanceled;
-        }
-
-        private void OnSaveEntry(int current, ZipEntry entry, bool before)
-        {
-            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
-            if (sp != null)
-            {
-                var e = new SaveProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, entry);
-                sp(this, e);
-                if (e.Cancel)
-                    _saveOperationCanceled = true;
-            }
-        }
-
-        private void OnSaveEvent(ZipProgressEventType eventFlavor)
-        {
-            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
-            if (sp != null)
-            {
-                var e = new SaveProgressEventArgs(ArchiveNameForEvent, eventFlavor);
-                sp(this, e);
-                if (e.Cancel)
-                    _saveOperationCanceled = true;
-            }
-        }
-
-        private void OnSaveStarted()
-        {
-            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
-            if (sp != null)
-            {
-                var e = SaveProgressEventArgs.Started(ArchiveNameForEvent);
-                sp(this, e);
-                if (e.Cancel)
-                    _saveOperationCanceled = true;
-            }
-        }
-        private void OnSaveCompleted()
-        {
-            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
-            if (sp != null)
-            {
-                var e = SaveProgressEventArgs.Completed(ArchiveNameForEvent);
-                sp(this, e);
-            }
-        }
-        #endregion
-
-
-        #region Read
-        /// <summary>
-        /// An event handler invoked before, during, and after the reading of a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// Depending on the particular event being signaled, different properties on the
-        /// <see cref="ReadProgressEventArgs"/> parameter are set.  The following table
-        /// summarizes the available EventTypes and the conditions under which this
-        /// event handler is invoked with a <c>ReadProgressEventArgs</c> with the given EventType.
-        /// </para>
-        ///
-        /// <list type="table">
-        /// <listheader>
-        /// <term>value of EntryType</term>
-        /// <description>Meaning and conditions</description>
-        /// </listheader>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Reading_Started</term>
-        /// <description>Fired just as ZipFile.Read() begins. Meaningful properties: ArchiveName.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Reading_Completed</term>
-        /// <description>Fired when ZipFile.Read() has completed. Meaningful properties: ArchiveName.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Reading_ArchiveBytesRead</term>
-        /// <description>Fired while reading, updates the number of bytes read for the entire archive.
-        /// Meaningful properties: ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Reading_BeforeReadEntry</term>
-        /// <description>Indicates an entry is about to be read from the archive.
-        /// Meaningful properties: ArchiveName, EntriesTotal.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Reading_AfterReadEntry</term>
-        /// <description>Indicates an entry has just been read from the archive.
-        /// Meaningful properties: ArchiveName, EntriesTotal, CurrentEntry.
-        /// </description>
-        /// </item>
-        ///
-        /// </list>
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
-        internal event EventHandler<ReadProgressEventArgs> ReadProgress;
-
-        private void OnReadStarted()
-        {
-            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
-            if (rp != null)
-            {
-                    var e = ReadProgressEventArgs.Started(ArchiveNameForEvent);
-                    rp(this, e);
-            }
-        }
-
-        private void OnReadCompleted()
-        {
-            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
-            if (rp != null)
-            {
-                    var e = ReadProgressEventArgs.Completed(ArchiveNameForEvent);
-                    rp(this, e);
-            }
-        }
-
-        internal void OnReadBytes(ZipEntry entry)
-        {
-            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
-            if (rp != null)
-            {
-                    var e = ReadProgressEventArgs.ByteUpdate(ArchiveNameForEvent,
-                                        entry,
-                                        ReadStream.Position,
-                                        LengthOfReadStream);
-                    rp(this, e);
-            }
-        }
-
-        internal void OnReadEntry(bool before, ZipEntry entry)
-        {
-            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
-            if (rp != null)
-            {
-                ReadProgressEventArgs e = (before)
-                    ? ReadProgressEventArgs.Before(ArchiveNameForEvent, _entries.Count)
-                    : ReadProgressEventArgs.After(ArchiveNameForEvent, entry, _entries.Count);
-                rp(this, e);
-            }
-        }
-
-        private Int64 _lengthOfReadStream = -99;
-        private Int64 LengthOfReadStream
-        {
-            get
-            {
-                if (_lengthOfReadStream == -99)
-                {
-                    _lengthOfReadStream = (_ReadStreamIsOurs)
-                        ? SharedUtilities.GetFileLength(_name)
-                        : -1L;
-                }
-                return _lengthOfReadStream;
-            }
-        }
-        #endregion
-
-
-        #region Extract
-        /// <summary>
-        ///   An event handler invoked before, during, and after extraction of
-        ///   entries in the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Depending on the particular event, different properties on the <see
-        ///   cref="ExtractProgressEventArgs"/> parameter are set.  The following
-        ///   table summarizes the available EventTypes and the conditions under
-        ///   which this event handler is invoked with a
-        ///   <c>ExtractProgressEventArgs</c> with the given EventType.
-        /// </para>
-        ///
-        /// <list type="table">
-        /// <listheader>
-        /// <term>value of EntryType</term>
-        /// <description>Meaning and conditions</description>
-        /// </listheader>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Extracting_BeforeExtractAll</term>
-        /// <description>
-        ///   Set when ExtractAll() begins. The ArchiveName, Overwrite, and
-        ///   ExtractLocation properties are meaningful.</description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Extracting_AfterExtractAll</term>
-        /// <description>
-        ///   Set when ExtractAll() has completed.  The ArchiveName, Overwrite,
-        ///   and ExtractLocation properties are meaningful.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Extracting_BeforeExtractEntry</term>
-        /// <description>
-        ///   Set when an Extract() on an entry in the ZipFile has begun.
-        ///   Properties that are meaningful: ArchiveName, EntriesTotal,
-        ///   CurrentEntry, Overwrite, ExtractLocation, EntriesExtracted.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Extracting_AfterExtractEntry</term>
-        /// <description>
-        ///   Set when an Extract() on an entry in the ZipFile has completed.
-        ///   Properties that are meaningful: ArchiveName, EntriesTotal,
-        ///   CurrentEntry, Overwrite, ExtractLocation, EntriesExtracted.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Extracting_EntryBytesWritten</term>
-        /// <description>
-        ///   Set within a call to Extract() on an entry in the ZipFile, as data
-        ///   is extracted for the entry.  Properties that are meaningful:
-        ///   ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
-        /// </description>
-        /// </item>
-        ///
-        /// <item>
-        /// <term>ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite</term>
-        /// <description>
-        ///   Set within a call to Extract() on an entry in the ZipFile, when the
-        ///   extraction would overwrite an existing file. This event type is used
-        ///   only when <c>ExtractExistingFileAction</c> on the <c>ZipFile</c> or
-        ///   <c>ZipEntry</c> is set to <c>InvokeExtractProgressEvent</c>.
-        /// </description>
-        /// </item>
-        ///
-        /// </list>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code>
-        /// private static bool justHadByteUpdate = false;
-        /// public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
-        /// {
-        ///   if(e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
-        ///   {
-        ///     if (justHadByteUpdate)
-        ///       Console.SetCursorPosition(0, Console.CursorTop);
-        ///
-        ///     Console.Write("   {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
-        ///                   e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
-        ///     justHadByteUpdate = true;
-        ///   }
-        ///   else if(e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
-        ///   {
-        ///     if (justHadByteUpdate)
-        ///       Console.WriteLine();
-        ///     Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName);
-        ///     justHadByteUpdate= false;
-        ///   }
-        /// }
-        ///
-        /// public static ExtractZip(string zipToExtract, string directory)
-        /// {
-        ///   string TargetDirectory= "extract";
-        ///   using (var zip = ZipFile.Read(zipToExtract)) {
-        ///     zip.ExtractProgress += ExtractProgress;
-        ///     foreach (var e in zip1)
-        ///     {
-        ///       e.Extract(TargetDirectory, true);
-        ///     }
-        ///   }
-        /// }
-        ///
-        /// </code>
-        /// <code lang="VB">
-        /// Public Shared Sub Main(ByVal args As String())
-        ///     Dim ZipToUnpack As String = "C1P3SML.zip"
-        ///     Dim TargetDir As String = "ExtractTest_Extract"
-        ///     Console.WriteLine("Extracting file {0} to {1}", ZipToUnpack, TargetDir)
-        ///     Using zip1 As ZipFile = ZipFile.Read(ZipToUnpack)
-        ///         AddHandler zip1.ExtractProgress, AddressOf MyExtractProgress
-        ///         Dim e As ZipEntry
-        ///         For Each e In zip1
-        ///             e.Extract(TargetDir, True)
-        ///         Next
-        ///     End Using
-        /// End Sub
-        ///
-        /// Private Shared justHadByteUpdate As Boolean = False
-        ///
-        /// Public Shared Sub MyExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
-        ///     If (e.EventType = ZipProgressEventType.Extracting_EntryBytesWritten) Then
-        ///         If ExtractTest.justHadByteUpdate Then
-        ///             Console.SetCursorPosition(0, Console.CursorTop)
-        ///         End If
-        ///         Console.Write("   {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer, (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
-        ///         ExtractTest.justHadByteUpdate = True
-        ///     ElseIf (e.EventType = ZipProgressEventType.Extracting_BeforeExtractEntry) Then
-        ///         If ExtractTest.justHadByteUpdate Then
-        ///             Console.WriteLine
-        ///         End If
-        ///         Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName)
-        ///         ExtractTest.justHadByteUpdate = False
-        ///     End If
-        /// End Sub
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
-        internal event EventHandler<ExtractProgressEventArgs> ExtractProgress;
-
-
-
-        private void OnExtractEntry(int current, bool before, ZipEntry currentEntry, string path)
-        {
-            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
-            if (ep != null)
-            {
-                var e = new ExtractProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, currentEntry, path);
-                ep(this, e);
-                if (e.Cancel)
-                    _extractOperationCanceled = true;
-            }
-        }
-
-
-        // Can be called from within ZipEntry._ExtractOne.
-        internal bool OnExtractBlock(ZipEntry entry, Int64 bytesWritten, Int64 totalBytesToWrite)
-        {
-            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
-            if (ep != null)
-            {
-                var e = ExtractProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
-                                                            bytesWritten, totalBytesToWrite);
-                ep(this, e);
-                if (e.Cancel)
-                    _extractOperationCanceled = true;
-            }
-            return _extractOperationCanceled;
-        }
-
-
-        // Can be called from within ZipEntry.InternalExtract.
-        internal bool OnSingleEntryExtract(ZipEntry entry, string path, bool before)
-        {
-            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
-            if (ep != null)
-            {
-                var e = (before)
-                    ? ExtractProgressEventArgs.BeforeExtractEntry(ArchiveNameForEvent, entry, path)
-                    : ExtractProgressEventArgs.AfterExtractEntry(ArchiveNameForEvent, entry, path);
-                ep(this, e);
-                if (e.Cancel)
-                    _extractOperationCanceled = true;
-            }
-            return _extractOperationCanceled;
-        }
-
-        internal bool OnExtractExisting(ZipEntry entry, string path)
-        {
-            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
-            if (ep != null)
-            {
-                var e = ExtractProgressEventArgs.ExtractExisting(ArchiveNameForEvent, entry, path);
-                ep(this, e);
-                if (e.Cancel)
-                    _extractOperationCanceled = true;
-            }
-            return _extractOperationCanceled;
-        }
-
-
-        private void OnExtractAllCompleted(string path)
-        {
-            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
-            if (ep != null)
-            {
-                var e = ExtractProgressEventArgs.ExtractAllCompleted(ArchiveNameForEvent,
-                                                                     path );
-                ep(this, e);
-            }
-        }
-
-
-        private void OnExtractAllStarted(string path)
-        {
-            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
-            if (ep != null)
-            {
-                var e = ExtractProgressEventArgs.ExtractAllStarted(ArchiveNameForEvent,
-                                                                   path );
-                ep(this, e);
-            }
-        }
-
-
-        #endregion
-
-
-
-        #region Add
-        /// <summary>
-        /// An event handler invoked before, during, and after Adding entries to a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///     Adding a large number of entries to a zip file can take a long
-        ///     time.  For example, when calling <see cref="AddDirectory(string)"/> on a
-        ///     directory that contains 50,000 files, it could take 3 minutes or so.
-        ///     This event handler allws an application to track the progress of the Add
-        ///     operation, and to optionally cancel a lengthy Add operation.
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code lang="C#">
-        ///
-        /// int _numEntriesToAdd= 0;
-        /// int _numEntriesAdded= 0;
-        /// void AddProgressHandler(object sender, AddProgressEventArgs e)
-        /// {
-        ///     switch (e.EventType)
-        ///     {
-        ///         case ZipProgressEventType.Adding_Started:
-        ///             Console.WriteLine("Adding files to the zip...");
-        ///             break;
-        ///         case ZipProgressEventType.Adding_AfterAddEntry:
-        ///             _numEntriesAdded++;
-        ///             Console.WriteLine(String.Format("Adding file {0}/{1} :: {2}",
-        ///                                      _numEntriesAdded, _numEntriesToAdd, e.CurrentEntry.FileName));
-        ///             break;
-        ///         case ZipProgressEventType.Adding_Completed:
-        ///             Console.WriteLine("Added all files");
-        ///             break;
-        ///     }
-        /// }
-        ///
-        /// void CreateTheZip()
-        /// {
-        ///     using (ZipFile zip = new ZipFile())
-        ///     {
-        ///         zip.AddProgress += AddProgressHandler;
-        ///         zip.AddDirectory(System.IO.Path.GetFileName(DirToZip));
-        ///         zip.Save(ZipFileToCreate);
-        ///     }
-        /// }
-        ///
-        /// </code>
-        ///
-        /// <code lang="VB">
-        ///
-        /// Private Sub AddProgressHandler(ByVal sender As Object, ByVal e As AddProgressEventArgs)
-        ///     Select Case e.EventType
-        ///         Case ZipProgressEventType.Adding_Started
-        ///             Console.WriteLine("Adding files to the zip...")
-        ///             Exit Select
-        ///         Case ZipProgressEventType.Adding_AfterAddEntry
-        ///             Console.WriteLine(String.Format("Adding file {0}", e.CurrentEntry.FileName))
-        ///             Exit Select
-        ///         Case ZipProgressEventType.Adding_Completed
-        ///             Console.WriteLine("Added all files")
-        ///             Exit Select
-        ///     End Select
-        /// End Sub
-        ///
-        /// Sub CreateTheZip()
-        ///     Using zip as ZipFile = New ZipFile
-        ///         AddHandler zip.AddProgress, AddressOf AddProgressHandler
-        ///         zip.AddDirectory(System.IO.Path.GetFileName(DirToZip))
-        ///         zip.Save(ZipFileToCreate);
-        ///     End Using
-        /// End Sub
-        ///
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
-        internal event EventHandler<AddProgressEventArgs> AddProgress;
-
-        private void OnAddStarted()
-        {
-            EventHandler<AddProgressEventArgs> ap = AddProgress;
-            if (ap != null)
-            {
-                var e = AddProgressEventArgs.Started(ArchiveNameForEvent);
-                ap(this, e);
-                if (e.Cancel) // workitem 13371
-                    _addOperationCanceled = true;
-            }
-        }
-
-        private void OnAddCompleted()
-        {
-            EventHandler<AddProgressEventArgs> ap = AddProgress;
-            if (ap != null)
-            {
-                var e = AddProgressEventArgs.Completed(ArchiveNameForEvent);
-                ap(this, e);
-            }
-        }
-
-        internal void AfterAddEntry(ZipEntry entry)
-        {
-            EventHandler<AddProgressEventArgs> ap = AddProgress;
-            if (ap != null)
-            {
-                var e = AddProgressEventArgs.AfterEntry(ArchiveNameForEvent, entry, _entries.Count);
-                ap(this, e);
-                if (e.Cancel) // workitem 13371
-                    _addOperationCanceled = true;
-            }
-        }
-
-        #endregion
-
-
-
-        #region Error
-        /// <summary>
-        /// An event that is raised when an error occurs during open or read of files
-        /// while saving a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///  <para>
-        ///     Errors can occur as a file is being saved to the zip archive.  For
-        ///     example, the File.Open may fail, or a File.Read may fail, because of
-        ///     lock conflicts or other reasons.  If you add a handler to this event,
-        ///     you can handle such errors in your own code.  If you don't add a
-        ///     handler, the library will throw an exception if it encounters an I/O
-        ///     error during a call to <c>Save()</c>.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    Setting a handler implicitly sets <see cref="ZipFile.ZipErrorAction"/> to
-        ///    <c>ZipErrorAction.InvokeErrorEvent</c>.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    The handler you add applies to all <see cref="ZipEntry"/> items that are
-        ///    subsequently added to the <c>ZipFile</c> instance. If you set this
-        ///    property after you have added items to the <c>ZipFile</c>, but before you
-        ///    have called <c>Save()</c>, errors that occur while saving those items
-        ///    will not cause the error handler to be invoked.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    If you want to handle any errors that occur with any entry in the zip
-        ///    file using the same error handler, then add your error handler once,
-        ///    before adding any entries to the zip archive.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    In the error handler method, you need to set the <see
-        ///    cref="ZipEntry.ZipErrorAction"/> property on the
-        ///    <c>ZipErrorEventArgs.CurrentEntry</c>.  This communicates back to
-        ///    DotNetZip what you would like to do with this particular error.  Within
-        ///    an error handler, if you set the <c>ZipEntry.ZipErrorAction</c> property
-        ///    on the <c>ZipEntry</c> to <c>ZipErrorAction.InvokeErrorEvent</c> or if
-        ///    you don't set it at all, the library will throw the exception. (It is the
-        ///    same as if you had set the <c>ZipEntry.ZipErrorAction</c> property on the
-        ///    <c>ZipEntry</c> to <c>ZipErrorAction.Throw</c>.) If you set the
-        ///    <c>ZipErrorEventArgs.Cancel</c> to true, the entire <c>Save()</c> will be
-        ///    canceled.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    In the case that you use <c>ZipErrorAction.Skip</c>, implying that
-        ///    you want to skip the entry for which there's been an error, DotNetZip
-        ///    tries to seek backwards in the output stream, and truncate all bytes
-        ///    written on behalf of that particular entry. This works only if the
-        ///    output stream is seekable.  It will not work, for example, when using
-        ///    ASPNET's Response.OutputStream.
-        ///  </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        /// This example shows how to use an event handler to handle
-        /// errors during save of the zip file.
-        /// <code lang="C#">
-        ///
-        /// public static void MyZipError(object sender, ZipErrorEventArgs e)
-        /// {
-        ///     Console.WriteLine("Error saving {0}...", e.FileName);
-        ///     Console.WriteLine("   Exception: {0}", e.exception);
-        ///     ZipEntry entry = e.CurrentEntry;
-        ///     string response = null;
-        ///     // Ask the user whether he wants to skip this error or not
-        ///     do
-        ///     {
-        ///         Console.Write("Retry, Skip, Throw, or Cancel ? (R/S/T/C) ");
-        ///         response = Console.ReadLine();
-        ///         Console.WriteLine();
-        ///
-        ///     } while (response != null &amp;&amp;
-        ///              response[0]!='S' &amp;&amp; response[0]!='s' &amp;&amp;
-        ///              response[0]!='R' &amp;&amp; response[0]!='r' &amp;&amp;
-        ///              response[0]!='T' &amp;&amp; response[0]!='t' &amp;&amp;
-        ///              response[0]!='C' &amp;&amp; response[0]!='c');
-        ///
-        ///     e.Cancel = (response[0]=='C' || response[0]=='c');
-        ///
-        ///     if (response[0]=='S' || response[0]=='s')
-        ///         entry.ZipErrorAction = ZipErrorAction.Skip;
-        ///     else if (response[0]=='R' || response[0]=='r')
-        ///         entry.ZipErrorAction = ZipErrorAction.Retry;
-        ///     else if (response[0]=='T' || response[0]=='t')
-        ///         entry.ZipErrorAction = ZipErrorAction.Throw;
-        /// }
-        ///
-        /// public void SaveTheFile()
-        /// {
-        ///   string directoryToZip = "fodder";
-        ///   string directoryInArchive = "files";
-        ///   string zipFileToCreate = "Archive.zip";
-        ///   using (var zip = new ZipFile())
-        ///   {
-        ///     // set the event handler before adding any entries
-        ///     zip.ZipError += MyZipError;
-        ///     zip.AddDirectory(directoryToZip, directoryInArchive);
-        ///     zip.Save(zipFileToCreate);
-        ///   }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Private Sub MyZipError(ByVal sender As Object, ByVal e As Ionic.Zip.ZipErrorEventArgs)
-        ///     ' At this point, the application could prompt the user for an action to take.
-        ///     ' But in this case, this application will simply automatically skip the file, in case of error.
-        ///     Console.WriteLine("Zip Error,  entry {0}", e.CurrentEntry.FileName)
-        ///     Console.WriteLine("   Exception: {0}", e.exception)
-        ///     ' set the desired ZipErrorAction on the CurrentEntry to communicate that to DotNetZip
-        ///     e.CurrentEntry.ZipErrorAction = Zip.ZipErrorAction.Skip
-        /// End Sub
-        ///
-        /// Public Sub SaveTheFile()
-        ///     Dim directoryToZip As String = "fodder"
-        ///     Dim directoryInArchive As String = "files"
-        ///     Dim zipFileToCreate as String = "Archive.zip"
-        ///     Using zipArchive As ZipFile = New ZipFile
-        ///         ' set the event handler before adding any entries
-        ///         AddHandler zipArchive.ZipError, AddressOf MyZipError
-        ///         zipArchive.AddDirectory(directoryToZip, directoryInArchive)
-        ///         zipArchive.Save(zipFileToCreate)
-        ///     End Using
-        /// End Sub
-        ///
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.ZipErrorAction"/>
-        internal event EventHandler<ZipErrorEventArgs> ZipError;
-
-        internal bool OnZipErrorSaving(ZipEntry entry, Exception exc)
-        {
-            if (ZipError != null)
-            {
-                lock (LOCK)
-                {
-                    var e = ZipErrorEventArgs.Saving(this.Name, entry, exc);
-                    ZipError(this, e);
-                    if (e.Cancel)
-                        _saveOperationCanceled = true;
-                }
-            }
-            return _saveOperationCanceled;
-        }
-        #endregion
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.Extract.cs b/EPPlus/Packaging/DotNetZip/ZipFile.Extract.cs
deleted file mode 100644
index 2fd8646..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.Extract.cs
+++ /dev/null
@@ -1,298 +0,0 @@
-// ZipFile.Extract.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-31 14:45:18>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for Extract operations on zip files.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    internal partial class ZipFile
-    {
-
-        /// <summary>
-        /// Extracts all of the items in the zip archive, to the specified path in the
-        /// filesystem.  The path can be relative or fully-qualified.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method will extract all entries in the <c>ZipFile</c> to the
-        ///   specified path.
-        /// </para>
-        ///
-        /// <para>
-        ///   If an extraction of a file from the zip archive would overwrite an
-        ///   existing file in the filesystem, the action taken is dictated by the
-        ///   ExtractExistingFile property, which overrides any setting you may have
-        ///   made on individual ZipEntry instances.  By default, if you have not
-        ///   set that property on the <c>ZipFile</c> instance, the entry will not
-        ///   be extracted, the existing file will not be overwritten and an
-        ///   exception will be thrown. To change this, set the property, or use the
-        ///   <see cref="ZipFile.ExtractAll(string,
-        ///   Ionic.Zip.ExtractExistingFileAction)" /> overload that allows you to
-        ///   specify an ExtractExistingFileAction parameter.
-        /// </para>
-        ///
-        /// <para>
-        ///   The action to take when an extract would overwrite an existing file
-        ///   applies to all entries.  If you want to set this on a per-entry basis,
-        ///   then you must use one of the <see
-        ///   cref="ZipEntry.Extract()">ZipEntry.Extract</see> methods.
-        /// </para>
-        ///
-        /// <para>
-        ///   This method will send verbose output messages to the <see
-        ///   cref="StatusMessageTextWriter"/>, if it is set on the <c>ZipFile</c>
-        ///   instance.
-        /// </para>
-        ///
-        /// <para>
-        /// You may wish to take advantage of the <c>ExtractProgress</c> event.
-        /// </para>
-        ///
-        /// <para>
-        ///   About timestamps: When extracting a file entry from a zip archive, the
-        ///   extracted file gets the last modified time of the entry as stored in
-        ///   the archive. The archive may also store extended file timestamp
-        ///   information, including last accessed and created times. If these are
-        ///   present in the <c>ZipEntry</c>, then the extracted file will also get
-        ///   these times.
-        /// </para>
-        ///
-        /// <para>
-        ///   A Directory entry is somewhat different. It will get the times as
-        ///   described for a file entry, but, if there are file entries in the zip
-        ///   archive that, when extracted, appear in the just-created directory,
-        ///   then when those file entries are extracted, the last modified and last
-        ///   accessed times of the directory will change, as a side effect.  The
-        ///   result is that after an extraction of a directory and a number of
-        ///   files within the directory, the last modified and last accessed
-        ///   timestamps on the directory will reflect the time that the last file
-        ///   was extracted into the directory, rather than the time stored in the
-        ///   zip archive for the directory.
-        /// </para>
-        ///
-        /// <para>
-        ///   To compensate, when extracting an archive with <c>ExtractAll</c>,
-        ///   DotNetZip will extract all the file and directory entries as described
-        ///   above, but it will then make a second pass on the directories, and
-        ///   reset the times on the directories to reflect what is stored in the
-        ///   zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   This compensation is performed only within the context of an
-        ///   <c>ExtractAll</c>. If you call <c>ZipEntry.Extract</c> on a directory
-        ///   entry, the timestamps on directory in the filesystem will reflect the
-        ///   times stored in the zip.  If you then call <c>ZipEntry.Extract</c> on
-        ///   a file entry, which is extracted into the directory, the timestamps on
-        ///   the directory will be updated to the current time.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example extracts all the entries in a zip archive file, to the
-        ///   specified target directory.  The extraction will overwrite any
-        ///   existing files silently.
-        ///
-        /// <code>
-        /// String TargetDirectory= "unpack";
-        /// using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
-        /// {
-        ///     zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently;
-        ///     zip.ExtractAll(TargetDirectory);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim TargetDirectory As String = "unpack"
-        /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
-        ///     zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently
-        ///     zip.ExtractAll(TargetDirectory)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ExtractExistingFile"/>
-        ///
-        /// <param name="path">
-        ///   The path to which the contents of the zipfile will be extracted.
-        ///   The path can be relative or fully-qualified.
-        /// </param>
-        ///
-        public void ExtractAll(string path)
-        {
-            _InternalExtractAll(path, true);
-        }
-
-
-
-        /// <summary>
-        /// Extracts all of the items in the zip archive, to the specified path in the
-        /// filesystem, using the specified behavior when extraction would overwrite an
-        /// existing file.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        /// This method will extract all entries in the <c>ZipFile</c> to the specified
-        /// path.  For an extraction that would overwrite an existing file, the behavior
-        /// is dictated by <paramref name="extractExistingFile"/>, which overrides any
-        /// setting you may have made on individual ZipEntry instances.
-        /// </para>
-        ///
-        /// <para>
-        /// The action to take when an extract would overwrite an existing file
-        /// applies to all entries.  If you want to set this on a per-entry basis,
-        /// then you must use <see cref="ZipEntry.Extract(String,
-        /// ExtractExistingFileAction)" /> or one of the similar methods.
-        /// </para>
-        ///
-        /// <para>
-        /// Calling this method is equivalent to setting the <see
-        /// cref="ExtractExistingFile"/> property and then calling <see
-        /// cref="ExtractAll(String)"/>.
-        /// </para>
-        ///
-        /// <para>
-        /// This method will send verbose output messages to the
-        /// <see cref="StatusMessageTextWriter"/>, if it is set on the <c>ZipFile</c> instance.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example extracts all the entries in a zip archive file, to the
-        /// specified target directory.  It does not overwrite any existing files.
-        /// <code>
-        /// String TargetDirectory= "c:\\unpack";
-        /// using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
-        /// {
-        ///   zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim TargetDirectory As String = "c:\unpack"
-        /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
-        ///     zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="path">
-        /// The path to which the contents of the zipfile will be extracted.
-        /// The path can be relative or fully-qualified.
-        /// </param>
-        ///
-        /// <param name="extractExistingFile">
-        /// The action to take if extraction would overwrite an existing file.
-        /// </param>
-        /// <seealso cref="ExtractSelectedEntries(String,ExtractExistingFileAction)"/>
-        internal void ExtractAll(string path, ExtractExistingFileAction extractExistingFile)
-        {
-            ExtractExistingFile = extractExistingFile;
-            _InternalExtractAll(path, true);
-        }
-
-
-        private void _InternalExtractAll(string path, bool overrideExtractExistingProperty)
-        {
-            bool header = Verbose;
-            _inExtractAll = true;
-            try
-            {
-                OnExtractAllStarted(path);
-
-                int n = 0;
-                foreach (ZipEntry e in _entries.Values)
-                {
-                    if (header)
-                    {
-                        StatusMessageTextWriter.WriteLine("\n{1,-22} {2,-8} {3,4}   {4,-8}  {0}",
-                                  "Name", "Modified", "Size", "Ratio", "Packed");
-                        StatusMessageTextWriter.WriteLine(new System.String('-', 72));
-                        header = false;
-                    }
-                    if (Verbose)
-                    {
-                        StatusMessageTextWriter.WriteLine("{1,-22} {2,-8} {3,4:F0}%   {4,-8} {0}",
-                                  e.FileName,
-                                  e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
-                                  e.UncompressedSize,
-                                  e.CompressionRatio,
-                                  e.CompressedSize);
-                        if (!String.IsNullOrEmpty(e.Comment))
-                            StatusMessageTextWriter.WriteLine("  Comment: {0}", e.Comment);
-                    }
-                    e.Password = _Password;  // this may be null
-                    OnExtractEntry(n, true, e, path);
-                    if (overrideExtractExistingProperty)
-                        e.ExtractExistingFile = this.ExtractExistingFile;
-                    e.Extract(path);
-                    n++;
-                    OnExtractEntry(n, false, e, path);
-                    if (_extractOperationCanceled)
-                        break;
-                }
-
-                if (!_extractOperationCanceled)
-                {
-                    // workitem 8264:
-                    // now, set times on directory entries, again.
-                    // The problem is, extracting a file changes the times on the parent
-                    // directory.  So after all files have been extracted, we have to
-                    // run through the directories again.
-                    foreach (ZipEntry e in _entries.Values)
-                    {
-                        // check if it is a directory
-                        if ((e.IsDirectory) || (e.FileName.EndsWith("/")))
-                        {
-                            string outputFile = (e.FileName.StartsWith("/"))
-                                ? Path.Combine(path, e.FileName.Substring(1))
-                                : Path.Combine(path, e.FileName);
-
-                            e._SetTimes(outputFile, false);
-                        }
-                    }
-                    OnExtractAllCompleted(path);
-                }
-
-            }
-            finally
-            {
-
-                _inExtractAll = false;
-            }
-        }
-
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.Read.cs b/EPPlus/Packaging/DotNetZip/ZipFile.Read.cs
deleted file mode 100644
index a2ed0b4..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.Read.cs
+++ /dev/null
@@ -1,1110 +0,0 @@
-// ZipFile.Read.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-August-05 11:38:59>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for Reading zip files.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    ///   A class for collecting the various options that can be used when
-    ///   Reading zip files for extraction or update.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///   <para>
-    ///     When reading a zip file, there are several options an
-    ///     application can set, to modify how the file is read, or what
-    ///     the library does while reading.  This class collects those
-    ///     options into one container.
-    ///   </para>
-    ///
-    ///   <para>
-    ///     Pass an instance of the <c>ReadOptions</c> class into the
-    ///     <c>ZipFile.Read()</c> method.
-    ///   </para>
-    ///
-    /// <seealso cref="ZipFile.Read(String, ReadOptions)"/>.
-    /// <seealso cref="ZipFile.Read(Stream, ReadOptions)"/>.
-    /// </remarks>
-    internal class ReadOptions
-    {
-        /// <summary>
-        /// An event handler for Read operations.  When opening large zip
-        /// archives, you may want to display a progress bar or other
-        /// indicator of status progress while reading.  This parameter
-        /// allows you to specify a ReadProgress Event Handler directly.
-        /// When you call <c>Read()</c>, the progress event is invoked as
-        /// necessary.
-        /// </summary>
-        public EventHandler<ReadProgressEventArgs> ReadProgress { get; set; }
-
-        /// <summary>
-        /// The <c>System.IO.TextWriter</c> to use for writing verbose status messages
-        /// during operations on the zip archive.  A console application may wish to
-        /// pass <c>System.Console.Out</c> to get messages on the Console. A graphical
-        /// or headless application may wish to capture the messages in a different
-        /// <c>TextWriter</c>, such as a <c>System.IO.StringWriter</c>.
-        /// </summary>
-        public TextWriter StatusMessageWriter { get; set; }
-
-        /// <summary>
-        /// The <c>System.Text.Encoding</c> to use when reading in the zip archive. Be
-        /// careful specifying the encoding.  If the value you use here is not the same
-        /// as the Encoding used when the zip archive was created (possibly by a
-        /// different archiver) you will get unexpected results and possibly exceptions.
-        /// </summary>
-        ///
-        /// <seealso cref="ZipFile.ProvisionalAlternateEncoding"/>
-        ///
-        public System.Text.Encoding @Encoding { get; set; }
-    }
-
-
-    internal partial class ZipFile
-    {
-        /// <summary>
-        /// Reads a zip file archive and returns the instance.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// The stream is read using the default <c>System.Text.Encoding</c>, which is the
-        /// <c>IBM437</c> codepage.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.Exception">
-        /// Thrown if the <c>ZipFile</c> cannot be read. The implementation of this method
-        /// relies on <c>System.IO.File.OpenRead</c>, which can throw a variety of exceptions,
-        /// including specific exceptions if a file is not found, an unauthorized access
-        /// exception, exceptions for poorly formatted filenames, and so on.
-        /// </exception>
-        ///
-        /// <param name="fileName">
-        /// The name of the zip archive to open.  This can be a fully-qualified or relative
-        /// pathname.
-        /// </param>
-        ///
-        /// <seealso cref="ZipFile.Read(String, ReadOptions)"/>.
-        ///
-        /// <returns>The instance read from the zip archive.</returns>
-        ///
-        public static ZipFile Read(string fileName)
-        {
-            return ZipFile.Read(fileName, null, null, null);
-        }
-
-
-        /// <summary>
-        ///   Reads a zip file archive from the named filesystem file using the
-        ///   specified options.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This version of the <c>Read()</c> method allows the caller to pass
-        ///   in a <c>TextWriter</c> an <c>Encoding</c>, via an instance of the
-        ///   <c>ReadOptions</c> class.  The <c>ZipFile</c> is read in using the
-        ///   specified encoding for entries where UTF-8 encoding is not
-        ///   explicitly specified.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        /// <para>
-        ///   This example shows how to read a zip file using the Big-5 Chinese
-        ///   code page (950), and extract each entry in the zip file, while
-        ///   sending status messages out to the Console.
-        /// </para>
-        ///
-        /// <para>
-        ///   For this code to work as intended, the zipfile must have been
-        ///   created using the big5 code page (CP950). This is typical, for
-        ///   example, when using WinRar on a machine with CP950 set as the
-        ///   default code page.  In that case, the names of entries within the
-        ///   Zip archive will be stored in that code page, and reading the zip
-        ///   archive must be done using that code page.  If the application did
-        ///   not use the correct code page in ZipFile.Read(), then names of
-        ///   entries within the zip archive would not be correctly retrieved.
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// string zipToExtract = "MyArchive.zip";
-        /// string extractDirectory = "extract";
-        /// var options = new ReadOptions
-        /// {
-        ///   StatusMessageWriter = System.Console.Out,
-        ///   Encoding = System.Text.Encoding.GetEncoding(950)
-        /// };
-        /// using (ZipFile zip = ZipFile.Read(zipToExtract, options))
-        /// {
-        ///   foreach (ZipEntry e in zip)
-        ///   {
-        ///      e.Extract(extractDirectory);
-        ///   }
-        /// }
-        /// </code>
-        ///
-        ///
-        /// <code lang="VB">
-        /// Dim zipToExtract as String = "MyArchive.zip"
-        /// Dim extractDirectory as String = "extract"
-        /// Dim options as New ReadOptions
-        /// options.Encoding = System.Text.Encoding.GetEncoding(950)
-        /// options.StatusMessageWriter = System.Console.Out
-        /// Using zip As ZipFile = ZipFile.Read(zipToExtract, options)
-        ///     Dim e As ZipEntry
-        ///     For Each e In zip
-        ///      e.Extract(extractDirectory)
-        ///     Next
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        ///
-        /// <example>
-        ///
-        /// <para>
-        ///   This example shows how to read a zip file using the default
-        ///   code page, to remove entries that have a modified date before a given threshold,
-        ///   sending status messages out to a <c>StringWriter</c>.
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// var options = new ReadOptions
-        /// {
-        ///   StatusMessageWriter = new System.IO.StringWriter()
-        /// };
-        /// using (ZipFile zip =  ZipFile.Read("PackedDocuments.zip", options))
-        /// {
-        ///   var Threshold = new DateTime(2007,7,4);
-        ///   // We cannot remove the entry from the list, within the context of
-        ///   // an enumeration of said list.
-        ///   // So we add the doomed entry to a list to be removed later.
-        ///   // pass 1: mark the entries for removal
-        ///   var MarkedEntries = new System.Collections.Generic.List&lt;ZipEntry&gt;();
-        ///   foreach (ZipEntry e in zip)
-        ///   {
-        ///     if (e.LastModified &lt; Threshold)
-        ///       MarkedEntries.Add(e);
-        ///   }
-        ///   // pass 2: actually remove the entry.
-        ///   foreach (ZipEntry zombie in MarkedEntries)
-        ///      zip.RemoveEntry(zombie);
-        ///   zip.Comment = "This archive has been updated.";
-        ///   zip.Save();
-        /// }
-        /// // can now use contents of sw, eg store in an audit log
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim options as New ReadOptions
-        /// options.StatusMessageWriter = New System.IO.StringWriter
-        /// Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip", options)
-        ///     Dim Threshold As New DateTime(2007, 7, 4)
-        ///     ' We cannot remove the entry from the list, within the context of
-        ///     ' an enumeration of said list.
-        ///     ' So we add the doomed entry to a list to be removed later.
-        ///     ' pass 1: mark the entries for removal
-        ///     Dim MarkedEntries As New System.Collections.Generic.List(Of ZipEntry)
-        ///     Dim e As ZipEntry
-        ///     For Each e In zip
-        ///         If (e.LastModified &lt; Threshold) Then
-        ///             MarkedEntries.Add(e)
-        ///         End If
-        ///     Next
-        ///     ' pass 2: actually remove the entry.
-        ///     Dim zombie As ZipEntry
-        ///     For Each zombie In MarkedEntries
-        ///         zip.RemoveEntry(zombie)
-        ///     Next
-        ///     zip.Comment = "This archive has been updated."
-        ///     zip.Save
-        /// End Using
-        /// ' can now use contents of sw, eg store in an audit log
-        /// </code>
-        /// </example>
-        ///
-        /// <exception cref="System.Exception">
-        ///   Thrown if the zipfile cannot be read. The implementation of
-        ///   this method relies on <c>System.IO.File.OpenRead</c>, which
-        ///   can throw a variety of exceptions, including specific
-        ///   exceptions if a file is not found, an unauthorized access
-        ///   exception, exceptions for poorly formatted filenames, and so
-        ///   on.
-        /// </exception>
-        ///
-        /// <param name="fileName">
-        /// The name of the zip archive to open.
-        /// This can be a fully-qualified or relative pathname.
-        /// </param>
-        ///
-        /// <param name="options">
-        /// The set of options to use when reading the zip file.
-        /// </param>
-        ///
-        /// <returns>The ZipFile instance read from the zip archive.</returns>
-        ///
-        /// <seealso cref="ZipFile.Read(Stream, ReadOptions)"/>
-        ///
-        internal static ZipFile Read(string fileName,
-                                   ReadOptions options)
-        {
-            if (options == null)
-                throw new ArgumentNullException("options");
-            return Read(fileName,
-                        options.StatusMessageWriter,
-                        options.Encoding,
-                        options.ReadProgress);
-        }
-
-        /// <summary>
-        /// Reads a zip file archive using the specified text encoding,  the specified
-        /// TextWriter for status messages, and the specified ReadProgress event handler,
-        /// and returns the instance.
-        /// </summary>
-        ///
-        /// <param name="fileName">
-        /// The name of the zip archive to open.
-        /// This can be a fully-qualified or relative pathname.
-        /// </param>
-        ///
-        /// <param name="readProgress">
-        /// An event handler for Read operations.
-        /// </param>
-        ///
-        /// <param name="statusMessageWriter">
-        /// The <c>System.IO.TextWriter</c> to use for writing verbose status messages
-        /// during operations on the zip archive.  A console application may wish to
-        /// pass <c>System.Console.Out</c> to get messages on the Console. A graphical
-        /// or headless application may wish to capture the messages in a different
-        /// <c>TextWriter</c>, such as a <c>System.IO.StringWriter</c>.
-        /// </param>
-        ///
-        /// <param name="encoding">
-        /// The <c>System.Text.Encoding</c> to use when reading in the zip archive. Be
-        /// careful specifying the encoding.  If the value you use here is not the same
-        /// as the Encoding used when the zip archive was created (possibly by a
-        /// different archiver) you will get unexpected results and possibly exceptions.
-        /// </param>
-        ///
-        /// <returns>The instance read from the zip archive.</returns>
-        ///
-        private static ZipFile Read(string fileName,
-                                   TextWriter statusMessageWriter,
-                                   System.Text.Encoding encoding,
-                                   EventHandler<ReadProgressEventArgs> readProgress)
-        {
-            ZipFile zf = new ZipFile();
-            zf.AlternateEncoding = encoding ?? DefaultEncoding;
-            zf.AlternateEncodingUsage = ZipOption.Always;
-            zf._StatusMessageTextWriter = statusMessageWriter;
-            zf._name = fileName;
-            if (readProgress != null)
-                zf.ReadProgress = readProgress;
-
-            if (zf.Verbose) zf._StatusMessageTextWriter.WriteLine("reading from {0}...", fileName);
-
-            ReadIntoInstance(zf);
-            zf._fileAlreadyExists = true;
-
-            return zf;
-        }
-
-        /// <summary>
-        ///   Reads a zip archive from a stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When reading from a file, it's probably easier to just use
-        ///   <see cref="ZipFile.Read(String,
-        ///   ReadOptions)">ZipFile.Read(String, ReadOptions)</see>.  This
-        ///   overload is useful when when the zip archive content is
-        ///   available from an already-open stream. The stream must be
-        ///   open and readable and seekable when calling this method.  The
-        ///   stream is left open when the reading is completed.
-        /// </para>
-        ///
-        /// <para>
-        ///   Using this overload, the stream is read using the default
-        ///   <c>System.Text.Encoding</c>, which is the <c>IBM437</c>
-        ///   codepage. If you want to specify the encoding to use when
-        ///   reading the zipfile content, see
-        ///   <see cref="ZipFile.Read(Stream,
-        ///   ReadOptions)">ZipFile.Read(Stream, ReadOptions)</see>.  This
-        /// </para>
-        ///
-        /// <para>
-        ///   Reading of zip content begins at the current position in the
-        ///   stream.  This means if you have a stream that concatenates
-        ///   regular data and zip data, if you position the open, readable
-        ///   stream at the start of the zip data, you will be able to read
-        ///   the zip archive using this constructor, or any of the ZipFile
-        ///   constructors that accept a <see cref="System.IO.Stream" /> as
-        ///   input. Some examples of where this might be useful: the zip
-        ///   content is concatenated at the end of a regular EXE file, as
-        ///   some self-extracting archives do.  (Note: SFX files produced
-        ///   by DotNetZip do not work this way; they can be read as normal
-        ///   ZIP files). Another example might be a stream being read from
-        ///   a database, where the zip content is embedded within an
-        ///   aggregate stream of data.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example shows how to Read zip content from a stream, and
-        ///   extract one entry into a different stream. In this example,
-        ///   the filename "NameOfEntryInArchive.doc", refers only to the
-        ///   name of the entry within the zip archive.  A file by that
-        ///   name is not created in the filesystem.  The I/O is done
-        ///   strictly with the given streams.
-        /// </para>
-        ///
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(InputStream))
-        /// {
-        ///    zip.Extract("NameOfEntryInArchive.doc", OutputStream);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip as ZipFile = ZipFile.Read(InputStream)
-        ///    zip.Extract("NameOfEntryInArchive.doc", OutputStream)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="zipStream">the stream containing the zip data.</param>
-        ///
-        /// <returns>The ZipFile instance read from the stream</returns>
-        ///
-        public static ZipFile Read(Stream zipStream)
-        {
-            return Read(zipStream, null, null, null);
-        }
-
-        /// <summary>
-        ///   Reads a zip file archive from the given stream using the
-        ///   specified options.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When reading from a file, it's probably easier to just use
-        ///   <see cref="ZipFile.Read(String,
-        ///   ReadOptions)">ZipFile.Read(String, ReadOptions)</see>.  This
-        ///   overload is useful when when the zip archive content is
-        ///   available from an already-open stream. The stream must be
-        ///   open and readable and seekable when calling this method.  The
-        ///   stream is left open when the reading is completed.
-        /// </para>
-        ///
-        /// <para>
-        ///   Reading of zip content begins at the current position in the
-        ///   stream.  This means if you have a stream that concatenates
-        ///   regular data and zip data, if you position the open, readable
-        ///   stream at the start of the zip data, you will be able to read
-        ///   the zip archive using this constructor, or any of the ZipFile
-        ///   constructors that accept a <see cref="System.IO.Stream" /> as
-        ///   input. Some examples of where this might be useful: the zip
-        ///   content is concatenated at the end of a regular EXE file, as
-        ///   some self-extracting archives do.  (Note: SFX files produced
-        ///   by DotNetZip do not work this way; they can be read as normal
-        ///   ZIP files). Another example might be a stream being read from
-        ///   a database, where the zip content is embedded within an
-        ///   aggregate stream of data.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="zipStream">the stream containing the zip data.</param>
-        ///
-        /// <param name="options">
-        ///   The set of options to use when reading the zip file.
-        /// </param>
-        ///
-        /// <exception cref="System.Exception">
-        ///   Thrown if the zip archive cannot be read.
-        /// </exception>
-        ///
-        /// <returns>The ZipFile instance read from the stream.</returns>
-        ///
-        /// <seealso cref="ZipFile.Read(String, ReadOptions)"/>
-        ///
-        internal static ZipFile Read(Stream zipStream, ReadOptions options)
-        {
-            if (options == null)
-                throw new ArgumentNullException("options");
-
-            return Read(zipStream,
-                        options.StatusMessageWriter,
-                        options.Encoding,
-                        options.ReadProgress);
-        }
-
-
-
-        /// <summary>
-        /// Reads a zip archive from a stream, using the specified text Encoding, the
-        /// specified TextWriter for status messages,
-        /// and the specified ReadProgress event handler.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// Reading of zip content begins at the current position in the stream.  This
-        /// means if you have a stream that concatenates regular data and zip data, if
-        /// you position the open, readable stream at the start of the zip data, you
-        /// will be able to read the zip archive using this constructor, or any of the
-        /// ZipFile constructors that accept a <see cref="System.IO.Stream" /> as
-        /// input. Some examples of where this might be useful: the zip content is
-        /// concatenated at the end of a regular EXE file, as some self-extracting
-        /// archives do.  (Note: SFX files produced by DotNetZip do not work this
-        /// way). Another example might be a stream being read from a database, where
-        /// the zip content is embedded within an aggregate stream of data.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="zipStream">the stream containing the zip data.</param>
-        ///
-        /// <param name="statusMessageWriter">
-        /// The <c>System.IO.TextWriter</c> to which verbose status messages are written
-        /// during operations on the <c>ZipFile</c>.  For example, in a console
-        /// application, System.Console.Out works, and will get a message for each entry
-        /// added to the ZipFile.  If the TextWriter is <c>null</c>, no verbose messages
-        /// are written.
-        /// </param>
-        ///
-        /// <param name="encoding">
-        /// The text encoding to use when reading entries that do not have the UTF-8
-        /// encoding bit set.  Be careful specifying the encoding.  If the value you use
-        /// here is not the same as the Encoding used when the zip archive was created
-        /// (possibly by a different archiver) you will get unexpected results and
-        /// possibly exceptions.  See the <see cref="ProvisionalAlternateEncoding"/>
-        /// property for more information.
-        /// </param>
-        ///
-        /// <param name="readProgress">
-        /// An event handler for Read operations.
-        /// </param>
-        ///
-        /// <returns>an instance of ZipFile</returns>
-        private static ZipFile Read(Stream zipStream,
-                                   TextWriter statusMessageWriter,
-                                   System.Text.Encoding encoding,
-                                   EventHandler<ReadProgressEventArgs> readProgress)
-        {
-            if (zipStream == null)
-                throw new ArgumentNullException("zipStream");
-
-            ZipFile zf = new ZipFile();
-            zf._StatusMessageTextWriter = statusMessageWriter;
-            zf._alternateEncoding = encoding ?? ZipFile.DefaultEncoding;
-            zf._alternateEncodingUsage = ZipOption.Always;
-            if (readProgress != null)
-                zf.ReadProgress += readProgress;
-            zf._readstream = (zipStream.Position == 0L)
-                ? zipStream
-                : new OffsetStream(zipStream);
-            zf._ReadStreamIsOurs = false;
-            if (zf.Verbose) zf._StatusMessageTextWriter.WriteLine("reading from stream...");
-
-            ReadIntoInstance(zf);
-            return zf;
-        }
-
-
-
-        private static void ReadIntoInstance(ZipFile zf)
-        {
-            Stream s = zf.ReadStream;
-            try
-            {
-                zf._readName = zf._name; // workitem 13915
-                if (!s.CanSeek)
-                {
-                    ReadIntoInstance_Orig(zf);
-                    return;
-                }
-
-                zf.OnReadStarted();
-
-                // change for workitem 8098
-                //zf._originPosition = s.Position;
-
-                // Try reading the central directory, rather than scanning the file.
-
-                uint datum = ReadFirstFourBytes(s);
-
-                if (datum == ZipConstants.EndOfCentralDirectorySignature)
-                    return;
-
-
-                // start at the end of the file...
-                // seek backwards a bit, then look for the EoCD signature.
-                int nTries = 0;
-                bool success = false;
-
-                // The size of the end-of-central-directory-footer plus 2 bytes is 18.
-                // This implies an archive comment length of 0.  We'll add a margin of
-                // safety and start "in front" of that, when looking for the
-                // EndOfCentralDirectorySignature
-                long posn = s.Length - 64;
-                long maxSeekback = Math.Max(s.Length - 0x4000, 10);
-                do
-                {
-                    if (posn < 0) posn = 0;  // BOF
-                    s.Seek(posn, SeekOrigin.Begin);
-                    long bytesRead = SharedUtilities.FindSignature(s, (int)ZipConstants.EndOfCentralDirectorySignature);
-                    if (bytesRead != -1)
-                        success = true;
-                    else
-                    {
-                        if (posn==0) break; // started at the BOF and found nothing
-                        nTries++;
-                        // Weird: with NETCF, negative offsets from SeekOrigin.End DO
-                        // NOT WORK. So rather than seek a negative offset, we seek
-                        // from SeekOrigin.Begin using a smaller number.
-                        posn -= (32 * (nTries + 1) * nTries);
-                    }
-                }
-                while (!success && posn > maxSeekback);
-
-                if (success)
-                {
-                    // workitem 8299
-                    zf._locEndOfCDS = s.Position - 4;
-
-                    byte[] block = new byte[16];
-                    s.Read(block, 0, block.Length);
-
-                    zf._diskNumberWithCd = BitConverter.ToUInt16(block, 2);
-
-                    if (zf._diskNumberWithCd == 0xFFFF)
-                        throw new ZipException("Spanned archives with more than 65534 segments are not supported at this time.");
-
-                    zf._diskNumberWithCd++; // I think the number in the file differs from reality by 1
-
-                    int i = 12;
-
-                    uint offset32 = (uint) BitConverter.ToUInt32(block, i);
-                    if (offset32 == 0xFFFFFFFF)
-                    {
-                        Zip64SeekToCentralDirectory(zf);
-                    }
-                    else
-                    {
-                        zf._OffsetOfCentralDirectory = offset32;
-                        // change for workitem 8098
-                        s.Seek(offset32, SeekOrigin.Begin);
-                    }
-
-                    ReadCentralDirectory(zf);
-                }
-                else
-                {
-                    // Could not find the central directory.
-                    // Fallback to the old method.
-                    // workitem 8098: ok
-                    //s.Seek(zf._originPosition, SeekOrigin.Begin);
-                    s.Seek(0L, SeekOrigin.Begin);
-                    ReadIntoInstance_Orig(zf);
-                }
-            }
-            catch (Exception ex1)
-            {
-                if (zf._ReadStreamIsOurs && zf._readstream != null)
-                {
-                    try
-                    {
-#if NETCF
-                        zf._readstream.Close();
-#else
-                        zf._readstream.Dispose();
-#endif
-                        zf._readstream = null;
-                    }
-                    finally { }
-                }
-
-                throw new ZipException("Cannot read that as a ZipFile", ex1);
-            }
-
-            // the instance has been read in
-            zf._contentsChanged = false;
-        }
-
-
-
-        private static void Zip64SeekToCentralDirectory(ZipFile zf)
-        {
-            Stream s = zf.ReadStream;
-            byte[] block = new byte[16];
-
-            // seek back to find the ZIP64 EoCD.
-            // I think this might not work for .NET CF ?
-            s.Seek(-40, SeekOrigin.Current);
-            s.Read(block, 0, 16);
-
-            Int64 offset64 = BitConverter.ToInt64(block, 8);
-            zf._OffsetOfCentralDirectory = 0xFFFFFFFF;
-            zf._OffsetOfCentralDirectory64 = offset64;
-            // change for workitem 8098
-            s.Seek(offset64, SeekOrigin.Begin);
-            //zf.SeekFromOrigin(Offset64);
-
-            uint datum = (uint)Ionic.Zip.SharedUtilities.ReadInt(s);
-            if (datum != ZipConstants.Zip64EndOfCentralDirectoryRecordSignature)
-                throw new BadReadException(String.Format("  Bad signature (0x{0:X8}) looking for ZIP64 EoCD Record at position 0x{1:X8}", datum, s.Position));
-
-            s.Read(block, 0, 8);
-            Int64 Size = BitConverter.ToInt64(block, 0);
-
-            block = new byte[Size];
-            s.Read(block, 0, block.Length);
-
-            offset64 = BitConverter.ToInt64(block, 36);
-            // change for workitem 8098
-            s.Seek(offset64, SeekOrigin.Begin);
-            //zf.SeekFromOrigin(Offset64);
-        }
-
-
-        private static uint ReadFirstFourBytes(Stream s)
-        {
-            uint datum = (uint)Ionic.Zip.SharedUtilities.ReadInt(s);
-            return datum;
-        }
-
-
-
-        private static void ReadCentralDirectory(ZipFile zf)
-        {
-            // We must have the central directory footer record, in order to properly
-            // read zip dir entries from the central directory.  This because the logic
-            // knows when to open a spanned file when the volume number for the central
-            // directory differs from the volume number for the zip entry.  The
-            // _diskNumberWithCd was set when originally finding the offset for the
-            // start of the Central Directory.
-
-            // workitem 9214
-            bool inputUsesZip64 = false;
-            ZipEntry de;
-            // in lieu of hashset, use a dictionary
-            var previouslySeen = new Dictionary<String,object>();
-            while ((de = ZipEntry.ReadDirEntry(zf, previouslySeen)) != null)
-            {
-                de.ResetDirEntry();
-                zf.OnReadEntry(true, null);
-
-                if (zf.Verbose)
-                    zf.StatusMessageTextWriter.WriteLine("entry {0}", de.FileName);
-
-                zf._entries.Add(de.FileName,de);
-
-                // workitem 9214
-                if (de._InputUsesZip64) inputUsesZip64 = true;
-                previouslySeen.Add(de.FileName, null); // to prevent dupes
-            }
-
-            // workitem 9214; auto-set the zip64 flag
-            if (inputUsesZip64) zf.UseZip64WhenSaving = Zip64Option.Always;
-
-            // workitem 8299
-            if (zf._locEndOfCDS > 0)
-                zf.ReadStream.Seek(zf._locEndOfCDS, SeekOrigin.Begin);
-
-            ReadCentralDirectoryFooter(zf);
-
-            if (zf.Verbose && !String.IsNullOrEmpty(zf.Comment))
-                zf.StatusMessageTextWriter.WriteLine("Zip file Comment: {0}", zf.Comment);
-
-            // We keep the read stream open after reading.
-
-            if (zf.Verbose)
-                zf.StatusMessageTextWriter.WriteLine("read in {0} entries.", zf._entries.Count);
-
-            zf.OnReadCompleted();
-        }
-
-
-
-
-        // build the TOC by reading each entry in the file.
-        private static void ReadIntoInstance_Orig(ZipFile zf)
-        {
-            zf.OnReadStarted();
-            //zf._entries = new System.Collections.Generic.List<ZipEntry>();
-            zf._entries = new System.Collections.Generic.Dictionary<String,ZipEntry>();
-
-            ZipEntry e;
-            if (zf.Verbose)
-                if (zf.Name == null)
-                    zf.StatusMessageTextWriter.WriteLine("Reading zip from stream...");
-                else
-                    zf.StatusMessageTextWriter.WriteLine("Reading zip {0}...", zf.Name);
-
-            // work item 6647:  PK00 (packed to removable disk)
-            bool firstEntry = true;
-            ZipContainer zc = new ZipContainer(zf);
-            while ((e = ZipEntry.ReadEntry(zc, firstEntry)) != null)
-            {
-                if (zf.Verbose)
-                    zf.StatusMessageTextWriter.WriteLine("  {0}", e.FileName);
-
-                zf._entries.Add(e.FileName,e);
-                firstEntry = false;
-            }
-
-            // read the zipfile's central directory structure here.
-            // workitem 9912
-            // But, because it may be corrupted, ignore errors.
-            try
-            {
-                ZipEntry de;
-                // in lieu of hashset, use a dictionary
-                var previouslySeen = new Dictionary<String,Object>();
-                while ((de = ZipEntry.ReadDirEntry(zf, previouslySeen)) != null)
-                {
-                    // Housekeeping: Since ZipFile exposes ZipEntry elements in the enumerator,
-                    // we need to copy the comment that we grab from the ZipDirEntry
-                    // into the ZipEntry, so the application can access the comment.
-                    // Also since ZipEntry is used to Write zip files, we need to copy the
-                    // file attributes to the ZipEntry as appropriate.
-                    ZipEntry e1 = zf._entries[de.FileName];
-                    if (e1 != null)
-                    {
-                        e1._Comment = de.Comment;
-                        if (de.IsDirectory) e1.MarkAsDirectory();
-                    }
-                    previouslySeen.Add(de.FileName,null); // to prevent dupes
-                }
-
-                // workitem 8299
-                if (zf._locEndOfCDS > 0)
-                    zf.ReadStream.Seek(zf._locEndOfCDS, SeekOrigin.Begin);
-
-                ReadCentralDirectoryFooter(zf);
-
-                if (zf.Verbose && !String.IsNullOrEmpty(zf.Comment))
-                    zf.StatusMessageTextWriter.WriteLine("Zip file Comment: {0}", zf.Comment);
-            }
-            catch (ZipException) { }
-            catch (IOException) { }
-
-            zf.OnReadCompleted();
-        }
-
-
-
-
-        private static void ReadCentralDirectoryFooter(ZipFile zf)
-        {
-            Stream s = zf.ReadStream;
-            int signature = Ionic.Zip.SharedUtilities.ReadSignature(s);
-
-            byte[] block = null;
-            int j = 0;
-            if (signature == ZipConstants.Zip64EndOfCentralDirectoryRecordSignature)
-            {
-                // We have a ZIP64 EOCD
-                // This data block is 4 bytes sig, 8 bytes size, 44 bytes fixed data,
-                // followed by a variable-sized extension block.  We have read the sig already.
-                // 8 - datasize (64 bits)
-                // 2 - version made by
-                // 2 - version needed to extract
-                // 4 - number of this disk
-                // 4 - number of the disk with the start of the CD
-                // 8 - total number of entries in the CD on this disk
-                // 8 - total number of entries in the CD
-                // 8 - size of the CD
-                // 8 - offset of the CD
-                // -----------------------
-                // 52 bytes
-
-                block = new byte[8 + 44];
-                s.Read(block, 0, block.Length);
-
-                Int64 DataSize = BitConverter.ToInt64(block, 0);  // == 44 + the variable length
-
-                if (DataSize < 44)
-                    throw new ZipException("Bad size in the ZIP64 Central Directory.");
-
-                zf._versionMadeBy = BitConverter.ToUInt16(block, j);
-                j += 2;
-                zf._versionNeededToExtract = BitConverter.ToUInt16(block, j);
-                j += 2;
-                zf._diskNumberWithCd = BitConverter.ToUInt32(block, j);
-                j += 2;
-
-                //zf._diskNumberWithCd++; // hack!!
-
-                // read the extended block
-                block = new byte[DataSize - 44];
-                s.Read(block, 0, block.Length);
-                // discard the result
-
-                signature = Ionic.Zip.SharedUtilities.ReadSignature(s);
-                if (signature != ZipConstants.Zip64EndOfCentralDirectoryLocatorSignature)
-                    throw new ZipException("Inconsistent metadata in the ZIP64 Central Directory.");
-
-                block = new byte[16];
-                s.Read(block, 0, block.Length);
-                // discard the result
-
-                signature = Ionic.Zip.SharedUtilities.ReadSignature(s);
-            }
-
-            // Throw if this is not a signature for "end of central directory record"
-            // This is a sanity check.
-            if (signature != ZipConstants.EndOfCentralDirectorySignature)
-            {
-                s.Seek(-4, SeekOrigin.Current);
-                throw new BadReadException(String.Format("Bad signature ({0:X8}) at position 0x{1:X8}",
-                                                         signature, s.Position));
-            }
-
-            // read the End-of-Central-Directory-Record
-            block = new byte[16];
-            zf.ReadStream.Read(block, 0, block.Length);
-
-            // off sz  data
-            // -------------------------------------------------------
-            //  0   4  end of central dir signature (0x06054b50)
-            //  4   2  number of this disk
-            //  6   2  number of the disk with start of the central directory
-            //  8   2  total number of entries in the  central directory on this disk
-            // 10   2  total number of entries in  the central directory
-            // 12   4  size of the central directory
-            // 16   4  offset of start of central directory with respect to the starting disk number
-            // 20   2  ZIP file comment length
-            // 22  ??  ZIP file comment
-
-            if (zf._diskNumberWithCd == 0)
-            {
-                zf._diskNumberWithCd = BitConverter.ToUInt16(block, 2);
-                //zf._diskNumberWithCd++; // hack!!
-            }
-
-            // read the comment here
-            ReadZipFileComment(zf);
-        }
-
-
-
-        private static void ReadZipFileComment(ZipFile zf)
-        {
-            // read the comment here
-            byte[] block = new byte[2];
-            zf.ReadStream.Read(block, 0, block.Length);
-
-            Int16 commentLength = (short)(block[0] + block[1] * 256);
-            if (commentLength > 0)
-            {
-                block = new byte[commentLength];
-                zf.ReadStream.Read(block, 0, block.Length);
-
-                // workitem 10392 - prefer ProvisionalAlternateEncoding,
-                // first.  The fix for workitem 6513 tried to use UTF8
-                // only as necessary, but that is impossible to test
-                // for, in this direction. There's no way to know what
-                // characters the already-encoded bytes refer
-                // to. Therefore, must do what the user tells us.
-
-                string s1 = zf.AlternateEncoding.GetString(block, 0, block.Length);
-                zf.Comment = s1;
-            }
-        }
-
-
-        // private static bool BlocksAreEqual(byte[] a, byte[] b)
-        // {
-        //     if (a.Length != b.Length) return false;
-        //     for (int i = 0; i < a.Length; i++)
-        //     {
-        //         if (a[i] != b[i]) return false;
-        //     }
-        //     return true;
-        // }
-
-
-
-        /// <summary>
-        /// Checks the given file to see if it appears to be a valid zip file.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   Calling this method is equivalent to calling <see cref="IsZipFile(string,
-        ///   bool)"/> with the testExtract parameter set to false.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="fileName">The file to check.</param>
-        /// <returns>true if the file appears to be a zip file.</returns>
-        public static bool IsZipFile(string fileName)
-        {
-            return IsZipFile(fileName, false);
-        }
-
-
-        /// <summary>
-        /// Checks a file to see if it is a valid zip file.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method opens the specified zip file, reads in the zip archive,
-        ///   verifying the ZIP metadata as it reads.
-        /// </para>
-        ///
-        /// <para>
-        ///   If everything succeeds, then the method returns true.  If anything fails -
-        ///   for example if an incorrect signature or CRC is found, indicating a
-        ///   corrupt file, the the method returns false.  This method also returns
-        ///   false for a file that does not exist.
-        /// </para>
-        ///
-        /// <para>
-        ///   If <paramref name="testExtract"/> is true, as part of its check, this
-        ///   method reads in the content for each entry, expands it, and checks CRCs.
-        ///   This provides an additional check beyond verifying the zip header and
-        ///   directory data.
-        /// </para>
-        ///
-        /// <para>
-        ///   If <paramref name="testExtract"/> is true, and if any of the zip entries
-        ///   are protected with a password, this method will return false.  If you want
-        ///   to verify a <c>ZipFile</c> that has entries which are protected with a
-        ///   password, you will need to do that manually.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="fileName">The zip file to check.</param>
-        /// <param name="testExtract">true if the caller wants to extract each entry.</param>
-        /// <returns>true if the file contains a valid zip file.</returns>
-        public static bool IsZipFile(string fileName, bool testExtract)
-        {
-            bool result = false;
-            try
-            {
-                if (!File.Exists(fileName)) return false;
-
-                using (var s = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
-                {
-                    result = IsZipFile(s, testExtract);
-                }
-            }
-            catch (IOException) { }
-            catch (ZipException) { }
-            return result;
-        }
-
-
-        /// <summary>
-        /// Checks a stream to see if it contains a valid zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// This method reads the zip archive contained in the specified stream, verifying
-        /// the ZIP metadata as it reads.  If testExtract is true, this method also extracts
-        /// each entry in the archive, dumping all the bits into <see cref="Stream.Null"/>.
-        /// </para>
-        ///
-        /// <para>
-        /// If everything succeeds, then the method returns true.  If anything fails -
-        /// for example if an incorrect signature or CRC is found, indicating a corrupt
-        /// file, the the method returns false.  This method also returns false for a
-        /// file that does not exist.
-        /// </para>
-        ///
-        /// <para>
-        /// If <c>testExtract</c> is true, this method reads in the content for each
-        /// entry, expands it, and checks CRCs.  This provides an additional check
-        /// beyond verifying the zip header data.
-        /// </para>
-        ///
-        /// <para>
-        /// If <c>testExtract</c> is true, and if any of the zip entries are protected
-        /// with a password, this method will return false.  If you want to verify a
-        /// ZipFile that has entries which are protected with a password, you will need
-        /// to do that manually.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="IsZipFile(string, bool)"/>
-        ///
-        /// <param name="stream">The stream to check.</param>
-        /// <param name="testExtract">true if the caller wants to extract each entry.</param>
-        /// <returns>true if the stream contains a valid zip archive.</returns>
-        public static bool IsZipFile(Stream stream, bool testExtract)
-        {
-            if (stream == null)
-                throw new ArgumentNullException("stream");
-
-            bool result = false;
-            try
-            {
-                if (!stream.CanRead) return false;
-
-                var bitBucket = Stream.Null;
-
-                using (ZipFile zip1 = ZipFile.Read(stream, null, null, null))
-                {
-                    if (testExtract)
-                    {
-                        foreach (var e in zip1)
-                        {
-                            if (!e.IsDirectory)
-                            {
-                                e.Extract(bitBucket);
-                            }
-                        }
-                    }
-                }
-                result = true;
-            }
-            catch (IOException) { }
-            catch (ZipException) { }
-            return result;
-        }
-
-
-
-
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.Save.cs b/EPPlus/Packaging/DotNetZip/ZipFile.Save.cs
deleted file mode 100644
index b66c5c9..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.Save.cs
+++ /dev/null
@@ -1,964 +0,0 @@
-// ZipFile.Save.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-August-05 13:31:23>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for Save operations on zip files.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    internal partial class ZipFile
-    {
-
-        /// <summary>
-        ///   Delete file with retry on UnauthorizedAccessException.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     When calling File.Delete() on a file that has been "recently"
-        ///     created, the call sometimes fails with
-        ///     UnauthorizedAccessException. This method simply retries the Delete 3
-        ///     times with a sleep between tries.
-        ///   </para>
-        /// </remarks>
-        ///
-        /// <param name='filename'>the name of the file to be deleted</param>
-        private void DeleteFileWithRetry(string filename)
-        {
-            bool done = false;
-            int nRetries = 3;
-            for (int i=0; i < nRetries && !done; i++)
-            {
-                try
-                {
-                    File.Delete(filename);
-                    done = true;
-                }
-                catch (System.UnauthorizedAccessException)
-                {
-                    Console.WriteLine("************************************************** Retry delete.");
-                    System.Threading.Thread.Sleep(200+i*200);
-                }
-            }
-        }
-
-
-        /// <summary>
-        ///   Saves the Zip archive to a file, specified by the Name property of the
-        ///   <c>ZipFile</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The <c>ZipFile</c> instance is written to storage, typically a zip file
-        ///   in a filesystem, only when the caller calls <c>Save</c>.  In the typical
-        ///   case, the Save operation writes the zip content to a temporary file, and
-        ///   then renames the temporary file to the desired name. If necessary, this
-        ///   method will delete a pre-existing file before the rename.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <see cref="ZipFile.Name"/> property is specified either explicitly,
-        ///   or implicitly using one of the parameterized ZipFile constructors.  For
-        ///   COM Automation clients, the <c>Name</c> property must be set explicitly,
-        ///   because COM Automation clients cannot call parameterized constructors.
-        /// </para>
-        ///
-        /// <para>
-        ///   When using a filesystem file for the Zip output, it is possible to call
-        ///   <c>Save</c> multiple times on the <c>ZipFile</c> instance. With each
-        ///   call the zip content is re-written to the same output file.
-        /// </para>
-        ///
-        /// <para>
-        ///   Data for entries that have been added to the <c>ZipFile</c> instance is
-        ///   written to the output when the <c>Save</c> method is called. This means
-        ///   that the input streams for those entries must be available at the time
-        ///   the application calls <c>Save</c>.  If, for example, the application
-        ///   adds entries with <c>AddEntry</c> using a dynamically-allocated
-        ///   <c>MemoryStream</c>, the memory stream must not have been disposed
-        ///   before the call to <c>Save</c>. See the <see
-        ///   cref="ZipEntry.InputStream"/> property for more discussion of the
-        ///   availability requirements of the input stream for an entry, and an
-        ///   approach for providing just-in-time stream lifecycle management.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.AddEntry(String, System.IO.Stream)"/>
-        ///
-        /// <exception cref="Ionic.Zip.BadStateException">
-        ///   Thrown if you haven't specified a location or stream for saving the zip,
-        ///   either in the constructor or by setting the Name property, or if you try
-        ///   to save a regular zip archive to a filename with a .exe extension.
-        /// </exception>
-        ///
-        /// <exception cref="System.OverflowException">
-        ///   Thrown if <see cref="MaxOutputSegmentSize"/> is non-zero, and the number
-        ///   of segments that would be generated for the spanned zip file during the
-        ///   save operation exceeds 99.  If this happens, you need to increase the
-        ///   segment size.
-        /// </exception>
-        ///
-        public void Save()
-        {
-            try
-            {
-                bool thisSaveUsedZip64 = false;
-                _saveOperationCanceled = false;
-                _numberOfSegmentsForMostRecentSave = 0;
-                OnSaveStarted();
-
-                if (WriteStream == null)
-                    throw new BadStateException("You haven't specified where to save the zip.");
-
-                if (_name != null && _name.EndsWith(".exe") && !_SavingSfx)
-                    throw new BadStateException("You specified an EXE for a plain zip file.");
-
-                // check if modified, before saving.
-                if (!_contentsChanged)
-                {
-                    OnSaveCompleted();
-                    if (Verbose) StatusMessageTextWriter.WriteLine("No save is necessary....");
-                    return;
-                }
-
-                Reset(true);
-
-                if (Verbose) StatusMessageTextWriter.WriteLine("saving....");
-
-                // validate the number of entries
-                if (_entries.Count >= 0xFFFF && _zip64 == Zip64Option.Never)
-                    throw new ZipException("The number of entries is 65535 or greater. Consider setting the UseZip64WhenSaving property on the ZipFile instance.");
-
-
-                // write an entry in the zip for each file
-                int n = 0;
-                // workitem 9831
-                ICollection<ZipEntry> c = (SortEntriesBeforeSaving) ? EntriesSorted : Entries;
-                foreach (ZipEntry e in c) // _entries.Values
-                {
-                    OnSaveEntry(n, e, true);
-                    e.Write(WriteStream);
-                    if (_saveOperationCanceled)
-                        break;
-
-                    n++;
-                    OnSaveEntry(n, e, false);
-                    if (_saveOperationCanceled)
-                        break;
-
-                    // Some entries can be skipped during the save.
-                    if (e.IncludedInMostRecentSave)
-                        thisSaveUsedZip64 |= e.OutputUsedZip64.Value;
-                }
-
-
-
-                if (_saveOperationCanceled)
-                    return;
-
-                var zss = WriteStream as ZipSegmentedStream;
-
-                _numberOfSegmentsForMostRecentSave = (zss!=null)
-                    ? zss.CurrentSegment
-                    : 1;
-
-                bool directoryNeededZip64 =
-                    ZipOutput.WriteCentralDirectoryStructure
-                    (WriteStream,
-                     c,
-                     _numberOfSegmentsForMostRecentSave,
-                     _zip64,
-                     Comment,
-                     new ZipContainer(this));
-
-                OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive);
-
-                _hasBeenSaved = true;
-                _contentsChanged = false;
-
-                thisSaveUsedZip64 |= directoryNeededZip64;
-                _OutputUsesZip64 = new Nullable<bool>(thisSaveUsedZip64);
-
-
-                // do the rename as necessary
-                if (_name != null &&
-                    (_temporaryFileName!=null || zss != null))
-                {
-                    // _temporaryFileName may remain null if we are writing to a stream.
-                    // only close the stream if there is a file behind it.
-#if NETCF
-                    WriteStream.Close();
-#else
-                    WriteStream.Dispose();
-#endif
-                    if (_saveOperationCanceled)
-                        return;
-
-                    if (_fileAlreadyExists && this._readstream != null)
-                    {
-                        // This means we opened and read a zip file.
-                        // If we are now saving to the same file, we need to close the
-                        // orig file, first.
-                        this._readstream.Close();
-                        this._readstream = null;
-                        // the archiveStream for each entry needs to be null
-                        foreach (var e in c)
-                        {
-                            var zss1 = e._archiveStream as ZipSegmentedStream;
-                            if (zss1 != null)
-#if NETCF
-                                zss1.Close();
-#else
-                                zss1.Dispose();
-#endif
-                            e._archiveStream = null;
-                        }
-                    }
-
-                    string tmpName = null;
-                    if (File.Exists(_name))
-                    {
-                        // the steps:
-                        //
-                        // 1. Delete tmpName
-                        // 2. move existing zip to tmpName
-                        // 3. rename (File.Move) working file to name of existing zip
-                        // 4. delete tmpName
-                        //
-                        // This series of steps avoids the exception,
-                        // System.IO.IOException:
-                        //   "Cannot create a file when that file already exists."
-                        //
-                        // Cannot just call File.Replace() here because
-                        // there is a possibility that the TEMP volume is different
-                        // that the volume for the final file (c:\ vs d:\).
-                        // So we need to do a Delete+Move pair.
-                        //
-                        // But, when doing the delete, Windows allows a process to
-                        // delete the file, even though it is held open by, say, a
-                        // virus scanner. It gets internally marked as "delete
-                        // pending". The file does not actually get removed from the
-                        // file system, it is still there after the File.Delete
-                        // call.
-                        //
-                        // Therefore, we need to move the existing zip, which may be
-                        // held open, to some other name. Then rename our working
-                        // file to the desired name, then delete (possibly delete
-                        // pending) the "other name".
-                        //
-                        // Ideally this would be transactional. It's possible that the
-                        // delete succeeds and the move fails. Lacking transactions, if
-                        // this kind of failure happens, we're hosed, and this logic will
-                        // throw on the next File.Move().
-                        //
-                        //File.Delete(_name);
-                        // workitem 10447
-#if NETCF || SILVERLIGHT
-                        tmpName = _name + "." + SharedUtilities.GenerateRandomStringImpl(8,0) + ".tmp";
-#else
-                        tmpName = _name + "." + Path.GetRandomFileName();
-#endif
-                        if (File.Exists(tmpName))
-                            DeleteFileWithRetry(tmpName);
-                        File.Move(_name, tmpName);
-                    }
-
-                    OnSaveEvent(ZipProgressEventType.Saving_BeforeRenameTempArchive);
-                    File.Move((zss != null) ? zss.CurrentTempName : _temporaryFileName,
-                              _name);
-
-                    OnSaveEvent(ZipProgressEventType.Saving_AfterRenameTempArchive);
-
-                    if (tmpName != null)
-                    {
-                        try
-                        {
-                            // not critical
-                            if (File.Exists(tmpName))
-                                File.Delete(tmpName);
-                        }
-                        catch
-                        {
-                            // don't care about exceptions here.
-                        }
-
-                    }
-                    _fileAlreadyExists = true;
-                }
-
-                NotifyEntriesSaveComplete(c);
-                OnSaveCompleted();
-                _JustSaved = true;
-            }
-
-            // workitem 5043
-            finally
-            {
-                CleanupAfterSaveOperation();
-            }
-
-            return;
-        }
-
-
-
-        private static void NotifyEntriesSaveComplete(ICollection<ZipEntry> c)
-        {
-            foreach (ZipEntry e in  c)
-            {
-                e.NotifySaveComplete();
-            }
-        }
-
-
-        private void RemoveTempFile()
-        {
-            try
-            {
-                if (File.Exists(_temporaryFileName))
-                {
-                    File.Delete(_temporaryFileName);
-                }
-            }
-            catch (IOException ex1)
-            {
-                if (Verbose)
-                    StatusMessageTextWriter.WriteLine("ZipFile::Save: could not delete temp file: {0}.", ex1.Message);
-            }
-        }
-
-
-        private void CleanupAfterSaveOperation()
-        {
-            if (_name != null)
-            {
-                // close the stream if there is a file behind it.
-                if (_writestream != null)
-                {
-                    try
-                    {
-                        // workitem 7704
-#if NETCF
-                        _writestream.Close();
-#else
-                        _writestream.Dispose();
-#endif
-                    }
-                    catch (System.IO.IOException) { }
-                }
-                _writestream = null;
-
-                if (_temporaryFileName != null)
-                {
-                    RemoveTempFile();
-                    _temporaryFileName = null;
-                }
-            }
-        }
-
-
-        /// <summary>
-        /// Save the file to a new zipfile, with the given name.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// This method allows the application to explicitly specify the name of the zip
-        /// file when saving. Use this when creating a new zip file, or when
-        /// updating a zip archive.
-        /// </para>
-        ///
-        /// <para>
-        /// An application can also save a zip archive in several places by calling this
-        /// method multiple times in succession, with different filenames.
-        /// </para>
-        ///
-        /// <para>
-        /// The <c>ZipFile</c> instance is written to storage, typically a zip file in a
-        /// filesystem, only when the caller calls <c>Save</c>.  The Save operation writes
-        /// the zip content to a temporary file, and then renames the temporary file
-        /// to the desired name. If necessary, this method will delete a pre-existing file
-        /// before the rename.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="System.ArgumentException">
-        /// Thrown if you specify a directory for the filename.
-        /// </exception>
-        ///
-        /// <param name="fileName">
-        /// The name of the zip archive to save to. Existing files will
-        /// be overwritten with great prejudice.
-        /// </param>
-        ///
-        /// <example>
-        /// This example shows how to create and Save a zip file.
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///   zip.AddDirectory(@"c:\reports\January");
-        ///   zip.Save("January.zip");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile()
-        ///   zip.AddDirectory("c:\reports\January")
-        ///   zip.Save("January.zip")
-        /// End Using
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <example>
-        /// This example shows how to update a zip file.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read("ExistingArchive.zip"))
-        /// {
-        ///   zip.AddFile("NewData.csv");
-        ///   zip.Save("UpdatedArchive.zip");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read("ExistingArchive.zip")
-        ///   zip.AddFile("NewData.csv")
-        ///   zip.Save("UpdatedArchive.zip")
-        /// End Using
-        /// </code>
-        ///
-        /// </example>
-        public void Save(String fileName)
-        {
-            // Check for the case where we are re-saving a zip archive
-            // that was originally instantiated with a stream.  In that case,
-            // the _name will be null. If so, we set _writestream to null,
-            // which insures that we'll cons up a new WriteStream (with a filesystem
-            // file backing it) in the Save() method.
-            if (_name == null)
-                _writestream = null;
-
-            else _readName = _name; // workitem 13915
-
-            _name = fileName;
-            if (Directory.Exists(_name))
-                throw new ZipException("Bad Directory", new System.ArgumentException("That name specifies an existing directory. Please specify a filename.", "fileName"));
-            _contentsChanged = true;
-            _fileAlreadyExists = File.Exists(_name);
-            Save();
-        }
-
-
-        /// <summary>
-        ///   Save the zip archive to the specified stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The <c>ZipFile</c> instance is written to storage - typically a zip file
-        ///   in a filesystem, but using this overload, the storage can be anything
-        ///   accessible via a writable stream - only when the caller calls <c>Save</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Use this method to save the zip content to a stream directly.  A common
-        ///   scenario is an ASP.NET application that dynamically generates a zip file
-        ///   and allows the browser to download it. The application can call
-        ///   <c>Save(Response.OutputStream)</c> to write a zipfile directly to the
-        ///   output stream, without creating a zip file on the disk on the ASP.NET
-        ///   server.
-        /// </para>
-        ///
-        /// <para>
-        ///   Be careful when saving a file to a non-seekable stream, including
-        ///   <c>Response.OutputStream</c>. When DotNetZip writes to a non-seekable
-        ///   stream, the zip archive is formatted in such a way that may not be
-        ///   compatible with all zip tools on all platforms.  It's a perfectly legal
-        ///   and compliant zip file, but some people have reported problems opening
-        ///   files produced this way using the Mac OS archive utility.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example saves the zipfile content into a MemoryStream, and
-        ///   then gets the array of bytes from that MemoryStream.
-        ///
-        /// <code lang="C#">
-        /// using (var zip = new Ionic.Zip.ZipFile())
-        /// {
-        ///     zip.CompressionLevel= Ionic.Zlib.CompressionLevel.BestCompression;
-        ///     zip.Password = "VerySecret.";
-        ///     zip.Encryption = EncryptionAlgorithm.WinZipAes128;
-        ///     zip.AddFile(sourceFileName);
-        ///     MemoryStream output = new MemoryStream();
-        ///     zip.Save(output);
-        ///
-        ///     byte[] zipbytes = output.ToArray();
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example shows a pitfall you should avoid. DO NOT read
-        ///   from a stream, then try to save to the same stream.  DO
-        ///   NOT DO THIS:
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// using (var fs = new FileSteeam(filename, FileMode.Open))
-        /// {
-        ///   using (var zip = Ionic.Zip.ZipFile.Read(inputStream))
-        ///   {
-        ///     zip.AddEntry("Name1.txt", "this is the content");
-        ///     zip.Save(inputStream);  // NO NO NO!!
-        ///   }
-        /// }
-        /// </code>
-        ///
-        /// <para>
-        ///   Better like this:
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// using (var zip = Ionic.Zip.ZipFile.Read(filename))
-        /// {
-        ///     zip.AddEntry("Name1.txt", "this is the content");
-        ///     zip.Save();  // YES!
-        /// }
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <param name="outputStream">
-        ///   The <c>System.IO.Stream</c> to write to. It must be
-        ///   writable. If you created the ZipFile instanct by calling
-        ///   ZipFile.Read(), this stream must not be the same stream
-        ///   you passed to ZipFile.Read().
-        /// </param>
-        public void Save(Stream outputStream)
-        {
-            if (outputStream == null)
-                throw new ArgumentNullException("outputStream");
-            if (!outputStream.CanWrite)
-                throw new ArgumentException("Must be a writable stream.", "outputStream");
-
-            // if we had a filename to save to, we are now obliterating it.
-            _name = null;
-
-            _writestream = new CountingStream(outputStream);
-
-            _contentsChanged = true;
-            _fileAlreadyExists = false;
-            Save();
-        }
-
-
-    }
-
-
-
-    internal static class ZipOutput
-    {
-        public static bool WriteCentralDirectoryStructure(Stream s,
-                                                          ICollection<ZipEntry> entries,
-                                                          uint numSegments,
-                                                          Zip64Option zip64,
-                                                          String comment,
-                                                          ZipContainer container)
-        {
-            var zss = s as ZipSegmentedStream;
-            if (zss != null)
-                zss.ContiguousWrite = true;
-
-            // write to a memory stream in order to keep the
-            // CDR contiguous
-            Int64 aLength = 0;
-            using (var ms = new MemoryStream())
-            {
-                foreach (ZipEntry e in entries)
-                {
-                    if (e.IncludedInMostRecentSave)
-                    {
-                        // this writes a ZipDirEntry corresponding to the ZipEntry
-                        e.WriteCentralDirectoryEntry(ms);
-                    }
-                }
-                var a = ms.ToArray();
-                s.Write(a, 0, a.Length);
-                aLength = a.Length;
-            }
-
-
-            // We need to keep track of the start and
-            // Finish of the Central Directory Structure.
-
-            // Cannot always use WriteStream.Length or Position; some streams do
-            // not support these. (eg, ASP.NET Response.OutputStream) In those
-            // cases we have a CountingStream.
-
-            // Also, we cannot just set Start as s.Position bfore the write, and Finish
-            // as s.Position after the write.  In a split zip, the write may actually
-            // flip to the next segment.  In that case, Start will be zero.  But we
-            // don't know that til after we know the size of the thing to write.  So the
-            // answer is to compute the directory, then ask the ZipSegmentedStream which
-            // segment that directory would fall in, it it were written.  Then, include
-            // that data into the directory, and finally, write the directory to the
-            // output stream.
-
-            var output = s as CountingStream;
-            long Finish = (output != null) ? output.ComputedPosition : s.Position;  // BytesWritten
-            long Start = Finish - aLength;
-
-            // need to know which segment the EOCD record starts in
-            UInt32 startSegment = (zss != null)
-                ? zss.CurrentSegment
-                : 0;
-
-            Int64 SizeOfCentralDirectory = Finish - Start;
-
-            int countOfEntries = CountEntries(entries);
-
-            bool needZip64CentralDirectory =
-                zip64 == Zip64Option.Always ||
-                countOfEntries >= 0xFFFF ||
-                SizeOfCentralDirectory > 0xFFFFFFFF ||
-                Start > 0xFFFFFFFF;
-
-            byte[] a2 = null;
-
-            // emit ZIP64 extensions as required
-            if (needZip64CentralDirectory)
-            {
-                if (zip64 == Zip64Option.Never)
-                {
-#if NETCF
-                    throw new ZipException("The archive requires a ZIP64 Central Directory. Consider enabling ZIP64 extensions.");
-#else
-                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(1);
-                    if (sf.GetMethod().DeclaringType == typeof(ZipFile))
-                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
-                    else
-                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
-#endif
-
-                }
-
-                var a = GenZip64EndOfCentralDirectory(Start, Finish, countOfEntries, numSegments);
-                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
-                if (startSegment != 0)
-                {
-                    UInt32 thisSegment = zss.ComputeSegment(a.Length + a2.Length);
-                    int i = 16;
-                    // number of this disk
-                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
-                    i += 4;
-                    // number of the disk with the start of the central directory
-                    //Array.Copy(BitConverter.GetBytes(startSegment), 0, a, i, 4);
-                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
-
-                    i = 60;
-                    // offset 60
-                    // number of the disk with the start of the zip64 eocd
-                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
-                    i += 4;
-                    i += 8;
-
-                    // offset 72
-                    // total number of disks
-                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
-                }
-                s.Write(a, 0, a.Length);
-            }
-            else
-                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
-
-
-            // now, the regular footer
-            if (startSegment != 0)
-            {
-                // The assumption is the central directory is never split across
-                // segment boundaries.
-
-                UInt16 thisSegment = (UInt16) zss.ComputeSegment(a2.Length);
-                int i = 4;
-                // number of this disk
-                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
-                i += 2;
-                // number of the disk with the start of the central directory
-                //Array.Copy(BitConverter.GetBytes((UInt16)startSegment), 0, a2, i, 2);
-                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
-                i += 2;
-            }
-
-            s.Write(a2, 0, a2.Length);
-
-            // reset the contiguous write property if necessary
-            if (zss != null)
-                zss.ContiguousWrite = false;
-
-            return needZip64CentralDirectory;
-        }
-
-
-        private static System.Text.Encoding GetEncoding(ZipContainer container, string t)
-        {
-            switch (container.AlternateEncodingUsage)
-            {
-                case ZipOption.Always:
-                    return container.AlternateEncoding;
-                case ZipOption.Never:
-                    return container.DefaultEncoding;
-            }
-
-            // AsNecessary is in force
-            var e = container.DefaultEncoding;
-            if (t == null) return e;
-
-            var bytes = e.GetBytes(t);
-            var t2 = e.GetString(bytes,0,bytes.Length);
-            if (t2.Equals(t)) return e;
-            return container.AlternateEncoding;
-        }
-
-
-
-        private static byte[] GenCentralDirectoryFooter(long StartOfCentralDirectory,
-                                                        long EndOfCentralDirectory,
-                                                        Zip64Option zip64,
-                                                        int entryCount,
-                                                        string comment,
-                                                        ZipContainer container)
-        {
-            System.Text.Encoding encoding = GetEncoding(container, comment);
-            int j = 0;
-            int bufferLength = 22;
-            byte[] block = null;
-            Int16 commentLength = 0;
-            if ((comment != null) && (comment.Length != 0))
-            {
-                block = encoding.GetBytes(comment);
-                commentLength = (Int16)block.Length;
-            }
-            bufferLength += commentLength;
-            byte[] bytes = new byte[bufferLength];
-
-            int i = 0;
-            // signature
-            byte[] sig = BitConverter.GetBytes(ZipConstants.EndOfCentralDirectorySignature);
-            Array.Copy(sig, 0, bytes, i, 4);
-            i+=4;
-
-            // number of this disk
-            // (this number may change later)
-            bytes[i++] = 0;
-            bytes[i++] = 0;
-
-            // number of the disk with the start of the central directory
-            // (this number may change later)
-            bytes[i++] = 0;
-            bytes[i++] = 0;
-
-            // handle ZIP64 extensions for the end-of-central-directory
-            if (entryCount >= 0xFFFF || zip64 == Zip64Option.Always)
-            {
-                // the ZIP64 version.
-                for (j = 0; j < 4; j++)
-                    bytes[i++] = 0xFF;
-            }
-            else
-            {
-                // the standard version.
-                // total number of entries in the central dir on this disk
-                bytes[i++] = (byte)(entryCount & 0x00FF);
-                bytes[i++] = (byte)((entryCount & 0xFF00) >> 8);
-
-                // total number of entries in the central directory
-                bytes[i++] = (byte)(entryCount & 0x00FF);
-                bytes[i++] = (byte)((entryCount & 0xFF00) >> 8);
-            }
-
-            // size of the central directory
-            Int64 SizeOfCentralDirectory = EndOfCentralDirectory - StartOfCentralDirectory;
-
-            if (SizeOfCentralDirectory >= 0xFFFFFFFF || StartOfCentralDirectory >= 0xFFFFFFFF)
-            {
-                // The actual data is in the ZIP64 central directory structure
-                for (j = 0; j < 8; j++)
-                    bytes[i++] = 0xFF;
-            }
-            else
-            {
-                // size of the central directory (we just get the low 4 bytes)
-                bytes[i++] = (byte)(SizeOfCentralDirectory & 0x000000FF);
-                bytes[i++] = (byte)((SizeOfCentralDirectory & 0x0000FF00) >> 8);
-                bytes[i++] = (byte)((SizeOfCentralDirectory & 0x00FF0000) >> 16);
-                bytes[i++] = (byte)((SizeOfCentralDirectory & 0xFF000000) >> 24);
-
-                // offset of the start of the central directory (we just get the low 4 bytes)
-                bytes[i++] = (byte)(StartOfCentralDirectory & 0x000000FF);
-                bytes[i++] = (byte)((StartOfCentralDirectory & 0x0000FF00) >> 8);
-                bytes[i++] = (byte)((StartOfCentralDirectory & 0x00FF0000) >> 16);
-                bytes[i++] = (byte)((StartOfCentralDirectory & 0xFF000000) >> 24);
-            }
-
-
-            // zip archive comment
-            if ((comment == null) || (comment.Length == 0))
-            {
-                // no comment!
-                bytes[i++] = (byte)0;
-                bytes[i++] = (byte)0;
-            }
-            else
-            {
-                // the size of our buffer defines the max length of the comment we can write
-                if (commentLength + i + 2 > bytes.Length) commentLength = (Int16)(bytes.Length - i - 2);
-                bytes[i++] = (byte)(commentLength & 0x00FF);
-                bytes[i++] = (byte)((commentLength & 0xFF00) >> 8);
-
-                if (commentLength != 0)
-                {
-                    // now actually write the comment itself into the byte buffer
-                    for (j = 0; (j < commentLength) && (i + j < bytes.Length); j++)
-                    {
-                        bytes[i + j] = block[j];
-                    }
-                    i += j;
-                }
-            }
-
-            //   s.Write(bytes, 0, i);
-            return bytes;
-        }
-
-
-
-        private static byte[] GenZip64EndOfCentralDirectory(long StartOfCentralDirectory,
-                                                            long EndOfCentralDirectory,
-                                                            int entryCount,
-                                                            uint numSegments)
-        {
-            const int bufferLength = 12 + 44 + 20;
-
-            byte[] bytes = new byte[bufferLength];
-
-            int i = 0;
-            // signature
-            byte[] sig = BitConverter.GetBytes(ZipConstants.Zip64EndOfCentralDirectoryRecordSignature);
-            Array.Copy(sig, 0, bytes, i, 4);
-            i+=4;
-
-            // There is a possibility to include "Extensible" data in the zip64
-            // end-of-central-dir record.  I cannot figure out what it might be used to
-            // store, so the size of this record is always fixed.  Maybe it is used for
-            // strong encryption data?  That is for another day.
-            long DataSize = 44;
-            Array.Copy(BitConverter.GetBytes(DataSize), 0, bytes, i, 8);
-            i += 8;
-
-            // offset 12
-            // VersionMadeBy = 45;
-            bytes[i++] = 45;
-            bytes[i++] = 0x00;
-
-            // VersionNeededToExtract = 45;
-            bytes[i++] = 45;
-            bytes[i++] = 0x00;
-
-            // offset 16
-            // number of the disk, and the disk with the start of the central dir.
-            // (this may change later)
-            for (int j = 0; j < 8; j++)
-                bytes[i++] = 0x00;
-
-            // offset 24
-            long numberOfEntries = entryCount;
-            Array.Copy(BitConverter.GetBytes(numberOfEntries), 0, bytes, i, 8);
-            i += 8;
-            Array.Copy(BitConverter.GetBytes(numberOfEntries), 0, bytes, i, 8);
-            i += 8;
-
-            // offset 40
-            Int64 SizeofCentraldirectory = EndOfCentralDirectory - StartOfCentralDirectory;
-            Array.Copy(BitConverter.GetBytes(SizeofCentraldirectory), 0, bytes, i, 8);
-            i += 8;
-            Array.Copy(BitConverter.GetBytes(StartOfCentralDirectory), 0, bytes, i, 8);
-            i += 8;
-
-            // offset 56
-            // now, the locator
-            // signature
-            sig = BitConverter.GetBytes(ZipConstants.Zip64EndOfCentralDirectoryLocatorSignature);
-            Array.Copy(sig, 0, bytes, i, 4);
-            i+=4;
-
-            // offset 60
-            // number of the disk with the start of the zip64 eocd
-            // (this will change later)  (it will?)
-            uint x2 = (numSegments==0)?0:(uint)(numSegments-1);
-            Array.Copy(BitConverter.GetBytes(x2), 0, bytes, i, 4);
-            i+=4;
-
-            // offset 64
-            // relative offset of the zip64 eocd
-            Array.Copy(BitConverter.GetBytes(EndOfCentralDirectory), 0, bytes, i, 8);
-            i += 8;
-
-            // offset 72
-            // total number of disks
-            // (this will change later)
-            Array.Copy(BitConverter.GetBytes(numSegments), 0, bytes, i, 4);
-            i+=4;
-
-            return bytes;
-        }
-
-
-
-        private static int CountEntries(ICollection<ZipEntry> _entries)
-        {
-            // Cannot just emit _entries.Count, because some of the entries
-            // may have been skipped.
-            int count = 0;
-            foreach (var entry in _entries)
-                if (entry.IncludedInMostRecentSave) count++;
-            return count;
-        }
-
-
-
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.SaveSelfExtractor.cs b/EPPlus/Packaging/DotNetZip/ZipFile.SaveSelfExtractor.cs
deleted file mode 100644
index 800a058..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.SaveSelfExtractor.cs
+++ /dev/null
@@ -1,1101 +0,0 @@
-// ZipFile.saveSelfExtractor.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008-2011 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-August-10 19:22:46>
-//
-// ------------------------------------------------------------------
-//
-// This is a the source module that implements the stuff for saving to a
-// self-extracting Zip archive.
-//
-// ZipFile is set up as a "partial class" - defined in multiple .cs source modules.
-// This is one of the source modules for the ZipFile class.
-//
-// Here's the design: The self-extracting zip file is just a regular managed EXE
-// file, with embedded resources.  The managed code logic instantiates a ZipFile, and
-// then extracts each entry.  The embedded resources include the zip archive content,
-// as well as the Zip library itself.  The latter is required so that self-extracting
-// can work on any machine, whether or not it has the DotNetZip library installed on
-// it.
-//
-// What we need to do is create the animal I just described, within a method on the
-// ZipFile class.  This source module provides that capability. The method is
-// SaveSelfExtractor().
-//
-// The way the method works: it uses the programmatic interface to the csc.exe
-// compiler, Microsoft.CSharp.CSharpCodeProvider, to compile "boilerplate"
-// extraction logic into a new assembly.  As part of that compile, we embed within
-// that assembly the zip archive itself, as well as the Zip library.
-//
-// Therefore we need to first save to a temporary zip file, then produce the exe.
-//
-// There are a few twists.
-//
-// The Visual Studio Project structure is a little weird.  There are code files
-// that ARE NOT compiled during a normal build of the VS Solution.  They are
-// marked as embedded resources.  These are the various "boilerplate" modules that
-// are used in the self-extractor. These modules are: WinFormsSelfExtractorStub.cs
-// WinFormsSelfExtractorStub.Designer.cs CommandLineSelfExtractorStub.cs
-// PasswordDialog.cs PasswordDialog.Designer.cs
-//
-// At design time, if you want to modify the way the GUI looks, you have to
-// mark those modules to have a "compile" build action.  Then tweak em, test,
-// etc.  Then again mark them as "Embedded resource".
-//
-// ------------------------------------------------------------------
-
-using System;
-using System.Reflection;
-using System.IO;
-using System.Collections.Generic;
-
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-#if !NO_SFX
-    /// <summary>
-    /// An enum that provides the different self-extractor flavors
-    /// </summary>
-    internal enum SelfExtractorFlavor
-    {
-        /// <summary>
-        /// A self-extracting zip archive that runs from the console or
-        /// command line.
-        /// </summary>
-        ConsoleApplication = 0,
-
-        /// <summary>
-        /// A self-extracting zip archive that presents a graphical user
-        /// interface when it is executed.
-        /// </summary>
-        WinFormsApplication,
-    }
-
-    /// <summary>
-    /// The options for generating a self-extracting archive.
-    /// </summary>
-    internal class SelfExtractorSaveOptions
-    {
-        /// <summary>
-        ///   The type of SFX to create.
-        /// </summary>
-        public SelfExtractorFlavor Flavor
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The command to run after extraction.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This is optional. Leave it empty (<c>null</c> in C# or <c>Nothing</c> in
-        ///   VB) to run no command after extraction.
-        /// </para>
-        ///
-        /// <para>
-        ///   If it is non-empty, the SFX will execute the command specified in this
-        ///   string on the user's machine, and using the extract directory as the
-        ///   working directory for the process, after unpacking the archive. The
-        ///   program to execute can include a path, if you like. If you want to execute
-        ///   a program that accepts arguments, specify the program name, followed by a
-        ///   space, and then the arguments for the program, each separated by a space,
-        ///   just as you would on a normal command line. Example: <c>program.exe arg1
-        ///   arg2</c>.  The string prior to the first space will be taken as the
-        ///   program name, and the string following the first space specifies the
-        ///   arguments to the program.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you want to execute a program that has a space in the name or path of
-        ///   the file, surround the program name in double-quotes. The first character
-        ///   of the command line should be a double-quote character, and there must be
-        ///   a matching double-quote following the end of the program file name. Any
-        ///   optional arguments to the program follow that, separated by
-        ///   spaces. Example: <c>"c:\project files\program name.exe" arg1 arg2</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   If the flavor of the SFX is <c>SelfExtractorFlavor.ConsoleApplication</c>,
-        ///   then the SFX starts a new process, using this string as the post-extract
-        ///   command line.  The SFX waits for the process to exit.  The exit code of
-        ///   the post-extract command line is returned as the exit code of the
-        ///   command-line self-extractor exe. A non-zero exit code is typically used to
-        ///   indicated a failure by the program. In the case of an SFX, a non-zero exit
-        ///   code may indicate a failure during extraction, OR, it may indicate a
-        ///   failure of the run-after-extract program if specified, OR, it may indicate
-        ///   the run-after-extract program could not be fuond. There is no way to
-        ///   distinguish these conditions from the calling shell, aside from parsing
-        ///   the output of the SFX. If you have Quiet set to <c>true</c>, you may not
-        ///   see error messages, if a problem occurs.
-        /// </para>
-        ///
-        /// <para>
-        ///   If the flavor of the SFX is
-        ///   <c>SelfExtractorFlavor.WinFormsApplication</c>, then the SFX starts a new
-        ///   process, using this string as the post-extract command line, and using the
-        ///   extract directory as the working directory for the process. The SFX does
-        ///   not wait for the command to complete, and does not check the exit code of
-        ///   the program. If the run-after-extract program cannot be fuond, a message
-        ///   box is displayed indicating that fact.
-        /// </para>
-        ///
-        /// <para>
-        ///   You can specify environment variables within this string, with a format like
-        ///   <c>%NAME%</c>. The value of these variables will be expanded at the time
-        ///   the SFX is run. Example: <c>%WINDIR%\system32\xcopy.exe</c> may expand at
-        ///   runtime to <c>c:\Windows\System32\xcopy.exe</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   By combining this with the <c>RemoveUnpackedFilesAfterExecute</c>
-        ///   flag, you can create an SFX that extracts itself, runs a file that
-        ///   was extracted, then deletes all the files that were extracted. If
-        ///   you want it to run "invisibly" then set <c>Flavor</c> to
-        ///   <c>SelfExtractorFlavor.ConsoleApplication</c>, and set <c>Quiet</c>
-        ///   to true.  The user running such an EXE will see a console window
-        ///   appear, then disappear quickly.  You may also want to specify the
-        ///   default extract location, with <c>DefaultExtractDirectory</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you set <c>Flavor</c> to
-        ///   <c>SelfExtractorFlavor.WinFormsApplication</c>, and set <c>Quiet</c> to
-        ///   true, then a GUI with progressbars is displayed, but it is
-        ///   "non-interactive" - it accepts no input from the user.  Instead the SFX
-        ///   just automatically unpacks and exits.
-        /// </para>
-        ///
-        /// </remarks>
-        public String PostExtractCommandLine
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The default extract directory the user will see when
-        ///   running the self-extracting archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Passing null (or Nothing in VB) here will cause the Self Extractor to use
-        ///   the the user's personal directory (<see
-        ///   cref="Environment.SpecialFolder.Personal"/>) for the default extract
-        ///   location.
-        /// </para>
-        ///
-        /// <para>
-        ///   This is only a default location.  The actual extract location will be
-        ///   settable on the command line when the SFX is executed.
-        /// </para>
-        ///
-        /// <para>
-        ///   You can specify environment variables within this string,
-        ///   with <c>%NAME%</c>. The value of these variables will be
-        ///   expanded at the time the SFX is run. Example:
-        ///   <c>%USERPROFILE%\Documents\unpack</c> may expand at runtime to
-        ///   <c>c:\users\melvin\Documents\unpack</c>.
-        /// </para>
-        /// </remarks>
-        public String DefaultExtractDirectory
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The name of an .ico file in the filesystem to use for the application icon
-        ///   for the generated SFX.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Normally, DotNetZip will embed an "zipped folder" icon into the generated
-        ///   SFX.  If you prefer to use a different icon, you can specify it here. It
-        ///   should be a .ico file.  This file is passed as the <c>/win32icon</c>
-        ///   option to the csc.exe compiler when constructing the SFX file.
-        /// </para>
-        /// </remarks>
-        ///
-        public string IconFile
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   Whether the ConsoleApplication SFX will be quiet during extraction.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This option affects the way the generated SFX runs. By default it is
-        ///   false.  When you set it to true,...
-        /// </para>
-        ///
-        /// <list type="table">
-        ///   <listheader>
-        ///     <term>Flavor</term>
-        ///     <description>Behavior</description>
-        ///   </listheader>
-        ///
-        /// <item>
-        ///   <term><c>ConsoleApplication</c></term>
-        ///   <description><para>no messages will be emitted during successful
-        ///     operation.</para> <para> Double-clicking the SFX in Windows
-        ///     Explorer or as an attachment in an email will cause a console
-        ///     window to appear briefly, before it disappears. If you run the
-        ///     ConsoleApplication SFX from the cmd.exe prompt, it runs as a
-        ///     normal console app; by default, because it is quiet, it displays
-        ///     no messages to the console.  If you pass the -v+ command line
-        ///     argument to the Console SFX when you run it, you will get verbose
-        ///     messages to the console. </para>
-        ///   </description>
-        /// </item>
-        ///
-        /// <item>
-        ///   <term><c>WinFormsApplication</c></term>
-        ///   <description>the SFX extracts automatically when the application
-        ///        is launched, with no additional user input.
-        ///   </description>
-        /// </item>
-        ///
-        /// </list>
-        ///
-        /// <para>
-        ///   When you set it to false,...
-        /// </para>
-        ///
-        /// <list type="table">
-        ///   <listheader>
-        ///     <term>Flavor</term>
-        ///     <description>Behavior</description>
-        ///   </listheader>
-        ///
-        /// <item>
-        ///   <term><c>ConsoleApplication</c></term>
-        ///   <description><para>the extractor will emit a
-        ///     message to the console for each entry extracted.</para>
-        ///     <para>
-        ///       When double-clicking to launch the SFX, the console window will
-        ///       remain, and the SFX will emit a message for each file as it
-        ///       extracts. The messages fly by quickly, they won't be easily
-        ///       readable, unless the extracted files are fairly large.
-        ///     </para>
-        ///   </description>
-        /// </item>
-        ///
-        /// <item>
-        ///   <term><c>WinFormsApplication</c></term>
-        ///   <description>the SFX presents a forms UI and allows the user to select
-        ///     options before extracting.
-        ///   </description>
-        /// </item>
-        ///
-        /// </list>
-        ///
-        /// </remarks>
-        public bool Quiet
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   Specify what the self-extractor will do when extracting an entry
-        ///   would overwrite an existing file.
-        /// </summary>
-        /// <remarks>
-        /// <para>
-        ///   The default behavvior is to Throw.
-        /// </para>
-        /// </remarks>
-        public Ionic.Zip.ExtractExistingFileAction ExtractExistingFile
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   Whether to remove the files that have been unpacked, after executing the
-        ///   PostExtractCommandLine.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   If true, and if there is a <see
-        ///   cref="SelfExtractorSaveOptions.PostExtractCommandLine">
-        ///   PostExtractCommandLine</see>, and if the command runs successfully,
-        ///   then the files that the SFX unpacked will be removed, afterwards.  If
-        ///   the command does not complete successfully (non-zero return code),
-        ///   that is interpreted as a failure, and the extracted files will not be
-        ///   removed.
-        /// </para>
-        ///
-        /// <para>
-        ///   Setting this flag, and setting <c>Flavor</c> to
-        ///   <c>SelfExtractorFlavor.ConsoleApplication</c>, and setting <c>Quiet</c> to
-        ///   true, results in an SFX that extracts itself, runs a file that was
-        ///   extracted, then deletes all the files that were extracted, with no
-        ///   intervention by the user.  You may also want to specify the default
-        ///   extract location, with <c>DefaultExtractDirectory</c>.
-        /// </para>
-        ///
-        /// </remarks>
-        public bool RemoveUnpackedFilesAfterExecute
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   The file version number to embed into the generated EXE. It will show up, for
-        ///   example, during a mouseover in Windows Explorer.
-        /// </summary>
-        ///
-        public Version FileVersion
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The product version to embed into the generated EXE. It will show up, for
-        ///   example, during a mouseover in Windows Explorer.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   You can use any arbitrary string, but a human-readable version number is
-        ///   recommended. For example "v1.2 alpha" or "v4.2 RC2".  If you specify nothing,
-        ///   then there is no product version embedded into the EXE.
-        /// </remarks>
-        ///
-        public String ProductVersion
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The copyright notice, if any, to embed into the generated EXE.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   It will show up, for example, while viewing properties of the file in
-        ///   Windows Explorer.  You can use any arbitrary string, but typically you
-        ///   want something like "Copyright � Dino Chiesa 2011".
-        /// </remarks>
-        ///
-        public String Copyright
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   The description to embed into the generated EXE.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Use any arbitrary string.  This text will be displayed during a
-        ///   mouseover in Windows Explorer.  If you specify nothing, then the string
-        ///   "DotNetZip SFX Archive" is embedded into the EXE as the description.
-        /// </remarks>
-        ///
-        public String Description
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The product name to embed into the generated EXE.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Use any arbitrary string. This text will be displayed
-        ///   while viewing properties of the EXE file in
-        ///   Windows Explorer.
-        /// </remarks>
-        ///
-        public String ProductName
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   The title to display in the Window of a GUI SFX, while it extracts.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     By default the title show in the GUI window of a self-extractor
-        ///     is "DotNetZip Self-extractor (http://DotNetZip.codeplex.com/)".
-        ///     You can change that by setting this property before saving the SFX.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     This property has an effect only when producing a Self-extractor
-        ///     of flavor <c>SelfExtractorFlavor.WinFormsApplication</c>.
-        ///   </para>
-        /// </remarks>
-        ///
-        public String SfxExeWindowTitle
-        {
-            // workitem 12608
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   Additional options for the csc.exe compiler, when producing the SFX
-        ///   EXE.
-        /// </summary>
-        /// <exclude/>
-        public string AdditionalCompilerSwitches
-        {
-            get; set;
-        }
-    }
-
-
-
-
-    partial class ZipFile
-    {
-        class ExtractorSettings
-        {
-            public SelfExtractorFlavor Flavor;
-            public List<string> ReferencedAssemblies;
-            public List<string> CopyThroughResources;
-            public List<string> ResourcesToCompile;
-        }
-
-
-        private static ExtractorSettings[] SettingsList = {
-            new ExtractorSettings() {
-                Flavor = SelfExtractorFlavor.WinFormsApplication,
-                ReferencedAssemblies= new List<string>{
-                    "System.dll", "System.Windows.Forms.dll", "System.Drawing.dll"},
-                CopyThroughResources = new List<string>{
-                    "Ionic.Zip.WinFormsSelfExtractorStub.resources",
-                    "Ionic.Zip.Forms.PasswordDialog.resources",
-                    "Ionic.Zip.Forms.ZipContentsDialog.resources"},
-                ResourcesToCompile = new List<string>{
-                    "WinFormsSelfExtractorStub.cs",
-                    "WinFormsSelfExtractorStub.Designer.cs", // .Designer.cs?
-                    "PasswordDialog.cs",
-                    "PasswordDialog.Designer.cs",             //.Designer.cs"
-                    "ZipContentsDialog.cs",
-                    "ZipContentsDialog.Designer.cs",             //.Designer.cs"
-                    "FolderBrowserDialogEx.cs",
-                }
-            },
-            new ExtractorSettings() {
-                Flavor = SelfExtractorFlavor.ConsoleApplication,
-                ReferencedAssemblies= new List<string> { "System.dll", },
-                CopyThroughResources = null,
-                ResourcesToCompile = new List<string>{"CommandLineSelfExtractorStub.cs"}
-            }
-        };
-
-
-
-        //string _defaultExtractLocation;
-        //string _postExtractCmdLine;
-        //         string _SetDefaultLocationCode =
-        //         "namespace OfficeOpenXml.Packaging.Ionic.Zip { internal partial class WinFormsSelfExtractorStub { partial void _SetDefaultExtractLocation() {" +
-        //         " txtExtractDirectory.Text = \"@@VALUE\"; } }}";
-
-
-
-        /// <summary>
-        /// Saves the ZipFile instance to a self-extracting zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        /// The generated exe image will execute on any machine that has the .NET
-        /// Framework 2.0 installed on it.  The generated exe image is also a
-        /// valid ZIP file, readable with DotNetZip or another Zip library or tool
-        /// such as WinZip.
-        /// </para>
-        ///
-        /// <para>
-        /// There are two "flavors" of self-extracting archive.  The
-        /// <c>WinFormsApplication</c> version will pop up a GUI and allow the
-        /// user to select a target directory into which to extract. There's also
-        /// a checkbox allowing the user to specify to overwrite existing files,
-        /// and another checkbox to allow the user to request that Explorer be
-        /// opened to see the extracted files after extraction.  The other flavor
-        /// is <c>ConsoleApplication</c>.  A self-extractor generated with that
-        /// flavor setting will run from the command line. It accepts command-line
-        /// options to set the overwrite behavior, and to specify the target
-        /// extraction directory.
-        /// </para>
-        ///
-        /// <para>
-        /// There are a few temporary files created during the saving to a
-        /// self-extracting zip.  These files are created in the directory pointed
-        /// to by <see cref="ZipFile.TempFileFolder"/>, which defaults to <see
-        /// cref="System.IO.Path.GetTempPath"/>.  These temporary files are
-        /// removed upon successful completion of this method.
-        /// </para>
-        ///
-        /// <para>
-        /// When a user runs the WinForms SFX, the user's personal directory (<see
-        /// cref="Environment.SpecialFolder.Personal">Environment.SpecialFolder.Personal</see>)
-        /// will be used as the default extract location.  If you want to set the
-        /// default extract location, you should use the other overload of
-        /// <c>SaveSelfExtractor()</c>/ The user who runs the SFX will have the
-        /// opportunity to change the extract directory before extracting. When
-        /// the user runs the Command-Line SFX, the user must explicitly specify
-        /// the directory to which to extract.  The .NET Framework 2.0 is required
-        /// on the computer when the self-extracting archive is run.
-        /// </para>
-        ///
-        /// <para>
-        /// NB: This method is not available in the version of DotNetZip build for
-        /// the .NET Compact Framework, nor in the "Reduced" DotNetZip library.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code>
-        /// string DirectoryPath = "c:\\Documents\\Project7";
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
-        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe";
-        ///     zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Dim DirectoryPath As String = "c:\Documents\Project7"
-        /// Using zip As New ZipFile()
-        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
-        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe"
-        ///     zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="exeToGenerate">
-        ///   a pathname, possibly fully qualified, to be created. Typically it
-        ///   will end in an .exe extension.</param>
-        /// <param name="flavor">
-        ///   Indicates whether a Winforms or Console self-extractor is
-        ///   desired. </param>
-        internal void SaveSelfExtractor(string exeToGenerate, SelfExtractorFlavor flavor)
-        {
-            SelfExtractorSaveOptions options = new SelfExtractorSaveOptions();
-            options.Flavor = flavor;
-            SaveSelfExtractor(exeToGenerate, options);
-        }
-
-
-
-        /// <summary>
-        ///   Saves the ZipFile instance to a self-extracting zip archive, using
-        ///   the specified save options.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method saves a self extracting archive, using the specified save
-        ///   options. These options include the flavor of the SFX, the default extract
-        ///   directory, the icon file, and so on.  See the documentation
-        ///   for <see cref="SaveSelfExtractor(string , SelfExtractorFlavor)"/> for more
-        ///   details.
-        /// </para>
-        ///
-        /// <para>
-        ///   The user who runs the SFX will have the opportunity to change the extract
-        ///   directory before extracting. If at the time of extraction, the specified
-        ///   directory does not exist, the SFX will create the directory before
-        ///   extracting the files.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example saves a WinForms-based self-extracting archive EXE that
-        ///   will use c:\ExtractHere as the default extract location. The C# code
-        ///   shows syntax for .NET 3.0, which uses an object initializer for
-        ///   the SelfExtractorOptions object.
-        /// <code>
-        /// string DirectoryPath = "c:\\Documents\\Project7";
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
-        ///     zip.Comment = "This will be embedded into a self-extracting WinForms-based exe";
-        ///     var options = new SelfExtractorOptions
-        ///     {
-        ///       Flavor = SelfExtractorFlavor.WinFormsApplication,
-        ///       DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere",
-        ///       PostExtractCommandLine = ExeToRunAfterExtract,
-        ///       SfxExeWindowTitle = "My Custom Window Title",
-        ///       RemoveUnpackedFilesAfterExecute = true
-        ///     };
-        ///     zip.SaveSelfExtractor("archive.exe", options);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Dim DirectoryPath As String = "c:\Documents\Project7"
-        /// Using zip As New ZipFile()
-        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
-        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe"
-        ///     Dim options As New SelfExtractorOptions()
-        ///     options.Flavor = SelfExtractorFlavor.WinFormsApplication
-        ///     options.DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere"
-        ///     options.PostExtractCommandLine = ExeToRunAfterExtract
-        ///     options.SfxExeWindowTitle = "My Custom Window Title"
-        ///     options.RemoveUnpackedFilesAfterExecute = True
-        ///     zip.SaveSelfExtractor("archive.exe", options)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="exeToGenerate">The name of the EXE to generate.</param>
-        /// <param name="options">provides the options for creating the
-        /// Self-extracting archive.</param>
-        internal void SaveSelfExtractor(string exeToGenerate, SelfExtractorSaveOptions options)
-        {
-            // Save an SFX that is both an EXE and a ZIP.
-
-            // Check for the case where we are re-saving a zip archive
-            // that was originally instantiated with a stream.  In that case,
-            // the _name will be null. If so, we set _writestream to null,
-            // which insures that we'll cons up a new WriteStream (with a filesystem
-            // file backing it) in the Save() method.
-            if (_name == null)
-                _writestream = null;
-
-            _SavingSfx = true;
-            _name = exeToGenerate;
-            if (Directory.Exists(_name))
-                throw new ZipException("Bad Directory", new System.ArgumentException("That name specifies an existing directory. Please specify a filename.", "exeToGenerate"));
-            _contentsChanged = true;
-            _fileAlreadyExists = File.Exists(_name);
-
-            _SaveSfxStub(exeToGenerate, options);
-
-            Save();
-            _SavingSfx = false;
-        }
-
-
-
-
-        private static void ExtractResourceToFile(Assembly a, string resourceName, string filename)
-        {
-            int n = 0;
-            byte[] bytes = new byte[1024];
-            using (Stream instream = a.GetManifestResourceStream(resourceName))
-            {
-                if (instream == null)
-                    throw new ZipException(String.Format("missing resource '{0}'", resourceName));
-
-                using (FileStream outstream = File.OpenWrite(filename))
-                {
-                    do
-                    {
-                        n = instream.Read(bytes, 0, bytes.Length);
-                        outstream.Write(bytes, 0, n);
-                    } while (n > 0);
-                }
-            }
-        }
-
-
-        private void _SaveSfxStub(string exeToGenerate, SelfExtractorSaveOptions options)
-        {
-            string nameOfIconFile = null;
-            string stubExe = null;
-            string unpackedResourceDir = null;
-            string tmpDir = null;
-            try
-            {
-                if (File.Exists(exeToGenerate))
-                {
-                    if (Verbose) StatusMessageTextWriter.WriteLine("The existing file ({0}) will be overwritten.", exeToGenerate);
-                }
-                if (!exeToGenerate.EndsWith(".exe"))
-                {
-                    if (Verbose) StatusMessageTextWriter.WriteLine("Warning: The generated self-extracting file will not have an .exe extension.");
-                }
-
-                // workitem 10553
-                tmpDir = TempFileFolder ?? Path.GetDirectoryName(exeToGenerate);
-                stubExe = GenerateTempPathname(tmpDir, "exe");
-
-                // get the Ionic.Zip assembly
-                Assembly a1 = typeof(ZipFile).Assembly;
-
-                using (var csharp = new Microsoft.CSharp.CSharpCodeProvider
-                       (new Dictionary<string,string>() { { "CompilerVersion", "v2.0" } })) {
-
-                    // The following is a perfect opportunity for a linq query, but
-                    // I cannot use it.  DotNetZip needs to run on .NET 2.0,
-                    // and using LINQ would break that. Here's what it would look
-                    // like:
-                    //
-                    //   var settings = (from x in SettingsList
-                    //                   where x.Flavor == flavor
-                    //                   select x).First();
-
-                    ExtractorSettings settings = null;
-                    foreach (var x in SettingsList)
-                    {
-                        if (x.Flavor == options.Flavor)
-                        {
-                            settings = x;
-                            break;
-                        }
-                    }
-
-                    // sanity check; should never happen
-                    if (settings == null)
-                        throw new BadStateException(String.Format("While saving a Self-Extracting Zip, Cannot find that flavor ({0})?", options.Flavor));
-
-                    // This is the list of referenced assemblies.  Ionic.Zip is
-                    // needed here.  Also if it is the winforms (gui) extractor, we
-                    // need other referenced assemblies, like
-                    // System.Windows.Forms.dll, etc.
-                    var cp = new System.CodeDom.Compiler.CompilerParameters();
-                    cp.ReferencedAssemblies.Add(a1.Location);
-                    if (settings.ReferencedAssemblies != null)
-                        foreach (string ra in settings.ReferencedAssemblies)
-                            cp.ReferencedAssemblies.Add(ra);
-
-                    cp.GenerateInMemory = false;
-                    cp.GenerateExecutable = true;
-                    cp.IncludeDebugInformation = false;
-                    cp.CompilerOptions = "";
-
-                    Assembly a2 = Assembly.GetExecutingAssembly();
-
-                    // Use this to concatenate all the source code resources into a
-                    // single module.
-                    var sb = new System.Text.StringBuilder();
-
-                    // In case there are compiler errors later, we allocate a source
-                    // file name now. If errors are detected, we'll spool the source
-                    // code as well as the errors (in comments) into that filename,
-                    // and throw an exception with the filename.  Makes it easier to
-                    // diagnose.  This should be rare; most errors happen only
-                    // during devlpmt of DotNetZip itself, but there are rare
-                    // occasions when they occur in other cases.
-                    string sourceFile = GenerateTempPathname(tmpDir, "cs");
-
-
-                    // // debugging: enumerate the resources in this assembly
-                    // Console.WriteLine("Resources in this assembly:");
-                    // foreach (string rsrc in a2.GetManifestResourceNames())
-                    //   {
-                    //     Console.WriteLine(rsrc);
-                    //   }
-                    // Console.WriteLine();
-
-
-                    // all the source code is embedded in the DLL as a zip file.
-                    using (ZipFile zip = ZipFile.Read(a2.GetManifestResourceStream("Ionic.Zip.Resources.ZippedResources.zip")))
-                    {
-                        // // debugging: enumerate the files in the embedded zip
-                        // Console.WriteLine("Entries in the embbedded zip:");
-                        // foreach (ZipEntry entry in zip)
-                        //   {
-                        //     Console.WriteLine(entry.FileName);
-                        //   }
-                        // Console.WriteLine();
-
-                        unpackedResourceDir = GenerateTempPathname(tmpDir, "tmp");
-
-                        if (String.IsNullOrEmpty(options.IconFile))
-                        {
-                            // Use the ico file that is embedded into the Ionic.Zip
-                            // DLL itself.  To do this we must unpack the icon to
-                            // the filesystem, in order to specify it on the cmdline
-                            // of csc.exe.  This method will remove the unpacked
-                            // file later.
-                            System.IO.Directory.CreateDirectory(unpackedResourceDir);
-                            ZipEntry e = zip["zippedFile.ico"];
-                            // Must not extract a readonly file - it will be impossible to
-                            // delete later.
-                            if ((e.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
-                                e.Attributes ^= FileAttributes.ReadOnly;
-                            e.Extract(unpackedResourceDir);
-                            nameOfIconFile = Path.Combine(unpackedResourceDir, "zippedFile.ico");
-                            cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", nameOfIconFile);
-                        }
-                        else
-                            cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", options.IconFile);
-
-                        cp.OutputAssembly = stubExe;
-
-                        if (options.Flavor == SelfExtractorFlavor.WinFormsApplication)
-                            cp.CompilerOptions += " /target:winexe";
-
-                        if (!String.IsNullOrEmpty(options.AdditionalCompilerSwitches))
-                            cp.CompilerOptions += " " + options.AdditionalCompilerSwitches;
-
-                        if (String.IsNullOrEmpty(cp.CompilerOptions))
-                            cp.CompilerOptions = null;
-
-                        if ((settings.CopyThroughResources != null) && (settings.CopyThroughResources.Count != 0))
-                        {
-                            if (!Directory.Exists(unpackedResourceDir)) System.IO.Directory.CreateDirectory(unpackedResourceDir);
-                            foreach (string re in settings.CopyThroughResources)
-                            {
-                                string filename = Path.Combine(unpackedResourceDir, re);
-
-                                ExtractResourceToFile(a2, re, filename);
-                                // add the file into the target assembly as an embedded resource
-                                cp.EmbeddedResources.Add(filename);
-                            }
-                        }
-
-                        // add the Ionic.Utils.Zip DLL as an embedded resource
-                        cp.EmbeddedResources.Add(a1.Location);
-
-                        // file header
-                        sb.Append("// " + Path.GetFileName(sourceFile) + "\n")
-                            .Append("// --------------------------------------------\n//\n")
-                            .Append("// This SFX source file was generated by DotNetZip ")
-                            .Append(ZipFile.LibraryVersion.ToString())
-                            .Append("\n//         at ")
-                            .Append(System.DateTime.Now.ToString("yyyy MMMM dd  HH:mm:ss"))
-                            .Append("\n//\n// --------------------------------------------\n\n\n");
-
-                        // assembly attributes
-                        if (!String.IsNullOrEmpty(options.Description))
-                            sb.Append("[assembly: System.Reflection.AssemblyTitle(\""
-                                      + options.Description.Replace("\"", "")
-                                      + "\")]\n");
-                        else
-                            sb.Append("[assembly: System.Reflection.AssemblyTitle(\"DotNetZip SFX Archive\")]\n");
-
-                        if (!String.IsNullOrEmpty(options.ProductVersion))
-                            sb.Append("[assembly: System.Reflection.AssemblyInformationalVersion(\""
-                                      + options.ProductVersion.Replace("\"", "")
-                                      + "\")]\n");
-
-                        // workitem
-                        string copyright =
-                            (String.IsNullOrEmpty(options.Copyright))
-                            ? "Extractor: Copyright � Dino Chiesa 2008-2011"
-                            : options.Copyright.Replace("\"", "");
-
-                        if (!String.IsNullOrEmpty(options.ProductName))
-                            sb.Append("[assembly: System.Reflection.AssemblyProduct(\"")
-                                .Append(options.ProductName.Replace("\"", ""))
-                                .Append("\")]\n");
-                        else
-                            sb.Append("[assembly: System.Reflection.AssemblyProduct(\"DotNetZip\")]\n");
-
-
-                        sb.Append("[assembly: System.Reflection.AssemblyCopyright(\"" + copyright + "\")]\n")
-                            .Append(String.Format("[assembly: System.Reflection.AssemblyVersion(\"{0}\")]\n", ZipFile.LibraryVersion.ToString()));
-                        if (options.FileVersion != null)
-                            sb.Append(String.Format("[assembly: System.Reflection.AssemblyFileVersion(\"{0}\")]\n",
-                                                    options.FileVersion.ToString()));
-
-                        sb.Append("\n\n\n");
-
-                        // Set the default extract location if it is available
-                        string extractLoc = options.DefaultExtractDirectory;
-                        if (extractLoc != null)
-                        {
-                            // remove double-quotes and replace slash with double-slash.
-                            // This, because the value is going to be embedded into a
-                            // cs file as a quoted string, and it needs to be escaped.
-                            extractLoc = extractLoc.Replace("\"", "").Replace("\\", "\\\\");
-                        }
-
-                        string postExCmdLine = options.PostExtractCommandLine;
-                        if (postExCmdLine != null)
-                        {
-                            postExCmdLine = postExCmdLine.Replace("\\", "\\\\");
-                            postExCmdLine = postExCmdLine.Replace("\"", "\\\"");
-                        }
-
-
-                        foreach (string rc in settings.ResourcesToCompile)
-                        {
-                            using (Stream s = zip[rc].OpenReader())
-                            {
-                                if (s == null)
-                                    throw new ZipException(String.Format("missing resource '{0}'", rc));
-                                using (StreamReader sr = new StreamReader(s))
-                                {
-                                    while (sr.Peek() >= 0)
-                                    {
-                                        string line = sr.ReadLine();
-                                        if (extractLoc != null)
-                                            line = line.Replace("@@EXTRACTLOCATION", extractLoc);
-
-                                        line = line.Replace("@@REMOVE_AFTER_EXECUTE", options.RemoveUnpackedFilesAfterExecute.ToString());
-                                        line = line.Replace("@@QUIET", options.Quiet.ToString());
-                                        if (!String.IsNullOrEmpty(options.SfxExeWindowTitle))
-
-                                            line = line.Replace("@@SFX_EXE_WINDOW_TITLE", options.SfxExeWindowTitle);
-
-                                        line = line.Replace("@@EXTRACT_EXISTING_FILE", ((int)options.ExtractExistingFile).ToString());
-
-                                        if (postExCmdLine != null)
-                                            line = line.Replace("@@POST_UNPACK_CMD_LINE", postExCmdLine);
-
-                                        sb.Append(line).Append("\n");
-                                    }
-                                }
-                                sb.Append("\n\n");
-                            }
-                        }
-                    }
-
-                    string LiteralSource = sb.ToString();
-
-#if DEBUGSFX
-                    // for debugging only
-                    string sourceModule = GenerateTempPathname(tmpDir, "cs");
-                    using (StreamWriter sw = File.CreateText(sourceModule))
-                    {
-                        sw.Write(LiteralSource);
-                    }
-                    Console.WriteLine("source: {0}", sourceModule);
-#endif
-
-                    var cr = csharp.CompileAssemblyFromSource(cp, LiteralSource);
-
-
-                    if (cr == null)
-                        throw new SfxGenerationException("Cannot compile the extraction logic!");
-
-                    if (Verbose)
-                        foreach (string output in cr.Output)
-                            StatusMessageTextWriter.WriteLine(output);
-
-                    if (cr.Errors.Count != 0)
-                    {
-                        using (TextWriter tw = new StreamWriter(sourceFile))
-                        {
-                            // first, the source we compiled
-                            tw.Write(LiteralSource);
-
-                            // now, append the compile errors
-                            tw.Write("\n\n\n// ------------------------------------------------------------------\n");
-                            tw.Write("// Errors during compilation: \n//\n");
-                            string p = Path.GetFileName(sourceFile);
-
-                            foreach (System.CodeDom.Compiler.CompilerError error in cr.Errors)
-                            {
-                                tw.Write(String.Format("//   {0}({1},{2}): {3} {4}: {5}\n//\n",
-                                                       p,                                   // 0
-                                                       error.Line,                          // 1
-                                                       error.Column,                        // 2
-                                                       error.IsWarning ? "Warning" : "error",   // 3
-                                                       error.ErrorNumber,                   // 4
-                                                       error.ErrorText));                  // 5
-                            }
-                        }
-                        throw new SfxGenerationException(String.Format("Errors compiling the extraction logic!  {0}", sourceFile));
-                    }
-
-                    OnSaveEvent(ZipProgressEventType.Saving_AfterCompileSelfExtractor);
-
-                    // Now, copy the resulting EXE image to the _writestream.
-                    // Because this stub exe is being saved first, the effect will be to
-                    // concatenate the exe and the zip data together.
-                    using (System.IO.Stream input = System.IO.File.OpenRead(stubExe))
-                    {
-                        byte[] buffer = new byte[4000];
-                        int n = 1;
-                        while (n != 0)
-                        {
-                            n = input.Read(buffer, 0, buffer.Length);
-                            if (n != 0)
-                                WriteStream.Write(buffer, 0, n);
-                        }
-                    }
-                }
-
-                OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive);
-            }
-            finally
-            {
-                try
-                {
-                    if (Directory.Exists(unpackedResourceDir))
-                    {
-                        try { Directory.Delete(unpackedResourceDir, true); }
-                        catch (System.IO.IOException exc1)
-                        {
-                            StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1);
-                        }
-                    }
-                    if (File.Exists(stubExe))
-                    {
-                        try { File.Delete(stubExe); }
-                        catch (System.IO.IOException exc1)
-                        {
-                            StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1);
-                        }
-                    }
-                }
-                catch (System.IO.IOException) { }
-            }
-
-            return;
-
-        }
-
-
-
-        internal static string GenerateTempPathname(string dir, string extension)
-        {
-            string candidate = null;
-            String AppName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
-            do
-            {
-                // workitem 13475
-                string uuid = System.Guid.NewGuid().ToString();
-
-                string Name = String.Format("{0}-{1}-{2}.{3}",
-                        AppName, System.DateTime.Now.ToString("yyyyMMMdd-HHmmss"),
-                                            uuid, extension);
-                candidate = System.IO.Path.Combine(dir, Name);
-            } while (System.IO.File.Exists(candidate) || System.IO.Directory.Exists(candidate));
-
-            // The candidate path does not exist as a file or directory.
-            // It can now be created, as a file or directory.
-            return candidate;
-        }
-
-    }
-#endif
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.Selector.cs b/EPPlus/Packaging/DotNetZip/ZipFile.Selector.cs
deleted file mode 100644
index 3023f77..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.Selector.cs
+++ /dev/null
@@ -1,1466 +0,0 @@
-// ZipFile.Selector.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2010 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-August-06 09:35:58>
-//
-// ------------------------------------------------------------------
-//
-// This module defines methods in the ZipFile class associated to the FileFilter
-// capability - selecting files to add into the archive, or selecting entries to
-// retrieve from the archive based on criteria including the filename, size, date, or
-// attributes.  It is something like a "poor man's LINQ".  I included it into DotNetZip
-// because not everyone has .NET 3.5 yet.  When using DotNetZip on .NET 3.5, the LINQ
-// query/selection will be superior.
-//
-// These methods are segregated into a different module to facilitate easy exclusion for
-// those people who wish to have a smaller library without this function.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using OfficeOpenXml.Packaging.Ionic.Zip;
-using System.Globalization;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    partial class ZipFile
-    {
-        /// <summary>
-        ///   Adds to the ZipFile a set of files from the current working directory on
-        ///   disk, that conform to the specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method selects files from the the current working directory matching
-        ///   the specified criteria, and adds them to the ZipFile.
-        /// </para>
-        ///
-        /// <para>
-        ///   Specify the criteria in statements of 3 elements: a noun, an operator, and
-        ///   a value.  Consider the string "name != *.doc" .  The noun is "name".  The
-        ///   operator is "!=", implying "Not Equal".  The value is "*.doc".  That
-        ///   criterion, in English, says "all files with a name that does not end in
-        ///   the .doc extension."
-        /// </para>
-        ///
-        /// <para>
-        ///   Supported nouns include "name" (or "filename") for the filename; "atime",
-        ///   "mtime", and "ctime" for last access time, last modfied time, and created
-        ///   time of the file, respectively; "attributes" (or "attrs") for the file
-        ///   attributes; "size" (or "length") for the file length (uncompressed), and
-        ///   "type" for the type of object, either a file or a directory.  The
-        ///   "attributes", "name" and "type" nouns both support = and != as operators.
-        ///   The "size", "atime", "mtime", and "ctime" nouns support = and !=, and
-        ///   &gt;, &gt;=, &lt;, &lt;= as well. The times are taken to be expressed in
-        ///   local time.
-        /// </para>
-        ///
-        /// <para>
-        /// Specify values for the file attributes as a string with one or more of the
-        /// characters H,R,S,A,I,L in any order, implying file attributes of Hidden,
-        /// ReadOnly, System, Archive, NotContextIndexed, and ReparsePoint (symbolic
-        /// link) respectively.
-        /// </para>
-        ///
-        /// <para>
-        /// To specify a time, use YYYY-MM-DD-HH:mm:ss or YYYY/MM/DD-HH:mm:ss as the
-        /// format.  If you omit the HH:mm:ss portion, it is assumed to be 00:00:00
-        /// (midnight).
-        /// </para>
-        ///
-        /// <para>
-        /// The value for a size criterion is expressed in integer quantities of bytes,
-        /// kilobytes (use k or kb after the number), megabytes (m or mb), or gigabytes
-        /// (g or gb).
-        /// </para>
-        ///
-        /// <para>
-        /// The value for a name is a pattern to match against the filename, potentially
-        /// including wildcards.  The pattern follows CMD.exe glob rules: * implies one
-        /// or more of any character, while ?  implies one character.  If the name
-        /// pattern contains any slashes, it is matched to the entire filename,
-        /// including the path; otherwise, it is matched against only the filename
-        /// without the path.  This means a pattern of "*\*.*" matches all files one
-        /// directory level deep, while a pattern of "*.*" matches all files in all
-        /// directories.
-        /// </para>
-        ///
-        /// <para>
-        /// To specify a name pattern that includes spaces, use single quotes around the
-        /// pattern.  A pattern of "'* *.*'" will match all files that have spaces in
-        /// the filename.  The full criteria string for that would be "name = '* *.*'" .
-        /// </para>
-        ///
-        /// <para>
-        /// The value for a type criterion is either F (implying a file) or D (implying
-        /// a directory).
-        /// </para>
-        ///
-        /// <para>
-        /// Some examples:
-        /// </para>
-        ///
-        /// <list type="table">
-        ///   <listheader>
-        ///     <term>criteria</term>
-        ///     <description>Files retrieved</description>
-        ///   </listheader>
-        ///
-        ///   <item>
-        ///     <term>name != *.xls </term>
-        ///     <description>any file with an extension that is not .xls
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>name = *.mp3 </term>
-        ///     <description>any file with a .mp3 extension.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>*.mp3</term>
-        ///     <description>(same as above) any file with a .mp3 extension.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>attributes = A </term>
-        ///     <description>all files whose attributes include the Archive bit.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>attributes != H </term>
-        ///     <description>all files whose attributes do not include the Hidden bit.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>mtime > 2009-01-01</term>
-        ///     <description>all files with a last modified time after January 1st, 2009.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>size > 2gb</term>
-        ///     <description>all files whose uncompressed size is greater than 2gb.
-        ///     </description>
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <term>type = D</term>
-        ///     <description>all directories in the filesystem. </description>
-        ///   </item>
-        ///
-        /// </list>
-        ///
-        /// <para>
-        /// You can combine criteria with the conjunctions AND or OR. Using a string
-        /// like "name = *.txt AND size &gt;= 100k" for the selectionCriteria retrieves
-        /// entries whose names end in .txt, and whose uncompressed size is greater than
-        /// or equal to 100 kilobytes.
-        /// </para>
-        ///
-        /// <para>
-        /// For more complex combinations of criteria, you can use parenthesis to group
-        /// clauses in the boolean logic.  Without parenthesis, the precedence of the
-        /// criterion atoms is determined by order of appearance.  Unlike the C#
-        /// language, the AND conjunction does not take precendence over the logical OR.
-        /// This is important only in strings that contain 3 or more criterion atoms.
-        /// In other words, "name = *.txt and size &gt; 1000 or attributes = H" implies
-        /// "((name = *.txt AND size &gt; 1000) OR attributes = H)" while "attributes =
-        /// H OR name = *.txt and size &gt; 1000" evaluates to "((attributes = H OR name
-        /// = *.txt) AND size &gt; 1000)".  When in doubt, use parenthesis.
-        /// </para>
-        ///
-        /// <para>
-        /// Using time properties requires some extra care. If you want to retrieve all
-        /// entries that were last updated on 2009 February 14, specify a time range
-        /// like so:"mtime &gt;= 2009-02-14 AND mtime &lt; 2009-02-15".  Read this to
-        /// say: all files updated after 12:00am on February 14th, until 12:00am on
-        /// February 15th.  You can use the same bracketing approach to specify any time
-        /// period - a year, a month, a week, and so on.
-        /// </para>
-        ///
-        /// <para>
-        /// The syntax allows one special case: if you provide a string with no spaces, it is
-        /// treated as a pattern to match for the filename.  Therefore a string like "*.xls"
-        /// will be equivalent to specifying "name = *.xls".
-        /// </para>
-        ///
-        /// <para>
-        /// There is no logic in this method that insures that the file inclusion
-        /// criteria are internally consistent.  For example, it's possible to specify
-        /// criteria that says the file must have a size of less than 100 bytes, as well
-        /// as a size that is greater than 1000 bytes. Obviously no file will ever
-        /// satisfy such criteria, but this method does not detect such logical
-        /// inconsistencies. The caller is responsible for insuring the criteria are
-        /// sensible.
-        /// </para>
-        ///
-        /// <para>
-        ///   Using this method, the file selection does not recurse into
-        ///   subdirectories, and the full path of the selected files is included in the
-        ///   entries added into the zip archive.  If you don't like these behaviors,
-        ///   see the other overloads of this method.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example zips up all *.csv files in the current working directory.
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     // To just match on filename wildcards,
-        ///     // use the shorthand form of the selectionCriteria string.
-        ///     zip.AddSelectedFiles("*.csv");
-        ///     zip.Save(PathToZipArchive);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = New ZipFile()
-        ///     zip.AddSelectedFiles("*.csv")
-        ///     zip.Save(PathToZipArchive)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">The criteria for file selection</param>
-        public void AddSelectedFiles(String selectionCriteria)
-        {
-            this.AddSelectedFiles(selectionCriteria, ".", null, false);
-        }
-
-        /// <summary>
-        ///   Adds to the ZipFile a set of files from the disk that conform to the
-        ///   specified criteria, optionally recursing into subdirectories.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method selects files from the the current working directory matching
-        ///   the specified criteria, and adds them to the ZipFile.  If
-        ///   <c>recurseDirectories</c> is true, files are also selected from
-        ///   subdirectories, and the directory structure in the filesystem is
-        ///   reproduced in the zip archive, rooted at the current working directory.
-        /// </para>
-        ///
-        /// <para>
-        ///   Using this method, the full path of the selected files is included in the
-        ///   entries added into the zip archive.  If you don't want this behavior, use
-        ///   one of the overloads of this method that allows the specification of a
-        ///   <c>directoryInArchive</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   For details on the syntax for the selectionCriteria parameter, see <see
-        ///   cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example zips up all *.xml files in the current working directory, or any
-        ///   subdirectory, that are larger than 1mb.
-        ///
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     // Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.xml  and  size > 1024kb", true);
-        ///     zip.Save(PathToZipArchive);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = New ZipFile()
-        ///     ' Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.xml  and  size > 1024kb", true)
-        ///     zip.Save(PathToZipArchive)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">The criteria for file selection</param>
-        ///
-        /// <param name="recurseDirectories">
-        ///   If true, the file selection will recurse into subdirectories.
-        /// </param>
-        public void AddSelectedFiles(String selectionCriteria, bool recurseDirectories)
-        {
-            this.AddSelectedFiles(selectionCriteria, ".", null, recurseDirectories);
-        }
-
-        /// <summary>
-        ///   Adds to the ZipFile a set of files from a specified directory in the
-        ///   filesystem, that conform to the specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method selects files that conform to the specified criteria, from the
-        ///   the specified directory on disk, and adds them to the ZipFile.  The search
-        ///   does not recurse into subdirectores.
-        /// </para>
-        ///
-        /// <para>
-        ///   Using this method, the full filesystem path of the files on disk is
-        ///   reproduced on the entries added to the zip file.  If you don't want this
-        ///   behavior, use one of the other overloads of this method.
-        /// </para>
-        ///
-        /// <para>
-        ///   For details on the syntax for the selectionCriteria parameter, see <see
-        ///   cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example zips up all *.xml files larger than 1mb in the directory
-        ///   given by "d:\rawdata".
-        ///
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     // Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.xml  and  size > 1024kb", "d:\\rawdata");
-        ///     zip.Save(PathToZipArchive);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As ZipFile = New ZipFile()
-        ///     ' Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.xml  and  size > 1024kb", "d:\rawdata)
-        ///     zip.Save(PathToZipArchive)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">The criteria for file selection</param>
-        ///
-        /// <param name="directoryOnDisk">
-        /// The name of the directory on the disk from which to select files.
-        /// </param>
-        public void AddSelectedFiles(String selectionCriteria, String directoryOnDisk)
-        {
-            this.AddSelectedFiles(selectionCriteria, directoryOnDisk, null, false);
-        }
-
-
-        /// <summary>
-        ///   Adds to the ZipFile a set of files from the specified directory on disk,
-        ///   that conform to the specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This method selects files from the the specified disk directory matching
-        ///   the specified selection criteria, and adds them to the ZipFile.  If
-        ///   <c>recurseDirectories</c> is true, files are also selected from
-        ///   subdirectories.
-        /// </para>
-        ///
-        /// <para>
-        ///   The full directory structure in the filesystem is reproduced on the
-        ///   entries added to the zip archive.  If you don't want this behavior, use
-        ///   one of the overloads of this method that allows the specification of a
-        ///   <c>directoryInArchive</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   For details on the syntax for the selectionCriteria parameter, see <see
-        ///   cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example zips up all *.csv files in the "files" directory, or any
-        ///   subdirectory, that have been saved since 2009 February 14th.
-        ///
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     // Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.csv  and  mtime > 2009-02-14", "files", true);
-        ///     zip.Save(PathToZipArchive);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = New ZipFile()
-        ///     ' Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.csv  and  mtime > 2009-02-14", "files", true)
-        ///     zip.Save(PathToZipArchive)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        ///   This example zips up all files in the current working
-        ///   directory, and all its child directories, except those in
-        ///   the <c>excludethis</c> subdirectory.
-        /// <code lang="VB">
-        /// Using Zip As ZipFile = New ZipFile(zipfile)
-        ///   Zip.AddSelectedFfiles("name != 'excludethis\*.*'", datapath, True)
-        ///   Zip.Save()
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">The criteria for file selection</param>
-        ///
-        /// <param name="directoryOnDisk">
-        ///   The filesystem path from which to select files.
-        /// </param>
-        ///
-        /// <param name="recurseDirectories">
-        ///   If true, the file selection will recurse into subdirectories.
-        /// </param>
-        public void AddSelectedFiles(String selectionCriteria, String directoryOnDisk, bool recurseDirectories)
-        {
-            this.AddSelectedFiles(selectionCriteria, directoryOnDisk, null, recurseDirectories);
-        }
-
-
-        /// <summary>
-        ///   Adds to the ZipFile a selection of files from the specified directory on
-        ///   disk, that conform to the specified criteria, and using a specified root
-        ///   path for entries added to the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method selects files from the specified disk directory matching the
-        ///   specified selection criteria, and adds those files to the ZipFile, using
-        ///   the specified directory path in the archive.  The search does not recurse
-        ///   into subdirectories.  For details on the syntax for the selectionCriteria
-        ///   parameter, see <see cref="AddSelectedFiles(String)" />.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example zips up all *.psd files in the "photos" directory that have
-        ///   been saved since 2009 February 14th, and puts them all in a zip file,
-        ///   using the directory name of "content" in the zip archive itself. When the
-        ///   zip archive is unzipped, the folder containing the .psd files will be
-        ///   named "content".
-        ///
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     // Use a compound expression in the selectionCriteria string.
-        ///     zip.AddSelectedFiles("name = *.psd  and  mtime > 2009-02-14", "photos", "content");
-        ///     zip.Save(PathToZipArchive);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = New ZipFile
-        ///     zip.AddSelectedFiles("name = *.psd  and  mtime > 2009-02-14", "photos", "content")
-        ///     zip.Save(PathToZipArchive)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">
-        ///   The criteria for selection of files to add to the <c>ZipFile</c>.
-        /// </param>
-        ///
-        /// <param name="directoryOnDisk">
-        ///   The path to the directory in the filesystem from which to select files.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to in place of the
-        ///   <c>directoryOnDisk</c>.  This path may, or may not, correspond to a real
-        ///   directory in the current filesystem.  If the files within the zip are
-        ///   later extracted, this is the path used for the extracted file.  Passing
-        ///   null (nothing in VB) will use the path on the file name, if any; in other
-        ///   words it would use <c>directoryOnDisk</c>, plus any subdirectory.  Passing
-        ///   the empty string ("") will insert the item at the root path within the
-        ///   archive.
-        /// </param>
-        public void AddSelectedFiles(String selectionCriteria,
-                                     String directoryOnDisk,
-                                     String directoryPathInArchive)
-        {
-            this.AddSelectedFiles(selectionCriteria, directoryOnDisk, directoryPathInArchive, false);
-        }
-
-        /// <summary>
-        ///   Adds to the ZipFile a selection of files from the specified directory on
-        ///   disk, that conform to the specified criteria, optionally recursing through
-        ///   subdirectories, and using a specified root path for entries added to the
-        ///   zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This method selects files from the specified disk directory that match the
-        ///   specified selection criteria, and adds those files to the ZipFile, using
-        ///   the specified directory path in the archive. If <c>recurseDirectories</c>
-        ///   is true, files are also selected from subdirectories, and the directory
-        ///   structure in the filesystem is reproduced in the zip archive, rooted at
-        ///   the directory specified by <c>directoryOnDisk</c>.  For details on the
-        ///   syntax for the selectionCriteria parameter, see <see
-        ///   cref="AddSelectedFiles(String)" />.
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example zips up all files that are NOT *.pst files, in the current
-        ///   working directory and any subdirectories.
-        ///
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.AddSelectedFiles("name != *.pst", SourceDirectory, "backup", true);
-        ///     zip.Save(PathToZipArchive);
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = New ZipFile
-        ///     zip.AddSelectedFiles("name != *.pst", SourceDirectory, "backup", true)
-        ///     zip.Save(PathToZipArchive)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">
-        ///   The criteria for selection of files to add to the <c>ZipFile</c>.
-        /// </param>
-        ///
-        /// <param name="directoryOnDisk">
-        ///   The path to the directory in the filesystem from which to select files.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to in place of the
-        ///   <c>directoryOnDisk</c>.  This path may, or may not, correspond to a real
-        ///   directory in the current filesystem.  If the files within the zip are
-        ///   later extracted, this is the path used for the extracted file.  Passing
-        ///   null (nothing in VB) will use the path on the file name, if any; in other
-        ///   words it would use <c>directoryOnDisk</c>, plus any subdirectory.  Passing
-        ///   the empty string ("") will insert the item at the root path within the
-        ///   archive.
-        /// </param>
-        ///
-        /// <param name="recurseDirectories">
-        ///   If true, the method also scans subdirectories for files matching the
-        ///   criteria.
-        /// </param>
-        public void AddSelectedFiles(String selectionCriteria,
-                                     String directoryOnDisk,
-                                     String directoryPathInArchive,
-                                     bool recurseDirectories)
-        {
-            _AddOrUpdateSelectedFiles(selectionCriteria,
-                                      directoryOnDisk,
-                                      directoryPathInArchive,
-                                      recurseDirectories,
-                                      false);
-        }
-
-        /// <summary>
-        ///   Updates the ZipFile with a selection of files from the disk that conform
-        ///   to the specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This method selects files from the specified disk directory that match the
-        ///   specified selection criteria, and Updates the <c>ZipFile</c> with those
-        ///   files, using the specified directory path in the archive. If
-        ///   <c>recurseDirectories</c> is true, files are also selected from
-        ///   subdirectories, and the directory structure in the filesystem is
-        ///   reproduced in the zip archive, rooted at the directory specified by
-        ///   <c>directoryOnDisk</c>.  For details on the syntax for the
-        ///   selectionCriteria parameter, see <see cref="AddSelectedFiles(String)" />.
-        /// </remarks>
-        ///
-        /// <param name="selectionCriteria">
-        ///   The criteria for selection of files to add to the <c>ZipFile</c>.
-        /// </param>
-        ///
-        /// <param name="directoryOnDisk">
-        ///   The path to the directory in the filesystem from which to select files.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        ///   Specifies a directory path to use to in place of the
-        ///   <c>directoryOnDisk</c>. This path may, or may not, correspond to a
-        ///   real directory in the current filesystem. If the files within the zip
-        ///   are later extracted, this is the path used for the extracted file.
-        ///   Passing null (nothing in VB) will use the path on the file name, if
-        ///   any; in other words it would use <c>directoryOnDisk</c>, plus any
-        ///   subdirectory.  Passing the empty string ("") will insert the item at
-        ///   the root path within the archive.
-        /// </param>
-        ///
-        /// <param name="recurseDirectories">
-        ///   If true, the method also scans subdirectories for files matching the criteria.
-        /// </param>
-        ///
-        /// <seealso cref="AddSelectedFiles(String, String, String, bool)" />
-        public void UpdateSelectedFiles(String selectionCriteria,
-                                     String directoryOnDisk,
-                                     String directoryPathInArchive,
-                                     bool recurseDirectories)
-        {
-            _AddOrUpdateSelectedFiles(selectionCriteria,
-                                      directoryOnDisk,
-                                      directoryPathInArchive,
-                                      recurseDirectories,
-                                      true);
-        }
-
-
-        private string EnsureendInSlash(string s)
-        {
-            if (s.EndsWith("\\")) return s;
-            return s + "\\";
-        }
-
-        private void _AddOrUpdateSelectedFiles(String selectionCriteria,
-                                               String directoryOnDisk,
-                                               String directoryPathInArchive,
-                                               bool recurseDirectories,
-                                               bool wantUpdate)
-        {
-            if (directoryOnDisk == null && (Directory.Exists(selectionCriteria)))
-            {
-                directoryOnDisk = selectionCriteria;
-                selectionCriteria = "*.*";
-            }
-            else if (String.IsNullOrEmpty(directoryOnDisk))
-            {
-                directoryOnDisk = ".";
-            }
-
-            // workitem 9176
-            while (directoryOnDisk.EndsWith("\\")) directoryOnDisk = directoryOnDisk.Substring(0, directoryOnDisk.Length - 1);
-            if (Verbose) StatusMessageTextWriter.WriteLine("adding selection '{0}' from dir '{1}'...",
-                                                               selectionCriteria, directoryOnDisk);
-            Ionic.FileSelector ff = new Ionic.FileSelector(selectionCriteria,
-                                                           AddDirectoryWillTraverseReparsePoints);
-            var itemsToAdd = ff.SelectFiles(directoryOnDisk, recurseDirectories);
-
-            if (Verbose) StatusMessageTextWriter.WriteLine("found {0} files...", itemsToAdd.Count);
-
-            OnAddStarted();
-
-            AddOrUpdateAction action = (wantUpdate) ? AddOrUpdateAction.AddOrUpdate : AddOrUpdateAction.AddOnly;
-            foreach (var item in itemsToAdd)
-            {
-                // workitem 10153
-                string dirInArchive = (directoryPathInArchive == null)
-                    ? null
-                    // workitem 12260
-                    : ReplaceLeadingDirectory(Path.GetDirectoryName(item),
-                                              directoryOnDisk,
-                                              directoryPathInArchive);
-
-                if (File.Exists(item))
-                {
-                    if (wantUpdate)
-                        this.UpdateFile(item, dirInArchive);
-                    else
-                        this.AddFile(item, dirInArchive);
-                }
-                else
-                {
-                    // this adds "just" the directory, without recursing to the contained files
-                    AddOrUpdateDirectoryImpl(item, dirInArchive, action, false, 0);
-                }
-            }
-
-            OnAddCompleted();
-        }
-
-
-        // workitem 12260
-        private static string ReplaceLeadingDirectory(string original,
-                                                      string pattern,
-                                                      string replacement)
-        {
-            string upperString = original.ToUpper(CultureInfo.InvariantCulture);
-            string upperPattern = pattern.ToUpper(CultureInfo.InvariantCulture);
-            int p1 = upperString.IndexOf(upperPattern);
-            if (p1 != 0) return original;
-            return replacement + original.Substring(upperPattern.Length);
-        }
-
-#if NOT
-        private static string ReplaceEx(string original,
-                                                      string pattern,
-                                                      string replacement)
-        {
-            int count, position0, position1;
-            count = position0 = position1 = 0;
-            string upperString = original.ToUpper();
-            string upperPattern = pattern.ToUpper();
-            int inc = (original.Length/pattern.Length) *
-                (replacement.Length-pattern.Length);
-            char [] chars = new char[original.Length + Math.Max(0, inc)];
-            while( (position1 = upperString.IndexOf(upperPattern,
-                                                    position0)) != -1 )
-            {
-                for ( int i=position0 ; i < position1 ; ++i )
-                    chars[count++] = original[i];
-                for ( int i=0 ; i < replacement.Length ; ++i )
-                    chars[count++] = replacement[i];
-                position0 = position1+pattern.Length;
-            }
-            if ( position0 == 0 ) return original;
-            for ( int i=position0 ; i < original.Length ; ++i )
-                chars[count++] = original[i];
-            return new string(chars, 0, count);
-        }
-#endif
-
-        /// <summary>
-        /// Retrieve entries from the zipfile by specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// This method allows callers to retrieve the collection of entries from the zipfile
-        /// that fit the specified criteria.  The criteria are described in a string format, and
-        /// can include patterns for the filename; constraints on the size of the entry;
-        /// constraints on the last modified, created, or last accessed time for the file
-        /// described by the entry; or the attributes of the entry.
-        /// </para>
-        ///
-        /// <para>
-        /// For details on the syntax for the selectionCriteria parameter, see <see
-        /// cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        ///
-        /// <para>
-        /// This method is intended for use with a ZipFile that has been read from storage.
-        /// When creating a new ZipFile, this method will work only after the ZipArchive has
-        /// been Saved to the disk (the ZipFile class subsequently and implicitly reads the Zip
-        /// archive from storage.)  Calling SelectEntries on a ZipFile that has not yet been
-        /// saved will deliver undefined results.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.Exception">
-        /// Thrown if selectionCriteria has an invalid syntax.
-        /// </exception>
-        ///
-        /// <example>
-        /// This example selects all the PhotoShop files from within an archive, and extracts them
-        /// to the current working directory.
-        /// <code>
-        /// using (ZipFile zip1 = ZipFile.Read(ZipFileName))
-        /// {
-        ///     var PhotoShopFiles = zip1.SelectEntries("*.psd");
-        ///     foreach (ZipEntry psd in PhotoShopFiles)
-        ///     {
-        ///         psd.Extract();
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip1 As ZipFile = ZipFile.Read(ZipFileName)
-        ///     Dim PhotoShopFiles as ICollection(Of ZipEntry)
-        ///     PhotoShopFiles = zip1.SelectEntries("*.psd")
-        ///     Dim psd As ZipEntry
-        ///     For Each psd In PhotoShopFiles
-        ///         psd.Extract
-        ///     Next
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="selectionCriteria">the string that specifies which entries to select</param>
-        /// <returns>a collection of ZipEntry objects that conform to the inclusion spec</returns>
-        public ICollection<ZipEntry> SelectEntries(String selectionCriteria)
-        {
-            Ionic.FileSelector ff = new Ionic.FileSelector(selectionCriteria,
-                                                           AddDirectoryWillTraverseReparsePoints);
-            return ff.SelectEntries(this);
-        }
-
-
-        /// <summary>
-        /// Retrieve entries from the zipfile by specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// This method allows callers to retrieve the collection of entries from the zipfile
-        /// that fit the specified criteria.  The criteria are described in a string format, and
-        /// can include patterns for the filename; constraints on the size of the entry;
-        /// constraints on the last modified, created, or last accessed time for the file
-        /// described by the entry; or the attributes of the entry.
-        /// </para>
-        ///
-        /// <para>
-        /// For details on the syntax for the selectionCriteria parameter, see <see
-        /// cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        ///
-        /// <para>
-        /// This method is intended for use with a ZipFile that has been read from storage.
-        /// When creating a new ZipFile, this method will work only after the ZipArchive has
-        /// been Saved to the disk (the ZipFile class subsequently and implicitly reads the Zip
-        /// archive from storage.)  Calling SelectEntries on a ZipFile that has not yet been
-        /// saved will deliver undefined results.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.Exception">
-        /// Thrown if selectionCriteria has an invalid syntax.
-        /// </exception>
-        ///
-        /// <example>
-        /// <code>
-        /// using (ZipFile zip1 = ZipFile.Read(ZipFileName))
-        /// {
-        ///     var UpdatedPhotoShopFiles = zip1.SelectEntries("*.psd", "UpdatedFiles");
-        ///     foreach (ZipEntry e in UpdatedPhotoShopFiles)
-        ///     {
-        ///         // prompt for extract here
-        ///         if (WantExtract(e.FileName))
-        ///             e.Extract();
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip1 As ZipFile = ZipFile.Read(ZipFileName)
-        ///     Dim UpdatedPhotoShopFiles As ICollection(Of ZipEntry) = zip1.SelectEntries("*.psd", "UpdatedFiles")
-        ///     Dim e As ZipEntry
-        ///     For Each e In UpdatedPhotoShopFiles
-        ///         ' prompt for extract here
-        ///         If Me.WantExtract(e.FileName) Then
-        ///             e.Extract
-        ///         End If
-        ///     Next
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="selectionCriteria">the string that specifies which entries to select</param>
-        ///
-        /// <param name="directoryPathInArchive">
-        /// the directory in the archive from which to select entries. If null, then
-        /// all directories in the archive are used.
-        /// </param>
-        ///
-        /// <returns>a collection of ZipEntry objects that conform to the inclusion spec</returns>
-        public ICollection<ZipEntry> SelectEntries(String selectionCriteria, string directoryPathInArchive)
-        {
-            Ionic.FileSelector ff = new Ionic.FileSelector(selectionCriteria,
-                                                           AddDirectoryWillTraverseReparsePoints);
-            return ff.SelectEntries(this, directoryPathInArchive);
-        }
-
-
-
-        /// <summary>
-        /// Remove entries from the zipfile by specified criteria.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// This method allows callers to remove the collection of entries from the zipfile
-        /// that fit the specified criteria.  The criteria are described in a string format, and
-        /// can include patterns for the filename; constraints on the size of the entry;
-        /// constraints on the last modified, created, or last accessed time for the file
-        /// described by the entry; or the attributes of the entry.
-        /// </para>
-        ///
-        /// <para>
-        /// For details on the syntax for the selectionCriteria parameter, see <see
-        /// cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        ///
-        /// <para>
-        /// This method is intended for use with a ZipFile that has been read from storage.
-        /// When creating a new ZipFile, this method will work only after the ZipArchive has
-        /// been Saved to the disk (the ZipFile class subsequently and implicitly reads the Zip
-        /// archive from storage.)  Calling SelectEntries on a ZipFile that has not yet been
-        /// saved will deliver undefined results.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.Exception">
-        /// Thrown if selectionCriteria has an invalid syntax.
-        /// </exception>
-        ///
-        /// <example>
-        /// This example removes all entries in a zip file that were modified prior to January 1st, 2008.
-        /// <code>
-        /// using (ZipFile zip1 = ZipFile.Read(ZipFileName))
-        /// {
-        ///     // remove all entries from prior to Jan 1, 2008
-        ///     zip1.RemoveEntries("mtime &lt; 2008-01-01");
-        ///     // don't forget to save the archive!
-        ///     zip1.Save();
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read(ZipFileName)
-        ///     ' remove all entries from prior to Jan 1, 2008
-        ///     zip1.RemoveEntries("mtime &lt; 2008-01-01")
-        ///     ' do not forget to save the archive!
-        ///     zip1.Save
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="selectionCriteria">the string that specifies which entries to select</param>
-        /// <returns>the number of entries removed</returns>
-        public int RemoveSelectedEntries(String selectionCriteria)
-        {
-            var selection = this.SelectEntries(selectionCriteria);
-            this.RemoveEntries(selection);
-            return selection.Count;
-        }
-
-
-        /// <summary>
-        /// Remove entries from the zipfile by specified criteria, and within the specified
-        /// path in the archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// This method allows callers to remove the collection of entries from the zipfile
-        /// that fit the specified criteria.  The criteria are described in a string format, and
-        /// can include patterns for the filename; constraints on the size of the entry;
-        /// constraints on the last modified, created, or last accessed time for the file
-        /// described by the entry; or the attributes of the entry.
-        /// </para>
-        ///
-        /// <para>
-        /// For details on the syntax for the selectionCriteria parameter, see <see
-        /// cref="AddSelectedFiles(String)"/>.
-        /// </para>
-        ///
-        /// <para>
-        /// This method is intended for use with a ZipFile that has been read from storage.
-        /// When creating a new ZipFile, this method will work only after the ZipArchive has
-        /// been Saved to the disk (the ZipFile class subsequently and implicitly reads the Zip
-        /// archive from storage.)  Calling SelectEntries on a ZipFile that has not yet been
-        /// saved will deliver undefined results.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.Exception">
-        /// Thrown if selectionCriteria has an invalid syntax.
-        /// </exception>
-        ///
-        /// <example>
-        /// <code>
-        /// using (ZipFile zip1 = ZipFile.Read(ZipFileName))
-        /// {
-        ///     // remove all entries from prior to Jan 1, 2008
-        ///     zip1.RemoveEntries("mtime &lt; 2008-01-01", "documents");
-        ///     // a call to ZipFile.Save will make the modifications permanent
-        ///     zip1.Save();
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read(ZipFileName)
-        ///     ' remove all entries from prior to Jan 1, 2008
-        ///     zip1.RemoveEntries("mtime &lt; 2008-01-01", "documents")
-        ///     ' a call to ZipFile.Save will make the modifications permanent
-        ///     zip1.Save
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">the string that specifies which entries to select</param>
-        /// <param name="directoryPathInArchive">
-        /// the directory in the archive from which to select entries. If null, then
-        /// all directories in the archive are used.
-        /// </param>
-        /// <returns>the number of entries removed</returns>
-        public int RemoveSelectedEntries(String selectionCriteria, string directoryPathInArchive)
-        {
-            var selection = this.SelectEntries(selectionCriteria, directoryPathInArchive);
-            this.RemoveEntries(selection);
-            return selection.Count;
-        }
-
-
-        /// <summary>
-        /// Selects and Extracts a set of Entries from the ZipFile.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// The entries are extracted into the current working directory.
-        /// </para>
-        ///
-        /// <para>
-        /// If any of the files to be extracted already exist, then the action taken is as
-        /// specified in the <see cref="ZipEntry.ExtractExistingFile"/> property on the
-        /// corresponding ZipEntry instance.  By default, the action taken in this case is to
-        /// throw an exception.
-        /// </para>
-        ///
-        /// <para>
-        /// For information on the syntax of the selectionCriteria string,
-        /// see <see cref="AddSelectedFiles(String)" />.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example shows how extract all XML files modified after 15 January 2009.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(zipArchiveName))
-        /// {
-        ///   zip.ExtractSelectedEntries("name = *.xml  and  mtime &gt; 2009-01-15");
-        /// }
-        /// </code>
-        /// </example>
-        /// <param name="selectionCriteria">the selection criteria for entries to extract.</param>
-        ///
-        /// <seealso cref="ExtractSelectedEntries(String,ExtractExistingFileAction)"/>
-        public void ExtractSelectedEntries(String selectionCriteria)
-        {
-            foreach (ZipEntry e in SelectEntries(selectionCriteria))
-            {
-                e.Password = _Password; // possibly null
-                e.Extract();
-            }
-        }
-
-
-        /// <summary>
-        /// Selects and Extracts a set of Entries from the ZipFile.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// The entries are extracted into the current working directory. When extraction would would
-        /// overwrite an existing filesystem file, the action taken is as specified in the
-        /// <paramref name="extractExistingFile"/> parameter.
-        /// </para>
-        ///
-        /// <para>
-        /// For information on the syntax of the string describing the entry selection criteria,
-        /// see <see cref="AddSelectedFiles(String)" />.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example shows how extract all XML files modified after 15 January 2009,
-        /// overwriting any existing files.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(zipArchiveName))
-        /// {
-        ///   zip.ExtractSelectedEntries("name = *.xml  and  mtime &gt; 2009-01-15",
-        ///                              ExtractExistingFileAction.OverwriteSilently);
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">the selection criteria for entries to extract.</param>
-        ///
-        /// <param name="extractExistingFile">
-        /// The action to take if extraction would overwrite an existing file.
-        /// </param>
-        internal void ExtractSelectedEntries(String selectionCriteria, ExtractExistingFileAction extractExistingFile)
-        {
-            foreach (ZipEntry e in SelectEntries(selectionCriteria))
-            {
-                e.Password = _Password; // possibly null
-                e.Extract(extractExistingFile);
-            }
-        }
-
-
-        /// <summary>
-        /// Selects and Extracts a set of Entries from the ZipFile.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// The entries are selected from the specified directory within the archive, and then
-        /// extracted into the current working directory.
-        /// </para>
-        ///
-        /// <para>
-        /// If any of the files to be extracted already exist, then the action taken is as
-        /// specified in the <see cref="ZipEntry.ExtractExistingFile"/> property on the
-        /// corresponding ZipEntry instance.  By default, the action taken in this case is to
-        /// throw an exception.
-        /// </para>
-        ///
-        /// <para>
-        /// For information on the syntax of the string describing the entry selection criteria,
-        /// see <see cref="AddSelectedFiles(String)" />.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example shows how extract all XML files modified after 15 January 2009,
-        /// and writes them to the "unpack" directory.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(zipArchiveName))
-        /// {
-        ///   zip.ExtractSelectedEntries("name = *.xml  and  mtime &gt; 2009-01-15","unpack");
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">the selection criteria for entries to extract.</param>
-        ///
-        /// <param name="directoryPathInArchive">
-        /// the directory in the archive from which to select entries. If null, then
-        /// all directories in the archive are used.
-        /// </param>
-        ///
-        /// <seealso cref="ExtractSelectedEntries(String,String,String,ExtractExistingFileAction)"/>
-        public void ExtractSelectedEntries(String selectionCriteria, String directoryPathInArchive)
-        {
-            foreach (ZipEntry e in SelectEntries(selectionCriteria, directoryPathInArchive))
-            {
-                e.Password = _Password; // possibly null
-                e.Extract();
-            }
-        }
-
-
-        /// <summary>
-        /// Selects and Extracts a set of Entries from the ZipFile.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// The entries are extracted into the specified directory. If any of the files to be
-        /// extracted already exist, an exception will be thrown.
-        /// </para>
-        /// <para>
-        /// For information on the syntax of the string describing the entry selection criteria,
-        /// see <see cref="AddSelectedFiles(String)" />.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="selectionCriteria">the selection criteria for entries to extract.</param>
-        ///
-        /// <param name="directoryInArchive">
-        /// the directory in the archive from which to select entries. If null, then
-        /// all directories in the archive are used.
-        /// </param>
-        ///
-        /// <param name="extractDirectory">
-        /// the directory on the disk into which to extract. It will be created
-        /// if it does not exist.
-        /// </param>
-        public void ExtractSelectedEntries(String selectionCriteria, string directoryInArchive, string extractDirectory)
-        {
-            foreach (ZipEntry e in SelectEntries(selectionCriteria, directoryInArchive))
-            {
-                e.Password = _Password; // possibly null
-                e.Extract(extractDirectory);
-            }
-        }
-
-
-        /// <summary>
-        /// Selects and Extracts a set of Entries from the ZipFile.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        /// The entries are extracted into the specified directory. When extraction would would
-        /// overwrite an existing filesystem file, the action taken is as specified in the
-        /// <paramref name="extractExistingFile"/> parameter.
-        /// </para>
-        ///
-        /// <para>
-        /// For information on the syntax of the string describing the entry selection criteria,
-        /// see <see cref="AddSelectedFiles(String)" />.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example shows how extract all files  with an XML extension or with  a size larger than 100,000 bytes,
-        /// and puts them in the unpack directory.  For any files that already exist in
-        /// that destination directory, they will not be overwritten.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(zipArchiveName))
-        /// {
-        ///   zip.ExtractSelectedEntries("name = *.xml  or  size &gt; 100000",
-        ///                              null,
-        ///                              "unpack",
-        ///                              ExtractExistingFileAction.DontOverwrite);
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="selectionCriteria">the selection criteria for entries to extract.</param>
-        ///
-        /// <param name="extractDirectory">
-        /// The directory on the disk into which to extract. It will be created if it does not exist.
-        /// </param>
-        ///
-        /// <param name="directoryPathInArchive">
-        /// The directory in the archive from which to select entries. If null, then
-        /// all directories in the archive are used.
-        /// </param>
-        ///
-        /// <param name="extractExistingFile">
-        /// The action to take if extraction would overwrite an existing file.
-        /// </param>
-        ///
-        internal void ExtractSelectedEntries(String selectionCriteria, string directoryPathInArchive, string extractDirectory, ExtractExistingFileAction extractExistingFile)
-        {
-            foreach (ZipEntry e in SelectEntries(selectionCriteria, directoryPathInArchive))
-            {
-                e.Password = _Password; // possibly null
-                e.Extract(extractDirectory, extractExistingFile);
-            }
-        }
-
-    }
-
-}
-
-
-
-namespace OfficeOpenXml.Packaging.Ionic
-{
-    internal abstract partial class SelectionCriterion
-    {
-        internal abstract bool Evaluate(ZipEntry entry);
-    }
-
-
-    internal partial class NameCriterion : SelectionCriterion
-    {
-        internal override bool Evaluate(ZipEntry entry)
-        {
-            // swap forward slashes in the entry.FileName for backslashes
-            string transformedFileName = entry.FileName.Replace("/", "\\");
-
-            return _Evaluate(transformedFileName);
-        }
-    }
-
-
-    internal partial class SizeCriterion : SelectionCriterion
-    {
-        internal override bool Evaluate(ZipEntry entry)
-        {
-            return _Evaluate(entry.UncompressedSize);
-        }
-    }
-
-    internal partial class TimeCriterion : SelectionCriterion
-    {
-        internal override bool Evaluate(ZipEntry entry)
-        {
-            DateTime x;
-            switch (Which)
-            {
-                case WhichTime.atime:
-                    x = entry.AccessedTime;
-                    break;
-                case WhichTime.mtime:
-                    x = entry.ModifiedTime;
-                    break;
-                case WhichTime.ctime:
-                    x = entry.CreationTime;
-                    break;
-                default: throw new ArgumentException("??time");
-            }
-            return _Evaluate(x);
-        }
-    }
-
-
-    internal partial class TypeCriterion : SelectionCriterion
-    {
-        internal override bool Evaluate(ZipEntry entry)
-        {
-            bool result = (ObjectType == 'D')
-                ? entry.IsDirectory
-                : !entry.IsDirectory;
-
-            if (Operator != ComparisonOperator.EqualTo)
-                result = !result;
-            return result;
-        }
-    }
-
-#if !SILVERLIGHT
-    internal partial class AttributesCriterion : SelectionCriterion
-    {
-        internal override bool Evaluate(ZipEntry entry)
-        {
-            FileAttributes fileAttrs = entry.Attributes;
-            return _Evaluate(fileAttrs);
-        }
-    }
-#endif
-
-    internal partial class CompoundCriterion : SelectionCriterion
-    {
-        internal override bool Evaluate(ZipEntry entry)
-        {
-            bool result = Left.Evaluate(entry);
-            switch (Conjunction)
-            {
-                case LogicalConjunction.AND:
-                    if (result)
-                        result = Right.Evaluate(entry);
-                    break;
-                case LogicalConjunction.OR:
-                    if (!result)
-                        result = Right.Evaluate(entry);
-                    break;
-                case LogicalConjunction.XOR:
-                    result ^= Right.Evaluate(entry);
-                    break;
-            }
-            return result;
-        }
-    }
-
-
-
-    internal partial class FileSelector
-    {
-        private bool Evaluate(ZipEntry entry)
-        {
-            bool result = _Criterion.Evaluate(entry);
-            return result;
-        }
-
-        /// <summary>
-        /// Retrieve the ZipEntry items in the ZipFile that conform to the specified criteria.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        /// This method applies the criteria set in the FileSelector instance (as described in
-        /// the <see cref="FileSelector.SelectionCriteria"/>) to the specified ZipFile.  Using this
-        /// method, for example, you can retrieve all entries from the given ZipFile that
-        /// have filenames ending in .txt.
-        /// </para>
-        ///
-        /// <para>
-        /// Normally, applications would not call this method directly.  This method is used
-        /// by the ZipFile class.
-        /// </para>
-        ///
-        /// <para>
-        /// Using the appropriate SelectionCriteria, you can retrieve entries based on size,
-        /// time, and attributes. See <see cref="FileSelector.SelectionCriteria"/> for a
-        /// description of the syntax of the SelectionCriteria string.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="zip">The ZipFile from which to retrieve entries.</param>
-        ///
-        /// <returns>a collection of ZipEntry objects that conform to the criteria.</returns>
-        public ICollection<ZipEntry> SelectEntries(ZipFile zip)
-        {
-            if (zip == null)
-                throw new ArgumentNullException("zip");
-
-            var list = new List<ZipEntry>();
-
-            foreach (ZipEntry e in zip)
-            {
-                if (this.Evaluate(e))
-                    list.Add(e);
-            }
-
-            return list;
-        }
-
-
-        /// <summary>
-        /// Retrieve the ZipEntry items in the ZipFile that conform to the specified criteria.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        /// This method applies the criteria set in the FileSelector instance (as described in
-        /// the <see cref="FileSelector.SelectionCriteria"/>) to the specified ZipFile.  Using this
-        /// method, for example, you can retrieve all entries from the given ZipFile that
-        /// have filenames ending in .txt.
-        /// </para>
-        ///
-        /// <para>
-        /// Normally, applications would not call this method directly.  This method is used
-        /// by the ZipFile class.
-        /// </para>
-        ///
-        /// <para>
-        /// This overload allows the selection of ZipEntry instances from the ZipFile to be restricted
-        /// to entries contained within a particular directory in the ZipFile.
-        /// </para>
-        ///
-        /// <para>
-        /// Using the appropriate SelectionCriteria, you can retrieve entries based on size,
-        /// time, and attributes. See <see cref="FileSelector.SelectionCriteria"/> for a
-        /// description of the syntax of the SelectionCriteria string.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="zip">The ZipFile from which to retrieve entries.</param>
-        ///
-        /// <param name="directoryPathInArchive">
-        /// the directory in the archive from which to select entries. If null, then
-        /// all directories in the archive are used.
-        /// </param>
-        ///
-        /// <returns>a collection of ZipEntry objects that conform to the criteria.</returns>
-        public ICollection<ZipEntry> SelectEntries(ZipFile zip, string directoryPathInArchive)
-        {
-            if (zip == null)
-                throw new ArgumentNullException("zip");
-
-            var list = new List<ZipEntry>();
-            // workitem 8559
-            string slashSwapped = (directoryPathInArchive == null) ? null : directoryPathInArchive.Replace("/", "\\");
-            // workitem 9174
-            if (slashSwapped != null)
-            {
-                while (slashSwapped.EndsWith("\\"))
-                    slashSwapped = slashSwapped.Substring(0, slashSwapped.Length - 1);
-            }
-            foreach (ZipEntry e in zip)
-            {
-                if (directoryPathInArchive == null || (Path.GetDirectoryName(e.FileName) == directoryPathInArchive)
-                    || (Path.GetDirectoryName(e.FileName) == slashSwapped)) // workitem 8559
-                    if (this.Evaluate(e))
-                        list.Add(e);
-            }
-
-            return list;
-        }
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.cs b/EPPlus/Packaging/DotNetZip/ZipFile.cs
deleted file mode 100644
index 7edaff5..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.cs
+++ /dev/null
@@ -1,3909 +0,0 @@
-// ZipFile.cs
-//
-// Copyright (c) 2006-2010 Dino Chiesa
-// All rights reserved.
-//
-// This module is part of DotNetZip, a zipfile class library.
-// The class library reads and writes zip files, according to the format
-// described by PKware, at:
-// http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
-//
-//
-// There are other Zip class libraries available.
-//
-// - it is possible to read and write zip files within .NET via the J# runtime.
-//   But some people don't like to install the extra DLL, which is no longer
-//   supported by MS. And also, the J# libraries don't support advanced zip
-//   features, like ZIP64, spanned archives, or AES encryption.
-//
-// - There are third-party GPL and LGPL libraries available. Some people don't
-//   like the license, and some of them don't support all the ZIP features, like AES.
-//
-// - Finally, there are commercial tools (From ComponentOne, XCeed, etc).  But
-//   some people don't want to incur the cost.
-//
-// This alternative implementation is **not** GPL licensed. It is free of cost, and
-// does not require J#. It does require .NET 2.0.  It balances a good set of
-// features, with ease of use and speed of performance.
-//
-// This code is released under the Microsoft Public License .
-// See the License.txt for details.
-//
-//
-// NB: This implementation originally relied on the
-// System.IO.Compression.DeflateStream base class in the .NET Framework
-// v2.0 base class library, but now includes a managed-code port of Zlib.
-//
-// Thu, 08 Oct 2009  17:04
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using Interop = System.Runtime.InteropServices;
-using OfficeOpenXml.Packaging.Ionic.Zlib;
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    /// <summary>
-    ///   The ZipFile type represents a zip archive file.
-    /// </summary>
-    ///
-    /// <remarks>
-    /// <para>
-    ///   This is the main type in the DotNetZip class library. This class reads and
-    ///   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 a general purpose zip file capability.  Use it to read,
-    ///   create, or update zip files.  When you want to create zip files using a
-    ///   <c>Stream</c> type to write the zip file, you may want to consider the <see
-    ///   cref="ZipOutputStream"/> class.
-    /// </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 methods and 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 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>ZipFile</c> class implements the <see
-    ///   cref="System.IDisposable"/> interface.  In order for <c>ZipFile</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>
-    ///
-    /// </remarks>
-    [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00005")]
-    [Interop.ComVisible(true)]
-#if !NETCF
-    [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
-#endif
-    internal partial class ZipFile :
-    System.Collections.IEnumerable,
-    System.Collections.Generic.IEnumerable<ZipEntry>,
-    IDisposable
-    {
-
-        #region public properties
-
-        /// <summary>
-        /// Indicates whether to perform a full scan of the zip file when reading it.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   You almost never want to use this property.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading a zip file, if this flag is <c>true</c> (<c>True</c> in
-        ///   VB), the entire zip archive will be scanned and searched for entries.
-        ///   For large archives, this can take a very, long time. The much more
-        ///   efficient default behavior is to read the zip directory, which is
-        ///   stored at the end of the zip file. But, in some cases the directory is
-        ///   corrupted and you need to perform a full scan of the zip file to
-        ///   determine the contents of the zip file. This property lets you do
-        ///   that, when necessary.
-        /// </para>
-        ///
-        /// <para>
-        ///   This flag is effective only when calling <see
-        ///   cref="Initialize(string)"/>. Normally you would read a ZipFile with the
-        ///   static <see cref="ZipFile.Read(String)">ZipFile.Read</see>
-        ///   method. But you can't set the <c>FullScan</c> property on the
-        ///   <c>ZipFile</c> instance when you use a static factory method like
-        ///   <c>ZipFile.Read</c>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example shows how to read a zip file using the full scan approach,
-        ///   and then save it, thereby producing a corrected zip file.
-        ///
-        /// <code lang="C#">
-        /// using (var zip = new ZipFile())
-        /// {
-        ///     zip.FullScan = true;
-        ///     zip.Initialize(zipFileName);
-        ///     zip.Save(newName);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     zip.FullScan = True
-        ///     zip.Initialize(zipFileName)
-        ///     zip.Save(newName)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        public bool FullScan
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   Whether to sort the ZipEntries before saving the file.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   The default is false.  If you have a large number of zip entries, the sort
-        ///   alone can consume significant time.
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code lang="C#">
-        /// using (var zip = new ZipFile())
-        /// {
-        ///     zip.AddFiles(filesToAdd);
-        ///     zip.SortEntriesBeforeSaving = true;
-        ///     zip.Save(name);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     zip.AddFiles(filesToAdd)
-        ///     zip.SortEntriesBeforeSaving = True
-        ///     zip.Save(name)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        public bool SortEntriesBeforeSaving
-        {
-            get;
-            set;
-        }
-
-
-
-        /// <summary>
-        ///   Indicates whether NTFS Reparse Points, like junctions, should be
-        ///   traversed during calls to <c>AddDirectory()</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   By default, calls to AddDirectory() will traverse NTFS reparse
-        ///   points, like mounted volumes, and directory junctions.  An example
-        ///   of a junction is the "My Music" directory in Windows Vista.  In some
-        ///   cases you may not want DotNetZip to traverse those directories.  In
-        ///   that case, set this property to false.
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code lang="C#">
-        /// using (var zip = new ZipFile())
-        /// {
-        ///     zip.AddDirectoryWillTraverseReparsePoints = false;
-        ///     zip.AddDirectory(dirToZip,"fodder");
-        ///     zip.Save(zipFileToCreate);
-        /// }
-        /// </code>
-        /// </example>
-        public bool AddDirectoryWillTraverseReparsePoints { get; set; }
-
-
-        /// <summary>
-        ///   Size of the IO buffer used while saving.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   First, let me say that you really don't need to bother with this.  It is
-        ///   here to allow for optimizations that you probably won't make! It will work
-        ///   fine if you don't set or get this property at all. Ok?
-        /// </para>
-        ///
-        /// <para>
-        ///   Now that we have <em>that</em> out of the way, the fine print: This
-        ///   property affects the size of the buffer that is used for I/O for each
-        ///   entry contained in the zip file. When a file is read in to be compressed,
-        ///   it uses a buffer given by the size here.  When you update a zip file, the
-        ///   data for unmodified entries is copied from the first zip file to the
-        ///   other, through a buffer given by the size here.
-        /// </para>
-        ///
-        /// <para>
-        ///   Changing the buffer size affects a few things: first, for larger buffer
-        ///   sizes, the memory used by the <c>ZipFile</c>, obviously, will be larger
-        ///   during I/O operations.  This may make operations faster for very much
-        ///   larger files.  Last, for any given entry, when you use a larger buffer
-        ///   there will be fewer progress events during I/O operations, because there's
-        ///   one progress event generated for each time the buffer is filled and then
-        ///   emptied.
-        /// </para>
-        ///
-        /// <para>
-        ///   The default buffer size is 8k.  Increasing the buffer size may speed
-        ///   things up as you compress larger files.  But there are no hard-and-fast
-        ///   rules here, eh?  You won't know til you test it.  And there will be a
-        ///   limit where ever larger buffers actually slow things down.  So as I said
-        ///   in the beginning, it's probably best if you don't set or get this property
-        ///   at all.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example shows how you might set a large buffer size for efficiency when
-        /// dealing with zip entries that are larger than 1gb.
-        /// <code lang="C#">
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.SaveProgress += this.zip1_SaveProgress;
-        ///     zip.AddDirectory(directoryToZip, "");
-        ///     zip.UseZip64WhenSaving = Zip64Option.Always;
-        ///     zip.BufferSize = 65536*8; // 65536 * 8 = 512k
-        ///     zip.Save(ZipFileToCreate);
-        /// }
-        /// </code>
-        /// </example>
-
-        public int BufferSize
-        {
-            get { return _BufferSize; }
-            set { _BufferSize = value; }
-        }
-
-        /// <summary>
-        ///   Size of the work buffer to use for the ZLIB codec during compression.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     When doing ZLIB or Deflate compression, the library fills a buffer,
-        ///     then passes it to the compressor for compression. Then the library
-        ///     reads out the compressed bytes. This happens repeatedly until there
-        ///     is no more uncompressed data to compress. This property sets the
-        ///     size of the buffer that will be used for chunk-wise compression. In
-        ///     order for the setting to take effect, your application needs to set
-        ///     this property before calling one of the <c>ZipFile.Save()</c>
-        ///     overloads.
-        ///   </para>
-        ///   <para>
-        ///     Setting this affects the performance and memory efficiency of
-        ///     compression and decompression. For larger files, setting this to a
-        ///     larger size may improve compression performance, but the exact
-        ///     numbers vary depending on available memory, the size of the streams
-        ///     you are compressing, and a bunch of other variables. I don't have
-        ///     good firm recommendations on how to set it.  You'll have to test it
-        ///     yourself. Or just leave it alone and accept the default.
-        ///   </para>
-        /// </remarks>
-        public int CodecBufferSize
-        {
-            get;
-            set;
-        }
-
-        /// <summary>
-        ///   Indicates whether extracted files should keep their paths as
-        ///   stored in the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///  <para>
-        ///    This property affects Extraction.  It is not used when creating zip
-        ///    archives.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    With this property set to <c>false</c>, the default, extracting entries
-        ///    from a zip file will create files in the filesystem that have the full
-        ///    path associated to the entry within the zip file.  With this property set
-        ///    to <c>true</c>, extracting entries from the zip file results in files
-        ///    with no path: the folders are "flattened."
-        ///  </para>
-        ///
-        ///  <para>
-        ///    An example: suppose the zip file contains entries /directory1/file1.txt and
-        ///    /directory2/file2.txt.  With <c>FlattenFoldersOnExtract</c> set to false,
-        ///    the files created will be \directory1\file1.txt and \directory2\file2.txt.
-        ///    With the property set to true, the files created are file1.txt and file2.txt.
-        ///  </para>
-        ///
-        /// </remarks>
-        public bool FlattenFoldersOnExtract
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   The compression strategy to use for all entries.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Set the Strategy used by the ZLIB-compatible compressor, when
-        ///   compressing entries using the DEFLATE method. 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">Ionic.Zlib.CompressionStrategy</see>.
-        /// </remarks>
-        public CompressionStrategy Strategy
-        {
-            get { return _Strategy; }
-            set { _Strategy = value; }
-        }
-
-
-        /// <summary>
-        ///   The name of the <c>ZipFile</c>, on disk.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When the <c>ZipFile</c> instance was created by reading an archive using
-        ///   one of the <c>ZipFile.Read</c> methods, this property represents the name
-        ///   of the zip file that was read.  When the <c>ZipFile</c> instance was
-        ///   created by using the no-argument constructor, this value is <c>null</c>
-        ///   (<c>Nothing</c> in VB).
-        /// </para>
-        ///
-        /// <para>
-        ///   If you use the no-argument constructor, and you then explicitly set this
-        ///   property, when you call <see cref="ZipFile.Save()"/>, this name will
-        ///   specify the name of the zip file created.  Doing so is equivalent to
-        ///   calling <see cref="ZipFile.Save(String)"/>.  When instantiating a
-        ///   <c>ZipFile</c> by reading from a stream or byte array, the <c>Name</c>
-        ///   property remains <c>null</c>.  When saving to a stream, the <c>Name</c>
-        ///   property is implicitly set to <c>null</c>.
-        /// </para>
-        /// </remarks>
-        public string Name
-        {
-            get { return _name; }
-            set { _name = 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>ZipFile</c> class, like <see
-        ///    cref="Password"/>, <see cref="Encryption"/>, and <see
-        ///    cref="ZipErrorAction"/>, setting this property on a <c>ZipFile</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>ZipFile</c> instance. If you set this property after you have added
-        ///    items to the <c>ZipFile</c>, but before you have called <c>Save()</c>,
-        ///    those items will not use the specified compression level.
-        ///  </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 for the zipfile.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     By default, the compression method is <c>CompressionMethod.Deflate.</c>
-        ///   </para>
-        /// </remarks>
-        /// <seealso cref="Ionic.Zip.CompressionMethod" />
-        internal Ionic.Zip.CompressionMethod CompressionMethod
-        {
-            get
-            {
-                return _compressionMethod;
-            }
-            set
-            {
-                _compressionMethod = value;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   A comment attached to the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This property is read/write. It allows the application to specify a
-        ///   comment for the <c>ZipFile</c>, or read the comment for the
-        ///   <c>ZipFile</c>.  After setting this property, changes are only made
-        ///   permanent when you call a <c>Save()</c> method.
-        /// </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>
-        ///
-        /// <para>
-        ///   When creating a zip archive using this library, it is possible to change
-        ///   the value of <see cref="AlternateEncoding" /> between each
-        ///   entry you add, and between adding entries and the call to
-        ///   <c>Save()</c>. Don't do this.  It will likely result in a zip file that is
-        ///   not readable by any tool or application.  For best interoperability, leave
-        ///   <see cref="AlternateEncoding"/> alone, or specify it only
-        ///   once, before adding any entries to the <c>ZipFile</c> instance.
-        /// </para>
-        ///
-        /// </remarks>
-        public string Comment
-        {
-            get { return _Comment; }
-            set
-            {
-                _Comment = value;
-                _contentsChanged = true;
-            }
-        }
-
-
-
-
-        /// <summary>
-        ///   Specifies whether the Creation, Access, and Modified times for entries
-        ///   added to the zip file will be emitted in &#147;Windows format&#148;
-        ///   when the zip archive is saved.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   An application creating a zip archive can use this flag to explicitly
-        ///   specify that the file times for the entries should or should not be stored
-        ///   in the zip archive in the format used by Windows. By default this flag is
-        ///   <c>true</c>, meaning the Windows-format times are stored in the zip
-        ///   archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   When adding an entry from a file or directory, the Creation (<see
-        ///   cref="ZipEntry.CreationTime"/>), Access (<see
-        ///   cref="ZipEntry.AccessedTime"/>), and Modified (<see
-        ///   cref="ZipEntry.ModifiedTime"/>) times for the given entry are
-        ///   automatically set from the filesystem values. When adding an entry from a
-        ///   stream or string, all three values are implicitly set to
-        ///   <c>DateTime.Now</c>.  Applications can also explicitly set those times by
-        ///   calling <see cref="ZipEntry.SetEntryTimes(DateTime, DateTime,
-        ///   DateTime)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
-        ///   zip specification</see> describes multiple ways to format these times in a
-        ///   zip file. One is the format Windows applications normally use: 100ns ticks
-        ///   since January 1, 1601 UTC.  The other is a format Unix applications typically
-        ///   use: seconds since January 1, 1970 UTC.  Each format can be stored in an
-        ///   "extra field" in the zip entry when saving the zip archive. The former
-        ///   uses an extra field with a Header Id of 0x000A, while the latter uses a
-        ///   header ID of 0x5455, although you probably don't need to know that.
-        /// </para>
-        ///
-        /// <para>
-        ///   Not all tools and libraries can interpret these fields.  Windows
-        ///   compressed folders is one that can read the Windows Format timestamps,
-        ///   while I believe <see href="http://www.info-zip.org/">the Infozip
-        ///   tools</see> can read the Unix format timestamps. Some tools and libraries
-        ///   may be able to read only one or the other. DotNetZip can read or write
-        ///   times in either or both formats.
-        /// </para>
-        ///
-        /// <para>
-        ///   The times stored are taken from <see cref="ZipEntry.ModifiedTime"/>, <see
-        ///   cref="ZipEntry.AccessedTime"/>, and <see cref="ZipEntry.CreationTime"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   The value set here applies to all entries subsequently added to the
-        ///   <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is not mutually exclusive of the <see
-        ///   cref="EmitTimesInUnixFormatWhenSaving" /> property. It is possible and
-        ///   legal and valid to produce a zip file that contains timestamps encoded in
-        ///   the Unix format as well as in the Windows format, in addition to the <see
-        ///   cref="ZipEntry.LastModified">LastModified</see> time attached to each
-        ///   entry in the archive, a time that is always stored in "DOS format". And,
-        ///   notwithstanding the names PKWare uses for these time formats, any of them
-        ///   can be read and written by any computer, on any operating system.  But,
-        ///   there are no guarantees that a program running on Mac or Linux will
-        ///   gracefully handle a zip file with "Windows" formatted times, or that an
-        ///   application that does not use DotNetZip but runs on Windows will be able to
-        ///   handle file times in Unix format.
-        /// </para>
-        ///
-        /// <para>
-        ///   When in doubt, test.  Sorry, I haven't got a complete list of tools and
-        ///   which sort of timestamps they can use and will tolerate.  If you get any
-        ///   good information and would like to pass it on, please do so and I will
-        ///   include that information in this documentation.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example shows how to save a zip file that contains file timestamps
-        ///   in a format normally used by Unix.
-        /// <code lang="C#">
-        /// using (var zip = new ZipFile())
-        /// {
-        ///     // produce a zip file the Mac will like
-        ///     zip.EmitTimesInWindowsFormatWhenSaving = false;
-        ///     zip.EmitTimesInUnixFormatWhenSaving = true;
-        ///     zip.AddDirectory(directoryToZip, "files");
-        ///     zip.Save(outputFile);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     '' produce a zip file the Mac will like
-        ///     zip.EmitTimesInWindowsFormatWhenSaving = False
-        ///     zip.EmitTimesInUnixFormatWhenSaving = True
-        ///     zip.AddDirectory(directoryToZip, "files")
-        ///     zip.Save(outputFile)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="ZipEntry.EmitTimesInWindowsFormatWhenSaving" />
-        /// <seealso cref="EmitTimesInUnixFormatWhenSaving" />
-        public bool EmitTimesInWindowsFormatWhenSaving
-        {
-            get
-            {
-                return _emitNtfsTimes;
-            }
-            set
-            {
-                _emitNtfsTimes = value;
-            }
-        }
-
-
-        /// <summary>
-        /// Specifies whether the Creation, Access, and Modified times
-        /// for entries added to the zip file will be emitted in "Unix(tm)
-        /// format" when the zip archive is saved.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   An application creating a zip archive can use this flag to explicitly
-        ///   specify that the file times for the entries should or should not be stored
-        ///   in the zip archive in the format used by Unix. By default this flag is
-        ///   <c>false</c>, meaning the Unix-format times are not stored in the zip
-        ///   archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   When adding an entry from a file or directory, the Creation (<see
-        ///   cref="ZipEntry.CreationTime"/>), Access (<see
-        ///   cref="ZipEntry.AccessedTime"/>), and Modified (<see
-        ///   cref="ZipEntry.ModifiedTime"/>) times for the given entry are
-        ///   automatically set from the filesystem values. When adding an entry from a
-        ///   stream or string, all three values are implicitly set to DateTime.Now.
-        ///   Applications can also explicitly set those times by calling <see
-        ///   cref="ZipEntry.SetEntryTimes(DateTime, DateTime, DateTime)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   <see
-        ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
-        ///   zip specification</see> describes multiple ways to format these times in a
-        ///   zip file. One is the format Windows applications normally use: 100ns ticks
-        ///   since January 1, 1601 UTC.  The other is a format Unix applications
-        ///   typically use: seconds since January 1, 1970 UTC.  Each format can be
-        ///   stored in an "extra field" in the zip entry when saving the zip
-        ///   archive. The former uses an extra field with a Header Id of 0x000A, while
-        ///   the latter uses a header ID of 0x5455, although you probably don't need to
-        ///   know that.
-        /// </para>
-        ///
-        /// <para>
-        ///   Not all tools and libraries can interpret these fields.  Windows
-        ///   compressed folders is one that can read the Windows Format timestamps,
-        ///   while I believe the <see href="http://www.info-zip.org/">Infozip</see>
-        ///   tools can read the Unix format timestamps. Some tools and libraries may be
-        ///   able to read only one or the other.  DotNetZip can read or write times in
-        ///   either or both formats.
-        /// </para>
-        ///
-        /// <para>
-        ///   The times stored are taken from <see cref="ZipEntry.ModifiedTime"/>, <see
-        ///   cref="ZipEntry.AccessedTime"/>, and <see cref="ZipEntry.CreationTime"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is not mutually exclusive of the <see
-        ///   cref="EmitTimesInWindowsFormatWhenSaving" /> property. It is possible and
-        ///   legal and valid to produce a zip file that contains timestamps encoded in
-        ///   the Unix format as well as in the Windows format, in addition to the <see
-        ///   cref="ZipEntry.LastModified">LastModified</see> time attached to each
-        ///   entry in the zip archive, a time that is always stored in "DOS
-        ///   format". And, notwithstanding the names PKWare uses for these time
-        ///   formats, any of them can be read and written by any computer, on any
-        ///   operating system.  But, there are no guarantees that a program running on
-        ///   Mac or Linux will gracefully handle a zip file with "Windows" formatted
-        ///   times, or that an application that does not use DotNetZip but runs on
-        ///   Windows will be able to handle file times in Unix format.
-        /// </para>
-        ///
-        /// <para>
-        ///   When in doubt, test.  Sorry, I haven't got a complete list of tools and
-        ///   which sort of timestamps they can use and will tolerate.  If you get any
-        ///   good information and would like to pass it on, please do so and I will
-        ///   include that information in this documentation.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="ZipEntry.EmitTimesInUnixFormatWhenSaving" />
-        /// <seealso cref="EmitTimesInWindowsFormatWhenSaving" />
-        public bool EmitTimesInUnixFormatWhenSaving
-        {
-            get
-            {
-                return _emitUnixTimes;
-            }
-            set
-            {
-                _emitUnixTimes = value;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Indicates whether verbose output is sent to the <see
-        ///   cref="StatusMessageTextWriter"/> during <c>AddXxx()</c> and
-        ///   <c>ReadXxx()</c> operations.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This is a <em>synthetic</em> property.  It returns true if the <see
-        ///   cref="StatusMessageTextWriter"/> is non-null.
-        /// </remarks>
-        internal bool Verbose
-        {
-            get { return (_StatusMessageTextWriter != null); }
-        }
-
-
-        /// <summary>
-        ///   Returns true if an entry by the given name exists in the ZipFile.
-        /// </summary>
-        ///
-        /// <param name='name'>the name of the entry to find</param>
-        /// <returns>true if an entry with the given name exists; otherwise false.
-        /// </returns>
-        public bool ContainsEntry(string name)
-        {
-            // workitem 12534
-            return _entries.ContainsKey(SharedUtilities.NormalizePathForUseInZipFile(name));
-        }
-
-
-
-        /// <summary>
-        ///   Indicates whether to perform case-sensitive matching on the filename when
-        ///   retrieving entries in the zipfile via the string-based indexer.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   The default value is <c>false</c>, which means don't do case-sensitive
-        ///   matching. In other words, retrieving zip["ReadMe.Txt"] is the same as
-        ///   zip["readme.txt"].  It really makes sense to set this to <c>true</c> only
-        ///   if you are not running on Windows, which has case-insensitive
-        ///   filenames. But since this library is not built for non-Windows platforms,
-        ///   in most cases you should just leave this property alone.
-        /// </remarks>
-        public bool CaseSensitiveRetrieval
-        {
-            get
-            {
-                return _CaseSensitiveRetrieval;
-            }
-
-            set
-            {
-                // workitem 9868
-                if (value != _CaseSensitiveRetrieval)
-                {
-                    _CaseSensitiveRetrieval = value;
-                    _initEntriesDictionary();
-                }
-            }
-        }
-
-
-        /// <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,
-        ///   your <c>ZipFile</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>ZipFile</c>, 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, calling Extract() on the entry that
-        ///   has question marks in the filename will result in an exception, 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. Your applications should  use AlternateEncoding and AlternateEncodingUsage instead.")]
-        public bool UseUnicodeAsNecessary
-        {
-            get
-            {
-                return (_alternateEncoding == System.Text.Encoding.GetEncoding("UTF-8")) &&
-                    (_alternateEncodingUsage == ZipOption.AsNecessary);
-            }
-            set
-            {
-                if (value)
-                {
-                    _alternateEncoding = System.Text.Encoding.GetEncoding("UTF-8");
-                    _alternateEncodingUsage = ZipOption.AsNecessary;
-
-                }
-                else
-                {
-                    _alternateEncoding = Ionic.Zip.ZipFile.DefaultEncoding;
-                    _alternateEncodingUsage = ZipOption.Never;
-                }
-            }
-        }
-
-
-        /// <summary>
-        ///   Specify whether to use ZIP64 extensions when saving a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When creating a zip file, 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 may set the property at any time before calling Save().
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading a zip file via the <c>Zipfile.Read()</c> method, DotNetZip
-        ///   will properly read ZIP64-endowed zip archives, regardless of the value of
-        ///   this property.  DotNetZip will always read ZIP64 archives.  This property
-        ///   governs only whether DotNetZip will write them. Therefore, when updating
-        ///   archives, be careful about setting this property after reading an archive
-        ///   that may use ZIP64 extensions.
-        /// </para>
-        ///
-        /// <para>
-        ///   An interesting question is, if you have set this property to
-        ///   <c>AsNecessary</c>, and then successfully saved, does the resulting
-        ///   archive use ZIP64 extensions or not?  To learn this, check the <see
-        ///   cref="OutputUsedZip64"/> property, after calling <c>Save()</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Have you thought about
-        ///   <see href="http://cheeso.members.winisp.net/DotNetZipDonate.aspx">donating</see>?
-        /// </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="RequiresZip64"/>
-        internal Zip64Option UseZip64WhenSaving
-        {
-            get
-            {
-                return _zip64;
-            }
-            set
-            {
-                _zip64 = value;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Indicates whether the archive requires ZIP64 extensions.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This property is <c>null</c> (or <c>Nothing</c> in VB) if the archive has
-        ///   not been saved, and there are fewer than 65334 <c>ZipEntry</c> items
-        ///   contained in the archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <c>Value</c> is true if any of the following four conditions holds:
-        ///   the uncompressed size of any entry is larger than 0xFFFFFFFF; the
-        ///   compressed size of any entry is larger than 0xFFFFFFFF; the relative
-        ///   offset of any entry within the zip archive is larger than 0xFFFFFFFF; or
-        ///   there are more than 65534 entries in the archive.  (0xFFFFFFFF =
-        ///   4,294,967,295).  The result may not be known until a <c>Save()</c> is attempted
-        ///   on the zip archive.  The Value of this <see cref="System.Nullable"/>
-        ///   property may be set only AFTER one of the Save() methods has been called.
-        /// </para>
-        ///
-        /// <para>
-        ///   If none of the four conditions holds, and the archive has been saved, then
-        ///   the <c>Value</c> is false.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>Value</c> of false does not indicate that the zip archive, as saved,
-        ///   does not use ZIP64.  It merely indicates that ZIP64 is not required.  An
-        ///   archive may use ZIP64 even when not required if the <see
-        ///   cref="ZipFile.UseZip64WhenSaving"/> property is set to <see
-        ///   cref="Zip64Option.Always"/>, or if the <see
-        ///   cref="ZipFile.UseZip64WhenSaving"/> property is set to <see
-        ///   cref="Zip64Option.AsNecessary"/> and the output stream was not
-        ///   seekable. Use the <see cref="OutputUsedZip64"/> property to determine if
-        ///   the most recent <c>Save()</c> method resulted in an archive that utilized
-        ///   the ZIP64 extensions.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="UseZip64WhenSaving"/>
-        /// <seealso cref="OutputUsedZip64"/>
-        public Nullable<bool> RequiresZip64
-        {
-            get
-            {
-                if (_entries.Count > 65534)
-                    return new Nullable<bool>(true);
-
-                // If the <c>ZipFile</c> has not been saved or if the contents have changed, then
-                // it is not known if ZIP64 is required.
-                if (!_hasBeenSaved || _contentsChanged) return null;
-
-                // Whether ZIP64 is required is knowable.
-                foreach (ZipEntry e in _entries.Values)
-                {
-                    if (e.RequiresZip64.Value) return new Nullable<bool>(true);
-                }
-
-                return new Nullable<bool>(false);
-            }
-        }
-
-
-        /// <summary>
-        ///   Indicates whether the most recent <c>Save()</c> operation used ZIP64 extensions.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The use of ZIP64 extensions within an archive is not always necessary, and
-        ///   for interoperability concerns, it may be desired to NOT use ZIP64 if
-        ///   possible.  The <see cref="ZipFile.UseZip64WhenSaving"/> property can be
-        ///   set to use ZIP64 extensions only when necessary.  In those cases,
-        ///   Sometimes applications want to know whether a Save() actually used ZIP64
-        ///   extensions.  Applications can query this read-only property to learn
-        ///   whether ZIP64 has been used in a just-saved <c>ZipFile</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   The value is <c>null</c> (or <c>Nothing</c> in VB) if the archive has not
-        ///   been saved.
-        /// </para>
-        ///
-        /// <para>
-        ///   Non-null values (<c>HasValue</c> is true) indicate whether ZIP64
-        ///   extensions were used during the most recent <c>Save()</c> operation.  The
-        ///   ZIP64 extensions may have been used as required by any particular entry
-        ///   because of its uncompressed or compressed size, or because the archive is
-        ///   larger than 4294967295 bytes, or because there are more than 65534 entries
-        ///   in the archive, or because the <c>UseZip64WhenSaving</c> property was set
-        ///   to <see cref="Zip64Option.Always"/>, or because the
-        ///   <c>UseZip64WhenSaving</c> property was set to <see
-        ///   cref="Zip64Option.AsNecessary"/> and the output stream was not seekable.
-        ///   The value of this property does not indicate the reason the ZIP64
-        ///   extensions were used.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <seealso cref="UseZip64WhenSaving"/>
-        /// <seealso cref="RequiresZip64"/>
-        public Nullable<bool> OutputUsedZip64
-        {
-            get
-            {
-                return _OutputUsesZip64;
-            }
-        }
-
-
-        /// <summary>
-        ///   Indicates whether the most recent <c>Read()</c> operation read a zip file that uses
-        ///   ZIP64 extensions.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   This property will return null (Nothing in VB) if you've added an entry after reading
-        ///   the zip file.
-        /// </remarks>
-        public Nullable<bool> InputUsesZip64
-        {
-            get
-            {
-                if (_entries.Count > 65534)
-                    return true;
-
-                foreach (ZipEntry e in this)
-                {
-                    // if any entry was added after reading the zip file, then the result is null
-                    if (e.Source != ZipEntrySource.ZipFile) return null;
-
-                    // if any entry read from the zip used zip64, then the result is true
-                    if (e._InputUsesZip64) return true;
-                }
-                return false;
-            }
-        }
-
-
-        /// <summary>
-        ///   The text encoding to use when writing new entries to the <c>ZipFile</c>,
-        ///   for those entries that cannot be encoded with the default (IBM437)
-        ///   encoding; or, the text encoding that was used when reading the entries
-        ///   from the <c>ZipFile</c>.
-        /// </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 <see
-        ///   cref="ProvisionalAlternateEncoding" /> 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 <see cref="ProvisionalAlternateEncoding" /> between each
-        ///   entry you add, and between adding entries and the call to
-        ///   <c>Save()</c>. Don't do this. It will likely result in a zipfile that is
-        ///   not readable.  For best interoperability, either leave <see
-        ///   cref="ProvisionalAlternateEncoding" /> alone, or specify it only once,
-        ///   before adding any entries to the <c>ZipFile</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.  In other words, if you explicitly specify the codepage when you
-        ///   create the zipfile, you must explicitly specify the same codepage when
-        ///   reading the zipfile.
-        /// </para>
-        ///
-        /// <para>
-        ///   The way you specify the code page to use when reading a zip file varies
-        ///   depending on the tool or library you use to read the zip.  In DotNetZip,
-        ///   you use a ZipFile.Read() method that accepts an encoding parameter.  It
-        ///   isn't possible with Windows Explorer, as far as I know, to specify an
-        ///   explicit codepage to use when reading a zip.  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>
-        ///   Example: Suppose you create a zipfile that contains entries with
-        ///   filenames that have Danish characters.  If you use <see
-        ///   cref="ProvisionalAlternateEncoding" /> equal to "iso-8859-1" (cp 28591),
-        ///   the filenames will be correctly encoded in the zip.  But, to read that
-        ///   zipfile correctly, you have to specify the same codepage at the time you
-        ///   read it. If try to read that zip file with Windows Explorer or another
-        ///   application that is not flexible with respect to the codepage used to
-        ///   decode filenames in zipfiles, you will get a filename like "Inf�.txt".
-        /// </para>
-        ///
-        /// <para>
-        ///   When using DotNetZip to read a zip archive, and the zip archive uses an
-        ///   arbitrary code page, you must specify the encoding to use before or when
-        ///   the <c>Zipfile</c> is READ.  This means you must use a <c>ZipFile.Read()</c>
-        ///   method that allows you to specify a System.Text.Encoding parameter.  Setting
-        ///   the ProvisionalAlternateEncoding property after your application has read in
-        ///   the zip archive will not affect the entry names of entries that have already
-        ///   been read in.
-        /// </para>
-        ///
-        /// <para>
-        ///   And now, the exception to the rule described above.  One strategy 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 reset
-        ///   <c>ProvisionalAlternateEncoding</c> to IBM437 before setting the <see
-        ///   cref="Comment"/> property and calling Save().
-        /// </para>
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example shows how to read a zip file using the Big-5 Chinese code page
-        /// (950), and extract each entry in the zip file.  For this code to work as
-        /// desired, the <c>Zipfile</c> must have been created using the big5 code page
-        /// (CP950). This is typical, for example, when using WinRar on a machine with
-        /// CP950 set as the default code page.  In that case, the names of entries
-        /// within the Zip archive will be stored in that code page, and reading the zip
-        /// archive must be done using that code page.  If the application did not use
-        /// the correct code page in <c>ZipFile.Read()</c>, then names of entries within the
-        /// zip archive would not be correctly retrieved.
-        /// <code>
-        /// using (var zip = ZipFile.Read(zipFileName, System.Text.Encoding.GetEncoding("big5")))
-        /// {
-        ///     // retrieve and extract an entry using a name encoded with CP950
-        ///     zip[MyDesiredEntry].Extract("unpack");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read(ZipToExtract, System.Text.Encoding.GetEncoding("big5"))
-        ///     ' retrieve and extract an entry using a name encoded with CP950
-        ///     zip(MyDesiredEntry).Extract("unpack")
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.DefaultEncoding">DefaultEncoding</seealso>
-        [Obsolete("use AlternateEncoding 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>
-        internal 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 _defaultEncoding;
-            }
-        }
-
-
-        /// <summary>
-        /// Gets or sets the <c>TextWriter</c> to which status messages are delivered
-        /// for the instance.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   If the TextWriter is set to a non-null value, then verbose output is sent
-        ///   to the <c>TextWriter</c> during <c>Add</c><c>, Read</c><c>, Save</c> and
-        ///   <c>Extract</c> operations.  Typically, console applications might use
-        ///   <c>Console.Out</c> and graphical or headless applications might use a
-        ///   <c>System.IO.StringWriter</c>. The output of this is suitable for viewing
-        ///   by humans.
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   In this example, a console application instantiates a <c>ZipFile</c>, then
-        ///   sets the <c>StatusMessageTextWriter</c> to <c>Console.Out</c>.  At that
-        ///   point, all verbose status messages for that <c>ZipFile</c> are sent to the
-        ///   console.
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// using (ZipFile zip= ZipFile.Read(FilePath))
-        /// {
-        ///   zip.StatusMessageTextWriter= System.Console.Out;
-        ///   // messages are sent to the console during extraction
-        ///   zip.ExtractAll();
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read(FilePath)
-        ///   zip.StatusMessageTextWriter= System.Console.Out
-        ///   'Status Messages will be sent to the console during extraction
-        ///   zip.ExtractAll()
-        /// End Using
-        /// </code>
-        ///
-        /// <para>
-        ///   In this example, a Windows Forms application instantiates a
-        ///   <c>ZipFile</c>, then sets the <c>StatusMessageTextWriter</c> to a
-        ///   <c>StringWriter</c>.  At that point, all verbose status messages for that
-        ///   <c>ZipFile</c> are sent to the <c>StringWriter</c>.
-        /// </para>
-        ///
-        /// <code lang="C#">
-        /// var sw = new System.IO.StringWriter();
-        /// using (ZipFile zip= ZipFile.Read(FilePath))
-        /// {
-        ///   zip.StatusMessageTextWriter= sw;
-        ///   zip.ExtractAll();
-        /// }
-        /// Console.WriteLine("{0}", sw.ToString());
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim sw as New System.IO.StringWriter
-        /// Using zip As ZipFile = ZipFile.Read(FilePath)
-        ///   zip.StatusMessageTextWriter= sw
-        ///   zip.ExtractAll()
-        /// End Using
-        /// 'Status Messages are now available in sw
-        ///
-        /// </code>
-        /// </example>
-        public TextWriter StatusMessageTextWriter
-        {
-            get { return _StatusMessageTextWriter; }
-            set { _StatusMessageTextWriter = value; }
-        }
-
-
-
-
-        /// <summary>
-        ///   Gets or sets the name for the folder to store the temporary file
-        ///   this library writes when saving a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This library will create a temporary file when saving a Zip archive to a
-        ///   file.  This file is written when calling one of the <c>Save()</c> methods
-        ///   that does not save to a stream, or one of the <c>SaveSelfExtractor()</c>
-        ///   methods.
-        /// </para>
-        ///
-        /// <para>
-        ///   By default, the library will create the temporary file in the directory
-        ///   specified for the file itself, via the <see cref="Name"/> property or via
-        ///   the <see cref="ZipFile.Save(String)"/> method.
-        /// </para>
-        ///
-        /// <para>
-        ///   Setting this property allows applications to override this default
-        ///   behavior, so that the library will create the temporary file in the
-        ///   specified folder. For example, to have the library create the temporary
-        ///   file in the current working directory, regardless where the <c>ZipFile</c>
-        ///   is saved, specfy ".".  To revert to the default behavior, set this
-        ///   property to <c>null</c> (<c>Nothing</c> in VB).
-        /// </para>
-        ///
-        /// <para>
-        ///   When setting the property to a non-null value, the folder specified must
-        ///   exist; if it does not an exception is thrown.  The application should have
-        ///   write and delete permissions on the folder.  The permissions are not
-        ///   explicitly checked ahead of time; if the application does not have the
-        ///   appropriate rights, an exception will be thrown at the time <c>Save()</c>
-        ///   is called.
-        /// </para>
-        ///
-        /// <para>
-        ///   There is no temporary file created when reading a zip archive.  When
-        ///   saving to a Stream, there is no temporary file created.  For example, if
-        ///   the application is an ASP.NET application and calls <c>Save()</c>
-        ///   specifying the <c>Response.OutputStream</c> as the output stream, there is
-        ///   no temporary file created.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.IO.FileNotFoundException">
-        /// Thrown when setting the property if the directory does not exist.
-        /// </exception>
-        ///
-        public String TempFileFolder
-        {
-            get { return _TempFileFolder; }
-
-            set
-            {
-                _TempFileFolder = value;
-                if (value == null) return;
-
-                if (!Directory.Exists(value))
-                    throw new FileNotFoundException(String.Format("That directory ({0}) does not exist.", value));
-
-            }
-        }
-
-        /// <summary>
-        /// Sets the password to be used on the <c>ZipFile</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
-        ///   added to the <c>ZipFile</c>, using one of the <c>AddFile</c>,
-        ///   <c>AddDirectory</c>, <c>AddEntry</c>, or <c>AddItem</c> methods, etc.
-        ///   When reading a zip archive, this property applies to any entry
-        ///   subsequently extracted from the <c>ZipFile</c> using one of the Extract
-        ///   methods on the <c>ZipFile</c> class.
-        /// </para>
-        ///
-        /// <para>
-        ///   When writing a zip archive, keep this in mind: though the password is set
-        ///   on the ZipFile object, according to the Zip spec, the "directory" of the
-        ///   archive - in other words the list of entries or files contained in the archive - is
-        ///   not encrypted with the password, or protected in any way.  If you set the
-        ///   Password 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>
-        ///   One simple way around this limitation is to simply double-wrap sensitive
-        ///   filenames: Store the files in a zip file, and then store that zip file
-        ///   within a second, "outer" zip file.  If you apply a password to the outer
-        ///   zip file, then readers will be able to see that the outer zip file
-        ///   contains an inner zip file.  But readers will not be able to read the
-        ///   directory or file list of the inner zip file.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you set the password on the <c>ZipFile</c>, and then add a set of files
-        ///   to the archive, 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.  If you call <c>AddFile()</c>, then set
-        ///   the <c>Password</c> property, then call <c>ZipFile.Save</c>, the file
-        ///   added will not be password-protected, and no warning will be generated.
-        /// </para>
-        ///
-        /// <para>
-        ///   When setting the Password, 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 Password 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), Encryption is
-        ///   reset to None.
-        /// </para>
-        ///
-        /// <para>
-        ///   All of the preceding applies to writing zip archives, in other words when
-        ///   you use one of the Save methods.  To use this property when reading or an
-        ///   existing ZipFile, do the following: set the Password property on the
-        ///   <c>ZipFile</c>, then call one of the Extract() overloads on the <see
-        ///   cref="ZipEntry" />. In this case, the entry is extracted using the
-        ///   <c>Password</c> that is specified on the <c>ZipFile</c> instance. If you
-        ///   have not set the <c>Password</c> property, then the password is
-        ///   <c>null</c>, and the entry is extracted with no password.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you set the Password property on the <c>ZipFile</c>, then call
-        ///   <c>Extract()</c> an entry that has not been encrypted with a password, the
-        ///   password is not used for that entry, and the <c>ZipEntry</c> is extracted
-        ///   as normal. In other words, the password is used only if necessary.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <see cref="ZipEntry"/> class also has a <see
-        ///   cref="ZipEntry.Password">Password</see> property.  It takes precedence
-        ///   over this property on the <c>ZipFile</c>.  Typically, you would use the
-        ///   per-entry Password when most entries in the zip archive use one password,
-        ///   and a few entries use a different password.  If all entries in the zip
-        ///   file use the same password, then it is simpler to just set this property
-        ///   on the <c>ZipFile</c> itself, whether creating a zip archive or extracting
-        ///   a zip archive.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example creates a zip file, using password protection for the
-        ///   entries, and then extracts the entries from the zip file.  When creating
-        ///   the zip file, the Readme.txt file is not protected with a password, but
-        ///   the other two are password-protected as they are saved. During extraction,
-        ///   each file is extracted with the appropriate password.
-        /// </para>
-        /// <code>
-        /// // create a file with encryption
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.AddFile("ReadMe.txt");
-        ///     zip.Password= "!Secret1";
-        ///     zip.AddFile("MapToTheSite-7440-N49th.png");
-        ///     zip.AddFile("2008-Regional-Sales-Report.pdf");
-        ///     zip.Save("EncryptedArchive.zip");
-        /// }
-        ///
-        /// // extract entries that use encryption
-        /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
-        /// {
-        ///     zip.Password= "!Secret1";
-        ///     zip.ExtractAll("extractDir");
-        /// }
-        ///
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     zip.AddFile("ReadMe.txt")
-        ///     zip.Password = "123456!"
-        ///     zip.AddFile("MapToTheSite-7440-N49th.png")
-        ///     zip.Password= "!Secret1";
-        ///     zip.AddFile("2008-Regional-Sales-Report.pdf")
-        ///     zip.Save("EncryptedArchive.zip")
-        /// End Using
-        ///
-        ///
-        /// ' extract entries that use encryption
-        /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
-        ///     zip.Password= "!Secret1"
-        ///     zip.ExtractAll("extractDir")
-        /// End Using
-        ///
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.Encryption">ZipFile.Encryption</seealso>
-        /// <seealso cref="ZipEntry.Password">ZipEntry.Password</seealso>
-        public String Password
-        {
-            set
-            {
-                _Password = value;
-                if (_Password == null)
-                {
-                    Encryption = EncryptionAlgorithm.None;
-                }
-                else if (Encryption == EncryptionAlgorithm.None)
-                {
-                    Encryption = EncryptionAlgorithm.PkzipWeak;
-                }
-            }
-            private get
-            {
-                return _Password;
-            }
-        }
-
-
-
-
-
-        /// <summary>
-        ///   The action the library should take when extracting a file that already
-        ///   exists.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This property affects the behavior of the Extract methods (one of the
-        ///   <c>Extract()</c> or <c>ExtractWithPassword()</c> overloads), when
-        ///   extraction would would overwrite an existing filesystem file. If you do
-        ///   not set this property, the library throws an exception when extracting an
-        ///   entry would overwrite an existing file.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property has no effect when extracting to a stream, or when the file
-        ///   to be extracted does not already exist.
-        /// </para>
-        /// </remarks>
-        /// <seealso cref="ZipEntry.ExtractExistingFile"/>
-        internal ExtractExistingFileAction ExtractExistingFile
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   The action the library should take when an error is encountered while
-        ///   opening or reading files as they are saved into a zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///  <para>
-        ///    Errors can occur as a file is being saved to the zip archive.  For
-        ///    example, the File.Open may fail, or a File.Read may fail, because of
-        ///    lock conflicts or other reasons.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    The first problem might occur after having called AddDirectory() on a
-        ///    directory that contains a Clipper .dbf file; the file is locked by
-        ///    Clipper and cannot be opened for read by another process. An example of
-        ///    the second problem might occur when trying to zip a .pst file that is in
-        ///    use by Microsoft Outlook. Outlook locks a range on the file, which allows
-        ///    other processes to open the file, but not read it in its entirety.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    This property tells DotNetZip what you would like to do in the case of
-        ///    these errors.  The primary options are: <c>ZipErrorAction.Throw</c> to
-        ///    throw an exception (this is the default behavior if you don't set this
-        ///    property); <c>ZipErrorAction.Skip</c> to Skip the file for which there
-        ///    was an error and continue saving; <c>ZipErrorAction.Retry</c> to Retry
-        ///    the entry that caused the problem; or
-        ///    <c>ZipErrorAction.InvokeErrorEvent</c> to invoke an event handler.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    This property is implicitly set to <c>ZipErrorAction.InvokeErrorEvent</c>
-        ///    if you add a handler to the <see cref="ZipError" /> event.  If you set
-        ///    this property to something other than
-        ///    <c>ZipErrorAction.InvokeErrorEvent</c>, then the <c>ZipError</c>
-        ///    event is implicitly cleared.  What it means is you can set one or the
-        ///    other (or neither), depending on what you want, but you never need to set
-        ///    both.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    As with some other properties on the <c>ZipFile</c> class, like <see
-        ///    cref="Password"/>, <see cref="Encryption"/>, and <see
-        ///    cref="CompressionLevel"/>, setting this property on a <c>ZipFile</c>
-        ///    instance will cause the specified <c>ZipErrorAction</c> to be used on all
-        ///    <see cref="ZipEntry"/> items that are subsequently added to the
-        ///    <c>ZipFile</c> instance. If you set this property after you have added
-        ///    items to the <c>ZipFile</c>, but before you have called <c>Save()</c>,
-        ///    those items will not use the specified error handling action.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    If you want to handle any errors that occur with any entry in the zip
-        ///    file in the same way, then set this property once, before adding any
-        ///    entries to the zip archive.
-        ///  </para>
-        ///
-        ///  <para>
-        ///    If you set this property to <c>ZipErrorAction.Skip</c> and you'd like to
-        ///    learn which files may have been skipped after a <c>Save()</c>, you can
-        ///    set the <see cref="StatusMessageTextWriter" /> on the ZipFile before
-        ///    calling <c>Save()</c>. A message will be emitted into that writer for
-        ///    each skipped file, if any.
-        ///  </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example shows how to tell DotNetZip to skip any files for which an
-        ///   error is generated during the Save().
-        /// <code lang="VB">
-        /// Public Sub SaveZipFile()
-        ///     Dim SourceFolder As String = "fodder"
-        ///     Dim DestFile As String =  "eHandler.zip"
-        ///     Dim sw as New StringWriter
-        ///     Using zipArchive As ZipFile = New ZipFile
-        ///         ' Tell DotNetZip to skip any files for which it encounters an error
-        ///         zipArchive.ZipErrorAction = ZipErrorAction.Skip
-        ///         zipArchive.StatusMessageTextWriter = sw
-        ///         zipArchive.AddDirectory(SourceFolder)
-        ///         zipArchive.Save(DestFile)
-        ///     End Using
-        ///     ' examine sw here to see any messages
-        /// End Sub
-        ///
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="ZipEntry.ZipErrorAction"/>
-        /// <seealso cref="Ionic.Zip.ZipFile.ZipError"/>
-
-        internal ZipErrorAction ZipErrorAction
-        {
-            get
-            {
-                if (ZipError != null)
-                    _zipErrorAction = ZipErrorAction.InvokeErrorEvent;
-                return _zipErrorAction;
-            }
-            set
-            {
-                _zipErrorAction = value;
-                if (_zipErrorAction != ZipErrorAction.InvokeErrorEvent && ZipError != null)
-                    ZipError = null;
-            }
-        }
-
-
-        /// <summary>
-        ///   The Encryption to use for entries added to the <c>ZipFile</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Set this when creating a zip archive, or when updating a zip archive. The
-        ///   specified Encryption is applied to the entries subsequently added to the
-        ///   <c>ZipFile</c> instance.  Applications do not need to set the
-        ///   <c>Encryption</c> property when reading or extracting a zip archive.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you set this to something other than EncryptionAlgorithm.None, you
-        ///   will also need to set the <see cref="Password"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   As with some other properties on the <c>ZipFile</c> class, like <see
-        ///   cref="Password"/> and <see cref="CompressionLevel"/>, setting this
-        ///   property on a <c>ZipFile</c> instance will cause the specified
-        ///   <c>EncryptionAlgorithm</c> to be used on all <see cref="ZipEntry"/> items
-        ///   that are subsequently added to the <c>ZipFile</c> instance. In other
-        ///   words, if you set this property after you have added items to the
-        ///   <c>ZipFile</c>, but before you have called <c>Save()</c>, those items will
-        ///   not be encrypted or protected with a password in the resulting zip
-        ///   archive. To get a zip archive with encrypted entries, set this property,
-        ///   along with the <see cref="Password"/> property, before calling
-        ///   <c>AddFile</c>, <c>AddItem</c>, or <c>AddDirectory</c> (etc.) on the
-        ///   <c>ZipFile</c> instance.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you read a <c>ZipFile</c>, you can modify the <c>Encryption</c> on an
-        ///   encrypted entry, only by setting the <c>Encryption</c> property on the
-        ///   <c>ZipEntry</c> itself.  Setting the <c>Encryption</c> property on the
-        ///   <c>ZipFile</c>, once it has been created via a call to
-        ///   <c>ZipFile.Read()</c>, does not affect entries that were previously read.
-        /// </para>
-        ///
-        /// <para>
-        ///   For example, suppose you read a <c>ZipFile</c>, and there is an encrypted
-        ///   entry.  Setting the <c>Encryption</c> property on that <c>ZipFile</c> and
-        ///   then calling <c>Save()</c> on the <c>ZipFile</c> does not update the
-        ///   <c>Encryption</c> used for the entries in the archive.  Neither is an
-        ///   exception thrown. Instead, what happens during the <c>Save()</c> is that
-        ///   all previously existing entries are copied through to the new zip archive,
-        ///   with whatever encryption and password that was used when originally
-        ///   creating the zip archive. Upon re-reading that archive, to extract
-        ///   entries, applications should use the original password or passwords, if
-        ///   any.
-        /// </para>
-        ///
-        /// <para>
-        ///   Suppose an application reads a <c>ZipFile</c>, and there is an encrypted
-        ///   entry.  Setting the <c>Encryption</c> property on that <c>ZipFile</c> and
-        ///   then adding new entries (via <c>AddFile()</c>, <c>AddEntry()</c>, etc)
-        ///   and then calling <c>Save()</c> on the <c>ZipFile</c> does not update the
-        ///   <c>Encryption</c> on any of the entries that had previously been in the
-        ///   <c>ZipFile</c>.  The <c>Encryption</c> property applies only to the
-        ///   newly-added entries.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// <para>
-        ///   This example creates a zip archive that uses encryption, and then extracts
-        ///   entries from the archive.  When creating the zip archive, the ReadMe.txt
-        ///   file is zipped without using a password or encryption.  The other files
-        ///   use encryption.
-        /// </para>
-        ///
-        /// <code>
-        /// // Create a zip archive with AES Encryption.
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///     zip.AddFile("ReadMe.txt");
-        ///     zip.Encryption= EncryptionAlgorithm.WinZipAes256;
-        ///     zip.Password= "Top.Secret.No.Peeking!";
-        ///     zip.AddFile("7440-N49th.png");
-        ///     zip.AddFile("2008-Regional-Sales-Report.pdf");
-        ///     zip.Save("EncryptedArchive.zip");
-        /// }
-        ///
-        /// // Extract a zip archive that uses AES Encryption.
-        /// // You do not need to specify the algorithm during extraction.
-        /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
-        /// {
-        ///     zip.Password= "Top.Secret.No.Peeking!";
-        ///     zip.ExtractAll("extractDirectory");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// ' Create a zip that uses Encryption.
-        /// Using zip As New ZipFile()
-        ///     zip.Encryption= EncryptionAlgorithm.WinZipAes256
-        ///     zip.Password= "Top.Secret.No.Peeking!"
-        ///     zip.AddFile("ReadMe.txt")
-        ///     zip.AddFile("7440-N49th.png")
-        ///     zip.AddFile("2008-Regional-Sales-Report.pdf")
-        ///     zip.Save("EncryptedArchive.zip")
-        /// End Using
-        ///
-        /// ' Extract a zip archive that uses AES Encryption.
-        /// ' You do not need to specify the algorithm during extraction.
-        /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
-        ///     zip.Password= "Top.Secret.No.Peeking!"
-        ///     zip.ExtractAll("extractDirectory")
-        /// End Using
-        /// </code>
-        ///
-        /// </example>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.Password">ZipFile.Password</seealso>
-        /// <seealso cref="ZipEntry.Encryption">ZipEntry.Encryption</seealso>
-        internal EncryptionAlgorithm Encryption
-        {
-            get
-            {
-                return _Encryption;
-            }
-            set
-            {
-                if (value == EncryptionAlgorithm.Unsupported)
-                    throw new InvalidOperationException("You may not set Encryption to that value.");
-                _Encryption = value;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   A callback that allows the application to specify the compression level
-        ///   to use for entries subsequently added to the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   With this callback, the DotNetZip library allows the application to
-        ///   determine whether compression will be used, at the time of the
-        ///   <c>Save</c>. This may be useful if the application wants to favor
-        ///   speed over size, and wants to defer the decision until the time of
-        ///   <c>Save</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Typically applications set the <see cref="CompressionLevel"/> property on
-        ///   the <c>ZipFile</c> or on each <c>ZipEntry</c> to determine the level of
-        ///   compression used. This is done at the time the entry is added to the
-        ///   <c>ZipFile</c>. Setting the property to
-        ///   <c>Ionic.Zlib.CompressionLevel.None</c> means no compression will be used.
-        /// </para>
-        ///
-        /// <para>
-        ///   This callback allows the application to defer the decision on the
-        ///   <c>CompressionLevel</c> to use, until the time of the call to
-        ///   <c>ZipFile.Save()</c>. The callback is invoked once per <c>ZipEntry</c>,
-        ///   at the time the data for the entry is being written out as part of a
-        ///   <c>Save()</c> operation. The application can use whatever criteria it
-        ///   likes in determining the level to return.  For example, an application may
-        ///   wish that no .mp3 files should be compressed, because they are already
-        ///   compressed and the extra compression is not worth the CPU time incurred,
-        ///   and so can return <c>None</c> for all .mp3 entries.
-        /// </para>
-        ///
-        /// <para>
-        ///   The library determines whether compression will be attempted for an entry
-        ///   this way: If the entry is a zero length file, or a directory, no
-        ///   compression is used.  Otherwise, if this callback is set, it is invoked
-        ///   and the <c>CompressionLevel</c> is set to the return value. If this
-        ///   callback has not been set, then the previously set value for
-        ///   <c>CompressionLevel</c> is used.
-        /// </para>
-        ///
-        /// </remarks>
-        public SetCompressionCallback SetCompression
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        /// The maximum size of an output segment, when saving a split Zip file.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Set this to a non-zero value before calling <see cref="Save()"/> or <see
-        ///     cref="Save(String)"/> to specify that the ZipFile should be saved as a
-        ///     split archive, also sometimes called a spanned archive. Some also
-        ///     call them multi-file archives.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     A split zip archive is saved in a set of discrete filesystem files,
-        ///     rather than in a single file. This is handy when transmitting the
-        ///     archive in email or some other mechanism that has a limit to the size of
-        ///     each file.  The first file in a split archive will be named
-        ///     <c>basename.z01</c>, the second will be named <c>basename.z02</c>, and
-        ///     so on. The final file is named <c>basename.zip</c>. According to the zip
-        ///     specification from PKWare, the minimum value is 65536, for a 64k segment
-        ///     size. The maximum number of segments allows in a split archive is 99.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     The value of this property determines the maximum size of a split
-        ///     segment when writing a split archive.  For example, suppose you have a
-        ///     <c>ZipFile</c> that would save to a single file of 200k. If you set the
-        ///     <c>MaxOutputSegmentSize</c> to 65536 before calling <c>Save()</c>, you
-        ///     will get four distinct output files. On the other hand if you set this
-        ///     property to 256k, then you will get a single-file archive for that
-        ///     <c>ZipFile</c>.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     The size of each split output file will be as large as possible, up to
-        ///     the maximum size set here. The zip specification requires that some data
-        ///     fields in a zip archive may not span a split boundary, and an output
-        ///     segment may be smaller than the maximum if necessary to avoid that
-        ///     problem. Also, obviously the final segment of the archive may be smaller
-        ///     than the maximum segment size. Segments will never be larger than the
-        ///     value set with this property.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     You can save a split Zip file only when saving to a regular filesystem
-        ///     file. It's not possible to save a split zip file as a self-extracting
-        ///     archive, nor is it possible to save a split zip file to a stream. When
-        ///     saving to a SFX or to a Stream, this property is ignored.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     About interoperability: Split or spanned zip files produced by DotNetZip
-        ///     can be read by WinZip or PKZip, and vice-versa. Segmented zip files may
-        ///     not be readable by other tools, if those other tools don't support zip
-        ///     spanning or splitting.  When in doubt, test.  I don't believe Windows
-        ///     Explorer can extract a split archive.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     This property has no effect when reading a split archive. You can read
-        ///     a split archive in the normal way with DotNetZip.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     When saving a zip file, if you want a regular zip file rather than a
-        ///     split zip file, don't set this property, or set it to Zero.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     If you read a split archive, with <see cref="ZipFile.Read(string)"/> and
-        ///     then subsequently call <c>ZipFile.Save()</c>, unless you set this
-        ///     property before calling <c>Save()</c>, you will get a normal,
-        ///     single-file archive.
-        ///   </para>
-        /// </remarks>
-        ///
-        /// <seealso cref="NumberOfSegmentsForMostRecentSave"/>
-        public Int32 MaxOutputSegmentSize
-        {
-            get
-            {
-                return _maxOutputSegmentSize;
-            }
-            set
-            {
-                if (value < 65536 && value != 0)
-                    throw new ZipException("The minimum acceptable segment size is 65536.");
-                _maxOutputSegmentSize = value;
-            }
-        }
-
-
-        /// <summary>
-        ///   Returns the number of segments used in the most recent Save() operation.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     This is normally zero, unless you have set the <see
-        ///     cref="MaxOutputSegmentSize"/> property.  If you have set <see
-        ///     cref="MaxOutputSegmentSize"/>, and then you save a file, after the call to
-        ///     Save() completes, you can read this value to learn the number of segments that
-        ///     were created.
-        ///   </para>
-        ///   <para>
-        ///     If you call Save("Archive.zip"), and it creates 5 segments, then you
-        ///     will have filesystem files named Archive.z01, Archive.z02, Archive.z03,
-        ///     Archive.z04, and Archive.zip, and the value of this property will be 5.
-        ///   </para>
-        /// </remarks>
-        /// <seealso cref="MaxOutputSegmentSize"/>
-        public Int32 NumberOfSegmentsForMostRecentSave
-        {
-            get
-            {
-                return unchecked((Int32)_numberOfSegmentsForMostRecentSave + 1);
-            }
-        }
-
-
-#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,
-        ///     if the entry is larger than the given size.  Zero means "always
-        ///     use parallel deflate", while -1 means "never use parallel
-        ///     deflate". The default value for this property is 512k. Aside
-        ///     from the special values of 0 and 1, the minimum value is 65536.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     If the entry size cannot be known before compression, as with a
-        ///     read-forward stream, 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 not as effective.
-        ///   </para>
-        ///
-        ///   <para>
-        ///     Parallel deflate tends to yield slightly less compression when
-        ///     compared to as single-threaded deflate; this is 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.  For that reason, a deflated stream may be slightly
-        ///     larger when compressed using parallel deflate, as compared to a
-        ///     traditional single-threaded deflate. Sometimes the increase over the
-        ///     normal deflate is as much as 5% of the total compressed size. For
-        ///     larger files it 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>
-        ///
-        /// </remarks>
-        ///
-        /// <seealso cref="ParallelDeflateMaxBufferPairs"/>
-        ///
-        public long ParallelDeflateThreshold
-        {
-            set
-            {
-                if ((value != 0) && (value != -1) && (value < 64 * 1024))
-                    throw new ArgumentOutOfRangeException("ParallelDeflateThreshold should be -1, 0, or > 65536");
-                _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(System.Threading.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="BufferSize"/>).  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
-        ///   before calling <c>ZipFile.Save()</c>.
-        /// </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
-
-
-        /// <summary>Provides a string representation of the instance.</summary>
-        /// <returns>a string representation of the instance.</returns>
-        public override String ToString()
-        {
-            return String.Format("ZipFile::{0}", Name);
-        }
-
-
-        /// <summary>
-        /// Returns the version number on the DotNetZip assembly.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   <para>
-        ///     This property is exposed as a convenience.  Callers could also get the
-        ///     version value by retrieving GetName().Version on the
-        ///     System.Reflection.Assembly object pointing to the DotNetZip
-        ///     assembly. But sometimes it is not clear which assembly is being loaded.
-        ///     This property makes it clear.
-        ///   </para>
-        ///   <para>
-        ///     This static property is primarily useful for diagnostic purposes.
-        ///   </para>
-        /// </remarks>
-        public static System.Version LibraryVersion
-        {
-            get
-            {
-                return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
-            }
-        }
-
-        internal void NotifyEntryChanged()
-        {
-            _contentsChanged = true;
-        }
-
-
-        internal Stream StreamForDiskNumber(uint diskNumber)
-        {
-            if (diskNumber + 1 == this._diskNumberWithCd ||
-                (diskNumber == 0 && this._diskNumberWithCd == 0))
-            {
-                //return (this.ReadStream as FileStream);
-                return this.ReadStream;
-            }
-            return ZipSegmentedStream.ForReading(this._readName ?? this._name,
-                                                 diskNumber, _diskNumberWithCd);
-        }
-
-
-
-        // called by ZipEntry in ZipEntry.Extract(), when there is no stream set for the
-        // ZipEntry.
-        internal void Reset(bool whileSaving)
-        {
-            if (_JustSaved)
-            {
-                // read in the just-saved zip archive
-                using (ZipFile x = new ZipFile())
-                {
-                    // workitem 10735
-                    x._readName = x._name = whileSaving
-                        ? (this._readName ?? this._name)
-                        : this._name;
-                    x.AlternateEncoding = this.AlternateEncoding;
-                    x.AlternateEncodingUsage = this.AlternateEncodingUsage;
-                    ReadIntoInstance(x);
-                    // copy the contents of the entries.
-                    // cannot just replace the entries - the app may be holding them
-                    foreach (ZipEntry e1 in x)
-                    {
-                        foreach (ZipEntry e2 in this)
-                        {
-                            if (e1.FileName == e2.FileName)
-                            {
-                                e2.CopyMetaData(e1);
-                                break;
-                            }
-                        }
-                    }
-                }
-                _JustSaved = false;
-            }
-        }
-
-
-        #endregion
-
-        #region Constructors
-
-        /// <summary>
-        ///   Creates a new <c>ZipFile</c> instance, using the specified filename.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Applications can use this constructor to create a new ZipFile for writing,
-        ///   or to slurp in an existing zip archive for read and update purposes.
-        /// </para>
-        ///
-        /// <para>
-        ///   To create a new zip archive, an application can call this constructor,
-        ///   passing the name of a file that does not exist.  The name may be a fully
-        ///   qualified path. Then the application can add directories or files to the
-        ///   <c>ZipFile</c> via <c>AddDirectory()</c>, <c>AddFile()</c>, <c>AddItem()</c>
-        ///   and then write the zip archive to the disk by calling <c>Save()</c>. The
-        ///   zip file is not actually opened and written to the disk until the
-        ///   application calls <c>ZipFile.Save()</c>.  At that point the new zip file
-        ///   with the given name is created.
-        /// </para>
-        ///
-        /// <para>
-        ///   If you won't know the name of the <c>Zipfile</c> until the time you call
-        ///   <c>ZipFile.Save()</c>, or if you plan to save to a stream (which has no
-        ///   name), then you should use the no-argument constructor.
-        /// </para>
-        ///
-        /// <para>
-        ///   The application can also call this constructor to read an existing zip
-        ///   archive.  passing the name of a valid zip file that does exist. But, it's
-        ///   better form to use the static <see cref="ZipFile.Read(String)"/> method,
-        ///   passing the name of the zip file, because using <c>ZipFile.Read()</c> in
-        ///   your code communicates very clearly what you are doing.  In either case,
-        ///   the file is then read into the <c>ZipFile</c> instance.  The app can then
-        ///   enumerate the entries or can modify the zip file, for example adding
-        ///   entries, removing entries, changing comments, and so on.
-        /// </para>
-        ///
-        /// <para>
-        ///   One advantage to this parameterized constructor: it allows applications to
-        ///   use the same code to add items to a zip archive, regardless of whether the
-        ///   zip file exists.
-        /// </para>
-        ///
-        /// <para>
-        ///   Instances of the <c>ZipFile</c> class are not multi-thread safe.  You may
-        ///   not party on a single instance with multiple threads.  You may have
-        ///   multiple threads that each use a distinct <c>ZipFile</c> instance, or you
-        ///   can synchronize multi-thread access to a single instance.
-        /// </para>
-        ///
-        /// <para>
-        ///   By the way, since DotNetZip is so easy to use, don't you think <see
-        ///   href="http://cheeso.members.winisp.net/DotNetZipDonate.aspx">you should
-        ///   donate $5 or $10</see>?
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="Ionic.Zip.ZipException">
-        /// Thrown if name refers to an existing file that is not a valid zip file.
-        /// </exception>
-        ///
-        /// <example>
-        /// This example shows how to create a zipfile, and add a few files into it.
-        /// <code>
-        /// String ZipFileToCreate = "archive1.zip";
-        /// String DirectoryToZip  = "c:\\reports";
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///   // Store all files found in the top level directory, into the zip archive.
-        ///   String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
-        ///   zip.AddFiles(filenames, "files");
-        ///   zip.Save(ZipFileToCreate);
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Dim ZipFileToCreate As String = "archive1.zip"
-        /// Dim DirectoryToZip As String = "c:\reports"
-        /// Using zip As ZipFile = New ZipFile()
-        ///     Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
-        ///     zip.AddFiles(filenames, "files")
-        ///     zip.Save(ZipFileToCreate)
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="fileName">The filename to use for the new zip archive.</param>
-        ///
-        public ZipFile(string fileName)
-        {
-            try
-            {
-                _InitInstance(fileName, null);
-            }
-            catch (Exception e1)
-            {
-                throw new ZipException(String.Format("Could not read {0} as a zip file", fileName), e1);
-            }
-        }
-
-
-        /// <summary>
-        ///   Creates a new <c>ZipFile</c> instance, using the specified name for the
-        ///   filename, and the specified Encoding.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the documentation on the <see cref="ZipFile(String)">ZipFile
-        ///   constructor that accepts a single string argument</see> for basic
-        ///   information on all the <c>ZipFile</c> constructors.
-        /// </para>
-        ///
-        /// <para>
-        ///   The Encoding is used as the default alternate encoding for entries with
-        ///   filenames or comments that cannot be encoded with the IBM437 code page.
-        ///   This is equivalent to setting the <see
-        ///   cref="ProvisionalAlternateEncoding"/> property on the <c>ZipFile</c>
-        ///   instance after construction.
-        /// </para>
-        ///
-        /// <para>
-        ///   Instances of the <c>ZipFile</c> class are not multi-thread safe.  You may
-        ///   not party on a single instance with multiple threads.  You may have
-        ///   multiple threads that each use a distinct <c>ZipFile</c> instance, or you
-        ///   can synchronize multi-thread access to a single instance.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="Ionic.Zip.ZipException">
-        /// Thrown if name refers to an existing file that is not a valid zip file.
-        /// </exception>
-        ///
-        /// <param name="fileName">The filename to use for the new zip archive.</param>
-        /// <param name="encoding">The Encoding is used as the default alternate
-        /// encoding for entries with filenames or comments that cannot be encoded
-        /// with the IBM437 code page. </param>
-        public ZipFile(string fileName, System.Text.Encoding encoding)
-        {
-            try
-            {
-                AlternateEncoding = encoding;
-                AlternateEncodingUsage = ZipOption.Always;
-                _InitInstance(fileName, null);
-            }
-            catch (Exception e1)
-            {
-                throw new ZipException(String.Format("{0} is not a valid zip file", fileName), e1);
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Create a zip file, without specifying a target filename or stream to save to.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the documentation on the <see cref="ZipFile(String)">ZipFile
-        ///   constructor that accepts a single string argument</see> for basic
-        ///   information on all the <c>ZipFile</c> constructors.
-        /// </para>
-        ///
-        /// <para>
-        ///   After instantiating with this constructor and adding entries to the
-        ///   archive, the application should call <see cref="ZipFile.Save(String)"/> or
-        ///   <see cref="ZipFile.Save(System.IO.Stream)"/> to save to a file or a
-        ///   stream, respectively.  The application can also set the <see cref="Name"/>
-        ///   property and then call the no-argument <see cref="Save()"/> method.  (This
-        ///   is the preferred approach for applications that use the library through
-        ///   COM interop.)  If you call the no-argument <see cref="Save()"/> method
-        ///   without having set the <c>Name</c> of the <c>ZipFile</c>, either through
-        ///   the parameterized constructor or through the explicit property , the
-        ///   Save() will throw, because there is no place to save the file.  </para>
-        ///
-        /// <para>
-        ///   Instances of the <c>ZipFile</c> class are not multi-thread safe.  You may
-        ///   have multiple threads that each use a distinct <c>ZipFile</c> instance, or
-        ///   you can synchronize multi-thread access to a single instance.  </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example creates a Zip archive called Backup.zip, containing all the files
-        /// in the directory DirectoryToZip. Files within subdirectories are not zipped up.
-        /// <code>
-        /// using (ZipFile zip = new ZipFile())
-        /// {
-        ///   // Store all files found in the top level directory, into the zip archive.
-        ///   // note: this code does not recurse subdirectories!
-        ///   String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
-        ///   zip.AddFiles(filenames, "files");
-        ///   zip.Save("Backup.zip");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile
-        ///     ' Store all files found in the top level directory, into the zip archive.
-        ///     ' note: this code does not recurse subdirectories!
-        ///     Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
-        ///     zip.AddFiles(filenames, "files")
-        ///     zip.Save("Backup.zip")
-        /// End Using
-        /// </code>
-        /// </example>
-        public ZipFile()
-        {
-            _InitInstance(null, null);
-        }
-
-
-        /// <summary>
-        ///   Create a zip file, specifying a text Encoding, but without specifying a
-        ///   target filename or stream to save to.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the documentation on the <see cref="ZipFile(String)">ZipFile
-        ///   constructor that accepts a single string argument</see> for basic
-        ///   information on all the <c>ZipFile</c> constructors.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="encoding">
-        /// The Encoding is used as the default alternate encoding for entries with
-        /// filenames or comments that cannot be encoded with the IBM437 code page.
-        /// </param>
-        public ZipFile(System.Text.Encoding encoding)
-        {
-            AlternateEncoding = encoding;
-            AlternateEncodingUsage = ZipOption.Always;
-            _InitInstance(null, null);
-        }
-
-
-        /// <summary>
-        ///   Creates a new <c>ZipFile</c> instance, using the specified name for the
-        ///   filename, and the specified status message writer.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   See the documentation on the <see cref="ZipFile(String)">ZipFile
-        ///   constructor that accepts a single string argument</see> for basic
-        ///   information on all the <c>ZipFile</c> constructors.
-        /// </para>
-        ///
-        /// <para>
-        ///   This version of the constructor allows the caller to pass in a TextWriter,
-        ///   to which verbose messages will be written during extraction or creation of
-        ///   the zip archive.  A console application may wish to pass
-        ///   System.Console.Out to get messages on the Console. A graphical or headless
-        ///   application may wish to capture the messages in a different
-        ///   <c>TextWriter</c>, for example, a <c>StringWriter</c>, and then display
-        ///   the messages in a TextBox, or generate an audit log of ZipFile operations.
-        /// </para>
-        ///
-        /// <para>
-        ///   To encrypt the data for the files added to the <c>ZipFile</c> instance,
-        ///   set the Password property after creating the <c>ZipFile</c> instance.
-        /// </para>
-        ///
-        /// <para>
-        ///   Instances of the <c>ZipFile</c> class are not multi-thread safe.  You may
-        ///   not party on a single instance with multiple threads.  You may have
-        ///   multiple threads that each use a distinct <c>ZipFile</c> instance, or you
-        ///   can synchronize multi-thread access to a single instance.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="Ionic.Zip.ZipException">
-        /// Thrown if name refers to an existing file that is not a valid zip file.
-        /// </exception>
-        ///
-        /// <example>
-        /// <code>
-        /// using (ZipFile zip = new ZipFile("Backup.zip", Console.Out))
-        /// {
-        ///   // Store all files found in the top level directory, into the zip archive.
-        ///   // note: this code does not recurse subdirectories!
-        ///   // Status messages will be written to Console.Out
-        ///   String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
-        ///   zip.AddFiles(filenames);
-        ///   zip.Save();
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As New ZipFile("Backup.zip", Console.Out)
-        ///     ' Store all files found in the top level directory, into the zip archive.
-        ///     ' note: this code does not recurse subdirectories!
-        ///     ' Status messages will be written to Console.Out
-        ///     Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
-        ///     zip.AddFiles(filenames)
-        ///     zip.Save()
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="fileName">The filename to use for the new zip archive.</param>
-        /// <param name="statusMessageWriter">A TextWriter to use for writing
-        /// verbose status messages.</param>
-        public ZipFile(string fileName, TextWriter statusMessageWriter)
-        {
-            try
-            {
-                _InitInstance(fileName, statusMessageWriter);
-            }
-            catch (Exception e1)
-            {
-                throw new ZipException(String.Format("{0} is not a valid zip file", fileName), e1);
-            }
-        }
-
-
-        /// <summary>
-        ///   Creates a new <c>ZipFile</c> instance, using the specified name for the
-        ///   filename, the specified status message writer, and the specified Encoding.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This constructor works like the <see cref="ZipFile(String)">ZipFile
-        ///   constructor that accepts a single string argument.</see> See that
-        ///   reference for detail on what this constructor does.
-        /// </para>
-        ///
-        /// <para>
-        ///   This version of the constructor allows the caller to pass in a
-        ///   <c>TextWriter</c>, and an Encoding.  The <c>TextWriter</c> will collect
-        ///   verbose messages that are generated by the library during extraction or
-        ///   creation of the zip archive.  A console application may wish to pass
-        ///   <c>System.Console.Out</c> to get messages on the Console. A graphical or
-        ///   headless application may wish to capture the messages in a different
-        ///   <c>TextWriter</c>, for example, a <c>StringWriter</c>, and then display
-        ///   the messages in a <c>TextBox</c>, or generate an audit log of
-        ///   <c>ZipFile</c> operations.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <c>Encoding</c> is used as the default alternate encoding for entries
-        ///   with filenames or comments that cannot be encoded with the IBM437 code
-        ///   page.  This is a equivalent to setting the <see
-        ///   cref="ProvisionalAlternateEncoding"/> property on the <c>ZipFile</c>
-        ///   instance after construction.
-        /// </para>
-        ///
-        /// <para>
-        ///   To encrypt the data for the files added to the <c>ZipFile</c> instance,
-        ///   set the <c>Password</c> property after creating the <c>ZipFile</c>
-        ///   instance.
-        /// </para>
-        ///
-        /// <para>
-        ///   Instances of the <c>ZipFile</c> class are not multi-thread safe.  You may
-        ///   not party on a single instance with multiple threads.  You may have
-        ///   multiple threads that each use a distinct <c>ZipFile</c> instance, or you
-        ///   can synchronize multi-thread access to a single instance.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="Ionic.Zip.ZipException">
-        /// Thrown if <c>fileName</c> refers to an existing file that is not a valid zip file.
-        /// </exception>
-        ///
-        /// <param name="fileName">The filename to use for the new zip archive.</param>
-        /// <param name="statusMessageWriter">A TextWriter to use for writing verbose
-        /// status messages.</param>
-        /// <param name="encoding">
-        /// The Encoding is used as the default alternate encoding for entries with
-        /// filenames or comments that cannot be encoded with the IBM437 code page.
-        /// </param>
-        public ZipFile(string fileName, TextWriter statusMessageWriter,
-                       System.Text.Encoding encoding)
-        {
-            try
-            {
-                AlternateEncoding = encoding;
-                AlternateEncodingUsage = ZipOption.Always;
-                _InitInstance(fileName, statusMessageWriter);
-            }
-            catch (Exception e1)
-            {
-                throw new ZipException(String.Format("{0} is not a valid zip file", fileName), e1);
-            }
-        }
-
-
-
-
-        /// <summary>
-        ///   Initialize a <c>ZipFile</c> instance by reading in a zip file.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This method is primarily useful from COM Automation environments, when
-        ///   reading or extracting zip files. In COM, it is not possible to invoke
-        ///   parameterized constructors for a class. A COM Automation application can
-        ///   update a zip file by using the <see cref="ZipFile()">default (no argument)
-        ///   constructor</see>, then calling <c>Initialize()</c> to read the contents
-        ///   of an on-disk zip archive into the <c>ZipFile</c> instance.
-        /// </para>
-        ///
-        /// <para>
-        ///   .NET applications are encouraged to use the <c>ZipFile.Read()</c> methods
-        ///   for better clarity.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <param name="fileName">the name of the existing zip file to read in.</param>
-        public void Initialize(string fileName)
-        {
-            try
-            {
-                _InitInstance(fileName, null);
-            }
-            catch (Exception e1)
-            {
-                throw new ZipException(String.Format("{0} is not a valid zip file", fileName), e1);
-            }
-        }
-
-
-
-        private void _initEntriesDictionary()
-        {
-            // workitem 9868
-            StringComparer sc = (CaseSensitiveRetrieval) ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
-            _entries = (_entries == null)
-                ? new Dictionary<String, ZipEntry>(sc)
-                : new Dictionary<String, ZipEntry>(_entries, sc);
-        }
-
-
-        private void _InitInstance(string zipFileName, TextWriter statusMessageWriter)
-        {
-            // create a new zipfile
-            _name = zipFileName;
-            _StatusMessageTextWriter = statusMessageWriter;
-            _contentsChanged = true;
-            AddDirectoryWillTraverseReparsePoints = true;  // workitem 8617
-            CompressionLevel = OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.Default;
-#if !NETCF
-            ParallelDeflateThreshold = 512 * 1024;
-#endif
-            // workitem 7685, 9868
-            _initEntriesDictionary();
-
-            if (File.Exists(_name))
-            {
-                if (FullScan)
-                    ReadIntoInstance_Orig(this);
-                else
-                    ReadIntoInstance(this);
-                this._fileAlreadyExists = true;
-            }
-
-            return;
-        }
-        #endregion
-
-
-
-        #region Indexers and Collections
-
-        private List<ZipEntry> ZipEntriesAsList
-        {
-            get
-            {
-                if (_zipEntriesAsList == null)
-                    _zipEntriesAsList = new List<ZipEntry>(_entries.Values);
-                return _zipEntriesAsList;
-            }
-        }
-
-        /// <summary>
-        ///   This is an integer indexer into the Zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This property is read-only.
-        /// </para>
-        ///
-        /// <para>
-        ///   Internally, the <c>ZipEntry</c> instances that belong to the
-        ///   <c>ZipFile</c> are stored in a Dictionary.  When you use this
-        ///   indexer the first time, it creates a read-only
-        ///   <c>List&lt;ZipEntry&gt;</c> from the Dictionary.Values Collection.
-        ///   If at any time you modify the set of entries in the <c>ZipFile</c>,
-        ///   either by adding an entry, removing an entry, or renaming an
-        ///   entry, a new List will be created, and the numeric indexes for the
-        ///   remaining entries may be different.
-        /// </para>
-        ///
-        /// <para>
-        ///   This means you cannot rename any ZipEntry from
-        ///   inside an enumeration of the zip file.
-        /// </para>
-        ///
-        /// <param name="ix">
-        ///   The index value.
-        /// </param>
-        ///
-        /// </remarks>
-        ///
-        /// <returns>
-        ///   The <c>ZipEntry</c> within the Zip archive at the specified index. If the
-        ///   entry does not exist in the archive, this indexer throws.
-        /// </returns>
-        ///
-        public ZipEntry this[int ix]
-        {
-            // workitem 6402
-            get
-            {
-                return ZipEntriesAsList[ix];
-            }
-        }
-
-
-        /// <summary>
-        ///   This is a name-based indexer into the Zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This property is read-only.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <see cref="CaseSensitiveRetrieval"/> property on the <c>ZipFile</c>
-        ///   determines whether retrieval via this indexer is done via case-sensitive
-        ///   comparisons. By default, retrieval is not case sensitive.  This makes
-        ///   sense on Windows, in which filesystems are not case sensitive.
-        /// </para>
-        ///
-        /// <para>
-        ///   Regardless of case-sensitivity, it is not always the case that
-        ///   <c>this[value].FileName == value</c>. In other words, the <c>FileName</c>
-        ///   property of the <c>ZipEntry</c> retrieved with this indexer, may or may
-        ///   not be equal to the index value.
-        /// </para>
-        ///
-        /// <para>
-        ///   This is because DotNetZip performs a normalization of filenames passed to
-        ///   this indexer, before attempting to retrieve the item.  That normalization
-        ///   includes: removal of a volume letter and colon, swapping backward slashes
-        ///   for forward slashes.  So, <c>zip["dir1\\entry1.txt"].FileName ==
-        ///   "dir1/entry.txt"</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Directory entries in the zip file may be retrieved via this indexer only
-        ///   with names that have a trailing slash. DotNetZip automatically appends a
-        ///   trailing slash to the names of any directory entries added to a zip.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example extracts only the entries in a zip file that are .txt files.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read("PackedDocuments.zip"))
-        /// {
-        ///   foreach (string s1 in zip.EntryFilenames)
-        ///   {
-        ///     if (s1.EndsWith(".txt"))
-        ///       zip[s1].Extract("textfiles");
-        ///   }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        ///   Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip")
-        ///       Dim s1 As String
-        ///       For Each s1 In zip.EntryFilenames
-        ///           If s1.EndsWith(".txt") Then
-        ///               zip(s1).Extract("textfiles")
-        ///           End If
-        ///       Next
-        ///   End Using
-        /// </code>
-        /// </example>
-        /// <seealso cref="Ionic.Zip.ZipFile.RemoveEntry(string)"/>
-        ///
-        /// <exception cref="System.ArgumentException">
-        ///   Thrown if the caller attempts to assign a non-null value to the indexer.
-        /// </exception>
-        ///
-        /// <param name="fileName">
-        ///   The name of the file, including any directory path, to retrieve from the
-        ///   zip.  The filename match is not case-sensitive by default; you can use the
-        ///   <see cref="CaseSensitiveRetrieval"/> property to change this behavior. The
-        ///   pathname can use forward-slashes or backward slashes.
-        /// </param>
-        ///
-        /// <returns>
-        ///   The <c>ZipEntry</c> within the Zip archive, given by the specified
-        ///   filename. If the named entry does not exist in the archive, this indexer
-        ///   returns <c>null</c> (<c>Nothing</c> in VB).
-        /// </returns>
-        ///
-        public ZipEntry this[String fileName]
-        {
-            get
-            {
-                var key = SharedUtilities.NormalizePathForUseInZipFile(fileName);
-                if (_entries.ContainsKey(key))
-                    return _entries[key];
-                // workitem 11056
-                key = key.Replace("/", "\\");
-                if (_entries.ContainsKey(key))
-                    return _entries[key];
-                return null;
-
-#if MESSY
-                foreach (ZipEntry e in _entries.Values)
-                {
-                    if (this.CaseSensitiveRetrieval)
-                    {
-                        // check for the file match with a case-sensitive comparison.
-                        if (e.FileName == fileName) return e;
-                        // also check for equivalence
-                        if (fileName.Replace("\\", "/") == e.FileName) return e;
-                        if (e.FileName.Replace("\\", "/") == fileName) return e;
-
-                        // check for a difference only in trailing slash
-                        if (e.FileName.EndsWith("/"))
-                        {
-                            var fileNameNoSlash = e.FileName.Trim("/".ToCharArray());
-                            if (fileNameNoSlash == fileName) return e;
-                            // also check for equivalence
-                            if (fileName.Replace("\\", "/") == fileNameNoSlash) return e;
-                            if (fileNameNoSlash.Replace("\\", "/") == fileName) return e;
-                        }
-
-                    }
-                    else
-                    {
-                        // check for the file match in a case-insensitive manner.
-                        if (String.Compare(e.FileName, fileName, StringComparison.CurrentCultureIgnoreCase) == 0) return e;
-                        // also check for equivalence
-                        if (String.Compare(fileName.Replace("\\", "/"), e.FileName, StringComparison.CurrentCultureIgnoreCase) == 0) return e;
-                        if (String.Compare(e.FileName.Replace("\\", "/"), fileName, StringComparison.CurrentCultureIgnoreCase) == 0) return e;
-
-                        // check for a difference only in trailing slash
-                        if (e.FileName.EndsWith("/"))
-                        {
-                            var fileNameNoSlash = e.FileName.Trim("/".ToCharArray());
-
-                            if (String.Compare(fileNameNoSlash, fileName, StringComparison.CurrentCultureIgnoreCase) == 0) return e;
-                            // also check for equivalence
-                            if (String.Compare(fileName.Replace("\\", "/"), fileNameNoSlash, StringComparison.CurrentCultureIgnoreCase) == 0) return e;
-                            if (String.Compare(fileNameNoSlash.Replace("\\", "/"), fileName, StringComparison.CurrentCultureIgnoreCase) == 0) return e;
-
-                        }
-
-                    }
-
-                }
-                return null;
-
-#endif
-            }
-        }
-
-
-        /// <summary>
-        ///   The list of filenames for the entries contained within the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   According to the ZIP specification, the names of the entries use forward
-        ///   slashes in pathnames.  If you are scanning through the list, you may have
-        ///   to swap forward slashes for backslashes.
-        /// </remarks>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.this[string]"/>
-        ///
-        /// <example>
-        ///   This example shows one way to test if a filename is already contained
-        ///   within a zip archive.
-        /// <code>
-        /// String zipFileToRead= "PackedDocuments.zip";
-        /// string candidate = "DatedMaterial.xps";
-        /// using (ZipFile zip = new ZipFile(zipFileToRead))
-        /// {
-        ///   if (zip.EntryFilenames.Contains(candidate))
-        ///     Console.WriteLine("The file '{0}' exists in the zip archive '{1}'",
-        ///                       candidate,
-        ///                       zipFileName);
-        ///   else
-        ///     Console.WriteLine("The file, '{0}', does not exist in the zip archive '{1}'",
-        ///                       candidate,
-        ///                       zipFileName);
-        ///   Console.WriteLine();
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        ///   Dim zipFileToRead As String = "PackedDocuments.zip"
-        ///   Dim candidate As String = "DatedMaterial.xps"
-        ///   Using zip As ZipFile.Read(ZipFileToRead)
-        ///       If zip.EntryFilenames.Contains(candidate) Then
-        ///           Console.WriteLine("The file '{0}' exists in the zip archive '{1}'", _
-        ///                       candidate, _
-        ///                       zipFileName)
-        ///       Else
-        ///         Console.WriteLine("The file, '{0}', does not exist in the zip archive '{1}'", _
-        ///                       candidate, _
-        ///                       zipFileName)
-        ///       End If
-        ///       Console.WriteLine
-        ///   End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <returns>
-        ///   The list of strings for the filenames contained within the Zip archive.
-        /// </returns>
-        ///
-        public System.Collections.Generic.ICollection<String> EntryFileNames
-        {
-            get
-            {
-                return _entries.Keys;
-            }
-        }
-
-
-        /// <summary>
-        ///   Returns the readonly collection of entries in the Zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   If there are no entries in the current <c>ZipFile</c>, the value returned is a
-        ///   non-null zero-element collection.  If there are entries in the zip file,
-        ///   the elements are returned in no particular order.
-        /// </para>
-        /// <para>
-        ///   This is the implied enumerator on the <c>ZipFile</c> class.  If you use a
-        ///   <c>ZipFile</c> instance in a context that expects an enumerator, you will
-        ///   get this collection.
-        /// </para>
-        /// </remarks>
-        /// <seealso cref="EntriesSorted"/>
-        public System.Collections.Generic.ICollection<ZipEntry> Entries
-        {
-            get
-            {
-                return _entries.Values;
-            }
-        }
-
-
-        /// <summary>
-        ///   Returns a readonly collection of entries in the Zip archive, sorted by FileName.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   If there are no entries in the current <c>ZipFile</c>, the value returned
-        ///   is a non-null zero-element collection.  If there are entries in the zip
-        ///   file, the elements are returned sorted by the name of the entry.
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example fills a Windows Forms ListView with the entries in a zip file.
-        ///
-        /// <code lang="C#">
-        /// using (ZipFile zip = ZipFile.Read(zipFile))
-        /// {
-        ///     foreach (ZipEntry entry in zip.EntriesSorted)
-        ///     {
-        ///         ListViewItem item = new ListViewItem(n.ToString());
-        ///         n++;
-        ///         string[] subitems = new string[] {
-        ///             entry.FileName.Replace("/","\\"),
-        ///             entry.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
-        ///             entry.UncompressedSize.ToString(),
-        ///             String.Format("{0,5:F0}%", entry.CompressionRatio),
-        ///             entry.CompressedSize.ToString(),
-        ///             (entry.UsesEncryption) ? "Y" : "N",
-        ///             String.Format("{0:X8}", entry.Crc)};
-        ///
-        ///         foreach (String s in subitems)
-        ///         {
-        ///             ListViewItem.ListViewSubItem subitem = new ListViewItem.ListViewSubItem();
-        ///             subitem.Text = s;
-        ///             item.SubItems.Add(subitem);
-        ///         }
-        ///
-        ///         this.listView1.Items.Add(item);
-        ///     }
-        /// }
-        /// </code>
-        /// </example>
-        ///
-        /// <seealso cref="Entries"/>
-        public System.Collections.Generic.ICollection<ZipEntry> EntriesSorted
-        {
-            get
-            {
-                var coll = new System.Collections.Generic.List<ZipEntry>();
-                foreach (var e in this.Entries)
-                {
-                    coll.Add(e);
-                }
-                StringComparison sc = (CaseSensitiveRetrieval) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
-
-                coll.Sort((x, y) => { return String.Compare(x.FileName, y.FileName, sc); });
-                return coll.AsReadOnly();
-            }
-        }
-
-
-        /// <summary>
-        /// Returns the number of entries in the Zip archive.
-        /// </summary>
-        public int Count
-        {
-            get
-            {
-                return _entries.Count;
-            }
-        }
-
-
-
-        /// <summary>
-        ///   Removes the given <c>ZipEntry</c> from the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   After calling <c>RemoveEntry</c>, the application must call <c>Save</c> to
-        ///   make the changes permanent.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <exception cref="System.ArgumentException">
-        ///   Thrown if the specified <c>ZipEntry</c> does not exist in the <c>ZipFile</c>.
-        /// </exception>
-        ///
-        /// <example>
-        ///   In this example, all entries in the zip archive dating from before
-        ///   December 31st, 2007, are removed from the archive.  This is actually much
-        ///   easier if you use the RemoveSelectedEntries method.  But I needed an
-        ///   example for RemoveEntry, so here it is.
-        /// <code>
-        /// String ZipFileToRead = "ArchiveToModify.zip";
-        /// System.DateTime Threshold = new System.DateTime(2007,12,31);
-        /// using (ZipFile zip = ZipFile.Read(ZipFileToRead))
-        /// {
-        ///   var EntriesToRemove = new System.Collections.Generic.List&lt;ZipEntry&gt;();
-        ///   foreach (ZipEntry e in zip)
-        ///   {
-        ///     if (e.LastModified &lt; Threshold)
-        ///     {
-        ///       // We cannot remove the entry from the list, within the context of
-        ///       // an enumeration of said list.
-        ///       // So we add the doomed entry to a list to be removed later.
-        ///       EntriesToRemove.Add(e);
-        ///     }
-        ///   }
-        ///
-        ///   // actually remove the doomed entries.
-        ///   foreach (ZipEntry zombie in EntriesToRemove)
-        ///     zip.RemoveEntry(zombie);
-        ///
-        ///   zip.Comment= String.Format("This zip archive was updated at {0}.",
-        ///                              System.DateTime.Now.ToString("G"));
-        ///
-        ///   // save with a different name
-        ///   zip.Save("Archive-Updated.zip");
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        ///   Dim ZipFileToRead As String = "ArchiveToModify.zip"
-        ///   Dim Threshold As New DateTime(2007, 12, 31)
-        ///   Using zip As ZipFile = ZipFile.Read(ZipFileToRead)
-        ///       Dim EntriesToRemove As New System.Collections.Generic.List(Of ZipEntry)
-        ///       Dim e As ZipEntry
-        ///       For Each e In zip
-        ///           If (e.LastModified &lt; Threshold) Then
-        ///               ' We cannot remove the entry from the list, within the context of
-        ///               ' an enumeration of said list.
-        ///               ' So we add the doomed entry to a list to be removed later.
-        ///               EntriesToRemove.Add(e)
-        ///           End If
-        ///       Next
-        ///
-        ///       ' actually remove the doomed entries.
-        ///       Dim zombie As ZipEntry
-        ///       For Each zombie In EntriesToRemove
-        ///           zip.RemoveEntry(zombie)
-        ///       Next
-        ///       zip.Comment = String.Format("This zip archive was updated at {0}.", DateTime.Now.ToString("G"))
-        ///       'save as a different name
-        ///       zip.Save("Archive-Updated.zip")
-        ///   End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="entry">
-        /// The <c>ZipEntry</c> to remove from the zip.
-        /// </param>
-        ///
-        /// <seealso cref="Ionic.Zip.ZipFile.RemoveSelectedEntries(string)"/>
-        ///
-        public void RemoveEntry(ZipEntry entry)
-        {
-            //if (!_entries.Values.Contains(entry))
-            //    throw new ArgumentException("The entry you specified does not exist in the zip archive.");
-            if (entry == null)
-                throw new ArgumentNullException("entry");
-
-            _entries.Remove(SharedUtilities.NormalizePathForUseInZipFile(entry.FileName));
-            _zipEntriesAsList = null;
-
-#if NOTNEEDED
-            if (_direntries != null)
-            {
-                bool FoundAndRemovedDirEntry = false;
-                foreach (ZipDirEntry de1 in _direntries)
-                {
-                    if (entry.FileName == de1.FileName)
-                    {
-                        _direntries.Remove(de1);
-                        FoundAndRemovedDirEntry = true;
-                        break;
-                    }
-                }
-
-                if (!FoundAndRemovedDirEntry)
-                    throw new BadStateException("The entry to be removed was not found in the directory.");
-            }
-#endif
-            _contentsChanged = true;
-        }
-
-
-
-
-        /// <summary>
-        /// Removes the <c>ZipEntry</c> with the given filename from the zip archive.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   After calling <c>RemoveEntry</c>, the application must call <c>Save</c> to
-        ///   make the changes permanent.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <exception cref="System.InvalidOperationException">
-        ///   Thrown if the <c>ZipFile</c> is not updatable.
-        /// </exception>
-        ///
-        /// <exception cref="System.ArgumentException">
-        ///   Thrown if a <c>ZipEntry</c> with the specified filename does not exist in
-        ///   the <c>ZipFile</c>.
-        /// </exception>
-        ///
-        /// <example>
-        ///
-        ///   This example shows one way to remove an entry with a given filename from
-        ///   an existing zip archive.
-        ///
-        /// <code>
-        /// String zipFileToRead= "PackedDocuments.zip";
-        /// string candidate = "DatedMaterial.xps";
-        /// using (ZipFile zip = ZipFile.Read(zipFileToRead))
-        /// {
-        ///   if (zip.EntryFilenames.Contains(candidate))
-        ///   {
-        ///     zip.RemoveEntry(candidate);
-        ///     zip.Comment= String.Format("The file '{0}' has been removed from this archive.",
-        ///                                Candidate);
-        ///     zip.Save();
-        ///   }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        ///   Dim zipFileToRead As String = "PackedDocuments.zip"
-        ///   Dim candidate As String = "DatedMaterial.xps"
-        ///   Using zip As ZipFile = ZipFile.Read(zipFileToRead)
-        ///       If zip.EntryFilenames.Contains(candidate) Then
-        ///           zip.RemoveEntry(candidate)
-        ///           zip.Comment = String.Format("The file '{0}' has been removed from this archive.", Candidate)
-        ///           zip.Save
-        ///       End If
-        ///   End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="fileName">
-        /// The name of the file, including any directory path, to remove from the zip.
-        /// The filename match is not case-sensitive by default; you can use the
-        /// <c>CaseSensitiveRetrieval</c> property to change this behavior. The
-        /// pathname can use forward-slashes or backward slashes.
-        /// </param>
-        ///
-        public void RemoveEntry(String fileName)
-        {
-            string modifiedName = ZipEntry.NameInArchive(fileName, null);
-            ZipEntry e = this[modifiedName];
-            if (e == null)
-                throw new ArgumentException("The entry you specified was not found in the zip archive.");
-
-            RemoveEntry(e);
-        }
-
-
-        #endregion
-
-        #region Destructors and Disposers
-
-        //         /// <summary>
-        //         /// This is the class Destructor, which gets called implicitly when the instance
-        //         /// is destroyed.  Because the <c>ZipFile</c> type implements IDisposable, this
-        //         /// method calls Dispose(false).
-        //         /// </summary>
-        //         ~ZipFile()
-        //         {
-        //             // call Dispose with false.  Since we're in the
-        //             // destructor call, the managed resources will be
-        //             // disposed of anyways.
-        //             Dispose(false);
-        //         }
-
-        /// <summary>
-        ///   Closes the read and write streams associated
-        ///   to the <c>ZipFile</c>, if necessary.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   The Dispose() method is generally employed implicitly, via a <c>using(..) {..}</c>
-        ///   statement. (<c>Using...End Using</c> in VB) If you do not employ a using
-        ///   statement, insure that your application calls Dispose() explicitly.  For
-        ///   example, in a Powershell application, or an application that uses the COM
-        ///   interop interface, you must call Dispose() explicitly.
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example extracts an entry selected by name, from the Zip file to the
-        /// Console.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(zipfile))
-        /// {
-        ///   foreach (ZipEntry e in zip)
-        ///   {
-        ///     if (WantThisEntry(e.FileName))
-        ///       zip.Extract(e.FileName, Console.OpenStandardOutput());
-        ///   }
-        /// } // Dispose() is called implicitly here.
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using zip As ZipFile = ZipFile.Read(zipfile)
-        ///     Dim e As ZipEntry
-        ///     For Each e In zip
-        ///       If WantThisEntry(e.FileName) Then
-        ///           zip.Extract(e.FileName, Console.OpenStandardOutput())
-        ///       End If
-        ///     Next
-        /// End Using ' Dispose is implicity called here
-        /// </code>
-        /// </example>
-        public void Dispose()
-        {
-            // dispose of the managed and unmanaged resources
-            Dispose(true);
-
-            // tell the GC that the Finalize process no longer needs
-            // to be run for this object.
-            GC.SuppressFinalize(this);
-        }
-
-        /// <summary>
-        ///   Disposes any managed resources, if the flag is set, then marks the
-        ///   instance disposed.  This method is typically not called explicitly from
-        ///   application code.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Applications should call <see cref="Dispose()">the no-arg Dispose method</see>.
-        /// </remarks>
-        ///
-        /// <param name="disposeManagedResources">
-        ///   indicates whether the method should dispose streams or not.
-        /// </param>
-        protected virtual void Dispose(bool disposeManagedResources)
-        {
-            if (!this._disposed)
-            {
-                if (disposeManagedResources)
-                {
-                    // dispose managed resources
-                    if (_ReadStreamIsOurs)
-                    {
-                        if (_readstream != null)
-                        {
-                            // workitem 7704
-#if NETCF
-                            _readstream.Close();
-#else
-                            _readstream.Dispose();
-#endif
-                            _readstream = null;
-                        }
-                    }
-                    // only dispose the writestream if there is a backing file
-                    if ((_temporaryFileName != null) && (_name != null))
-                        if (_writestream != null)
-                        {
-                            // workitem 7704
-#if NETCF
-                            _writestream.Close();
-#else
-                            _writestream.Dispose();
-#endif
-                            _writestream = null;
-                        }
-
-#if !NETCF
-                    // workitem 10030
-                    if (this.ParallelDeflater != null)
-                    {
-                        this.ParallelDeflater.Dispose();
-                        this.ParallelDeflater = null;
-                    }
-#endif
-                }
-                this._disposed = true;
-            }
-        }
-        #endregion
-
-
-        #region private properties
-
-        internal Stream ReadStream
-        {
-            get
-            {
-                if (_readstream == null)
-                {
-                    if (_readName != null || _name !=null)
-                    {
-                        _readstream = File.Open(_readName ?? _name,
-                                                FileMode.Open,
-                                                FileAccess.Read,
-                                                FileShare.Read | FileShare.Write);
-                        _ReadStreamIsOurs = true;
-                    }
-                }
-                return _readstream;
-            }
-        }
-
-
-
-        private Stream WriteStream
-        {
-            // workitem 9763
-            get
-            {
-                if (_writestream != null) return _writestream;
-                if (_name == null) return _writestream;
-
-                if (_maxOutputSegmentSize != 0)
-                {
-                    _writestream = ZipSegmentedStream.ForWriting(this._name, _maxOutputSegmentSize);
-                    return _writestream;
-                }
-
-                SharedUtilities.CreateAndOpenUniqueTempFile(TempFileFolder ?? Path.GetDirectoryName(_name),
-                                                            out _writestream,
-                                                            out _temporaryFileName);
-                return _writestream;
-            }
-            set
-            {
-                if (value != null)
-                    throw new ZipException("Cannot set the stream to a non-null value.");
-                _writestream = null;
-            }
-        }
-        #endregion
-
-        #region private fields
-        private TextWriter _StatusMessageTextWriter;
-        private bool _CaseSensitiveRetrieval;
-        private Stream _readstream;
-        private Stream _writestream;
-        private UInt16 _versionMadeBy;
-        private UInt16 _versionNeededToExtract;
-        private UInt32 _diskNumberWithCd;
-        private Int32 _maxOutputSegmentSize;
-        private UInt32 _numberOfSegmentsForMostRecentSave;
-        private ZipErrorAction _zipErrorAction;
-        private bool _disposed;
-        //private System.Collections.Generic.List<ZipEntry> _entries;
-        private System.Collections.Generic.Dictionary<String, ZipEntry> _entries;
-        private List<ZipEntry> _zipEntriesAsList;
-        private string _name;
-        private string _readName;
-        private string _Comment;
-        internal string _Password;
-        private bool _emitNtfsTimes = true;
-        private bool _emitUnixTimes;
-        private Ionic.Zlib.CompressionStrategy _Strategy = Ionic.Zlib.CompressionStrategy.Default;
-        private Ionic.Zip.CompressionMethod _compressionMethod = Ionic.Zip.CompressionMethod.Deflate;
-        private bool _fileAlreadyExists;
-        private string _temporaryFileName;
-        private bool _contentsChanged;
-        private bool _hasBeenSaved;
-        private String _TempFileFolder;
-        private bool _ReadStreamIsOurs = true;
-        private object LOCK = new object();
-        private bool _saveOperationCanceled;
-        private bool _extractOperationCanceled;
-        private bool _addOperationCanceled;
-        private EncryptionAlgorithm _Encryption;
-        private bool _JustSaved;
-        private long _locEndOfCDS = -1;
-        private uint _OffsetOfCentralDirectory;
-        private Int64 _OffsetOfCentralDirectory64;
-        private Nullable<bool> _OutputUsesZip64;
-        internal bool _inExtractAll;
-        private System.Text.Encoding _alternateEncoding = System.Text.Encoding.ASCII; // UTF-8
-        private ZipOption _alternateEncodingUsage = ZipOption.Never;
-        private static System.Text.Encoding _defaultEncoding = System.Text.Encoding.ASCII;
-
-        private int _BufferSize = BufferSizeDefault;
-
-#if !NETCF
-        internal Ionic.Zlib.ParallelDeflateOutputStream ParallelDeflater;
-        private long _ParallelDeflateThreshold;
-        private int _maxBufferPairs = 16;
-#endif
-
-        internal Zip64Option _zip64 = Zip64Option.Default;
-#pragma warning disable 649
-        private bool _SavingSfx;
-#pragma warning restore 649
-
-        /// <summary>
-        ///   Default size of the buffer used for IO.
-        /// </summary>
-        public static readonly int BufferSizeDefault = 32768;
-
-        #endregion
-    }
-
-    /// <summary>
-    ///   Options for using ZIP64 extensions when saving zip archives.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///
-    /// <para>
-    ///   Designed many years ago, the <see
-    ///   href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">original zip
-    ///   specification from PKWARE</see> allowed for 32-bit quantities for the
-    ///   compressed and uncompressed sizes of zip entries, as well as a 32-bit quantity
-    ///   for specifying the length of the zip archive itself, and a maximum of 65535
-    ///   entries.  These limits are now regularly exceeded in many backup and archival
-    ///   scenarios.  Recently, PKWare added extensions to the original zip spec, called
-    ///   "ZIP64 extensions", to raise those limitations.  This property governs whether
-    ///   DotNetZip will use those extensions when writing zip archives. The use of
-    ///   these extensions is optional and explicit in DotNetZip because, despite the
-    ///   status of ZIP64 as a bona fide standard, many other zip tools and libraries do
-    ///   not support ZIP64, and therefore a zip file with ZIP64 extensions may be
-    ///   unreadable by some of those other tools.
-    /// </para>
-    ///
-    /// <para>
-    ///   Set this property to <see cref="Zip64Option.Always"/> to always use ZIP64
-    ///   extensions when saving, regardless of whether your zip archive needs it.
-    ///   Suppose you add 5 files, each under 100k, to a ZipFile. If you specify Always
-    ///   for this flag, you will get a ZIP64 archive, though the archive does not need
-    ///   to use ZIP64 because none of the original zip limits had been exceeded.
-    /// </para>
-    ///
-    /// <para>
-    ///   Set this property to <see cref="Zip64Option.Never"/> to tell the DotNetZip
-    ///   library to never use ZIP64 extensions.  This is useful for maximum
-    ///   compatibility and interoperability, at the expense of the capability of
-    ///   handling large files or large archives.  NB: Windows Explorer in Windows XP
-    ///   and Windows Vista cannot currently extract files from a zip64 archive, so if
-    ///   you want to guarantee that a zip archive produced by this library will work in
-    ///   Windows Explorer, use <c>Never</c>. If you set this property to <see
-    ///   cref="Zip64Option.Never"/>, and your application creates a zip that would
-    ///   exceed one of the Zip limits, the library will throw an exception while saving
-    ///   the zip file.
-    /// </para>
-    ///
-    /// <para>
-    ///   Set this property to <see cref="Zip64Option.AsNecessary"/> to tell the
-    ///   DotNetZip library to use the ZIP64 extensions when required by the
-    ///   entry. After the file is compressed, the original and compressed sizes are
-    ///   checked, and if they exceed the limits described above, then zip64 can be
-    ///   used. That is the general idea, but there is an additional wrinkle when saving
-    ///   to a non-seekable device, like the ASP.NET <c>Response.OutputStream</c>, or
-    ///   <c>Console.Out</c>.  When using non-seekable streams for output, the entry
-    ///   header - which indicates whether zip64 is in use - is emitted before it is
-    ///   known if zip64 is necessary.  It is only after all entries have been saved
-    ///   that it can be known if ZIP64 will be required.  On seekable output streams,
-    ///   after saving all entries, the library can seek backward and re-emit the zip
-    ///   file header to be consistent with the actual ZIP64 requirement.  But using a
-    ///   non-seekable output stream, the library cannot seek backward, so the header
-    ///   can never be changed. In other words, the archive's use of ZIP64 extensions is
-    ///   not alterable after the header is emitted.  Therefore, when saving to
-    ///   non-seekable streams, using <see cref="Zip64Option.AsNecessary"/> is the same
-    ///   as using <see cref="Zip64Option.Always"/>: it will always produce a zip
-    ///   archive that uses ZIP64 extensions.
-    /// </para>
-    ///
-    /// </remarks>
-    internal enum Zip64Option
-    {
-        /// <summary>
-        /// The default behavior, which is "Never".
-        /// (For COM clients, this is a 0 (zero).)
-        /// </summary>
-        Default = 0,
-        /// <summary>
-        /// Do not use ZIP64 extensions when writing zip archives.
-        /// (For COM clients, this is a 0 (zero).)
-        /// </summary>
-        Never = 0,
-        /// <summary>
-        /// Use ZIP64 extensions when writing zip archives, as necessary.
-        /// For example, when a single entry exceeds 0xFFFFFFFF in size, or when the archive as a whole
-        /// exceeds 0xFFFFFFFF in size, or when there are more than 65535 entries in an archive.
-        /// (For COM clients, this is a 1.)
-        /// </summary>
-        AsNecessary = 1,
-        /// <summary>
-        /// Always use ZIP64 extensions when writing zip archives, even when unnecessary.
-        /// (For COM clients, this is a 2.)
-        /// </summary>
-        Always
-    }
-
-
-    /// <summary>
-    ///  An enum representing the values on a three-way toggle switch
-    ///  for various options in the library. This might be used to
-    ///  specify whether to employ a particular text encoding, or to use
-    ///  ZIP64 extensions, or some other option.
-    /// </summary>
-    internal enum ZipOption
-    {
-        /// <summary>
-        /// The default behavior. This is the same as "Never".
-        /// (For COM clients, this is a 0 (zero).)
-        /// </summary>
-        Default = 0,
-        /// <summary>
-        /// Never use the associated option.
-        /// (For COM clients, this is a 0 (zero).)
-        /// </summary>
-        Never = 0,
-        /// <summary>
-        /// Use the associated behavior "as necessary."
-        /// (For COM clients, this is a 1.)
-        /// </summary>
-        AsNecessary = 1,
-        /// <summary>
-        /// Use the associated behavior Always, whether necessary or not.
-        /// (For COM clients, this is a 2.)
-        /// </summary>
-        Always
-    }
-
-
-    enum AddOrUpdateAction
-    {
-        AddOnly = 0,
-        AddOrUpdate
-    }
-
-}
-
-
-
-// ==================================================================
-//
-// Information on the ZIP format:
-//
-// From
-// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
-//
-//  Overall .ZIP file format:
-//
-//     [local file header 1]
-//     [file data 1]
-//     [data descriptor 1]  ** sometimes
-//     .
-//     .
-//     .
-//     [local file header n]
-//     [file data n]
-//     [data descriptor n]   ** sometimes
-//     [archive decryption header]
-//     [archive extra data record]
-//     [central directory]
-//     [zip64 end of central directory record]
-//     [zip64 end of central directory locator]
-//     [end of central directory record]
-//
-// Local File Header format:
-//         local file header signature ... 4 bytes  (0x04034b50)
-//         version needed to extract ..... 2 bytes
-//         general purpose bit field ..... 2 bytes
-//         compression method ............ 2 bytes
-//         last mod file time ............ 2 bytes
-//         last mod file date............. 2 bytes
-//         crc-32 ........................ 4 bytes
-//         compressed size................ 4 bytes
-//         uncompressed size.............. 4 bytes
-//         file name length............... 2 bytes
-//         extra field length ............ 2 bytes
-//         file name                       varies
-//         extra field                     varies
-//
-//
-// Data descriptor:  (used only when bit 3 of the general purpose bitfield is set)
-//         (although, I have found zip files where bit 3 is not set, yet this descriptor is present!)
-//         local file header signature     4 bytes  (0x08074b50)  ** sometimes!!! Not always
-//         crc-32                          4 bytes
-//         compressed size                 4 bytes
-//         uncompressed size               4 bytes
-//
-//
-//   Central directory structure:
-//
-//       [file header 1]
-//       .
-//       .
-//       .
-//       [file header n]
-//       [digital signature]
-//
-//
-//       File header:  (This is a ZipDirEntry)
-//         central file header signature   4 bytes  (0x02014b50)
-//         version made by                 2 bytes
-//         version needed to extract       2 bytes
-//         general purpose bit flag        2 bytes
-//         compression method              2 bytes
-//         last mod file time              2 bytes
-//         last mod file date              2 bytes
-//         crc-32                          4 bytes
-//         compressed size                 4 bytes
-//         uncompressed size               4 bytes
-//         file name length                2 bytes
-//         extra field length              2 bytes
-//         file comment length             2 bytes
-//         disk number start               2 bytes
-//         internal file attributes **     2 bytes
-//         external file attributes ***    4 bytes
-//         relative offset of local header 4 bytes
-//         file name (variable size)
-//         extra field (variable size)
-//         file comment (variable size)
-//
-// ** The internal file attributes, near as I can tell,
-// uses 0x01 for a file and a 0x00 for a directory.
-//
-// ***The external file attributes follows the MS-DOS file attribute byte, described here:
-// at http://support.microsoft.com/kb/q125019/
-// 0x0010 => directory
-// 0x0020 => file
-//
-//
-// End of central directory record:
-//
-//         end of central dir signature    4 bytes  (0x06054b50)
-//         number of this disk             2 bytes
-//         number of the disk with the
-//         start of the central directory  2 bytes
-//         total number of entries in the
-//         central directory on this disk  2 bytes
-//         total number of entries in
-//         the central directory           2 bytes
-//         size of the central directory   4 bytes
-//         offset of start of central
-//         directory with respect to
-//         the starting disk number        4 bytes
-//         .ZIP file comment length        2 bytes
-//         .ZIP file comment       (variable size)
-//
-// date and time are packed values, as MSDOS did them
-// time: bits 0-4 : seconds (divided by 2)
-//            5-10: minute
-//            11-15: hour
-// date  bits 0-4 : day
-//            5-8: month
-//            9-15 year (since 1980)
-//
-// see http://msdn.microsoft.com/en-us/library/ms724274(VS.85).aspx
-
diff --git a/EPPlus/Packaging/DotNetZip/ZipFile.x-IEnumerable.cs b/EPPlus/Packaging/DotNetZip/ZipFile.x-IEnumerable.cs
deleted file mode 100644
index bb607b1..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipFile.x-IEnumerable.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// ZipFile.x-IEnumerable.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006, 2007, 2008, 2009 Dino Chiesa and Microsoft Corporation.
-// 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: <2009-December-26 15:13:26>
-//
-// ------------------------------------------------------------------
-//
-// This module defines smoe methods for IEnumerable support. It is
-// particularly important for COM to have these things in a separate module.
-//
-// ------------------------------------------------------------------
-
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-
-    // For some weird reason, the method with the DispId(-4) attribute, which is used as
-    // the _NewEnum() method, and which is required to get enumeration to work from COM
-    // environments like VBScript and Javascript (etc) must be the LAST MEMBER in the
-    // source.  In the event of Partial classes, it needs to be the last member defined
-    // in the last source module.  The source modules are ordered alphabetically by
-    // filename.  Not sure why this is true. In any case, we put the enumeration stuff
-    // here in this oddly-named module, for this reason.
-    //
-
-
-
-    internal partial class ZipFile
-    {
-
-
-
-
-        /// <summary>
-        /// Generic IEnumerator support, for use of a ZipFile in an enumeration.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// You probably do not want to call <c>GetEnumerator</c> explicitly. Instead
-        /// it is implicitly called when you use a <see langword="foreach"/> loop in C#, or a
-        /// <c>For Each</c> loop in VB.NET.
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example reads a zipfile of a given name, then enumerates the
-        /// entries in that zip file, and displays the information about each
-        /// entry on the Console.
-        /// <code>
-        /// using (ZipFile zip = ZipFile.Read(zipfile))
-        /// {
-        ///   bool header = true;
-        ///   foreach (ZipEntry e in zip)
-        ///   {
-        ///     if (header)
-        ///     {
-        ///        System.Console.WriteLine("Zipfile: {0}", zip.Name);
-        ///        System.Console.WriteLine("Version Needed: 0x{0:X2}", e.VersionNeeded);
-        ///        System.Console.WriteLine("BitField: 0x{0:X2}", e.BitField);
-        ///        System.Console.WriteLine("Compression Method: 0x{0:X2}", e.CompressionMethod);
-        ///        System.Console.WriteLine("\n{1,-22} {2,-6} {3,4}   {4,-8}  {0}",
-        ///                     "Filename", "Modified", "Size", "Ratio", "Packed");
-        ///        System.Console.WriteLine(new System.String('-', 72));
-        ///        header = false;
-        ///     }
-        ///
-        ///     System.Console.WriteLine("{1,-22} {2,-6} {3,4:F0}%   {4,-8}  {0}",
-        ///                 e.FileName,
-        ///                 e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
-        ///                 e.UncompressedSize,
-        ///                 e.CompressionRatio,
-        ///                 e.CompressedSize);
-        ///
-        ///     e.Extract();
-        ///   }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        ///   Dim ZipFileToExtract As String = "c:\foo.zip"
-        ///   Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
-        ///       Dim header As Boolean = True
-        ///       Dim e As ZipEntry
-        ///       For Each e In zip
-        ///           If header Then
-        ///               Console.WriteLine("Zipfile: {0}", zip.Name)
-        ///               Console.WriteLine("Version Needed: 0x{0:X2}", e.VersionNeeded)
-        ///               Console.WriteLine("BitField: 0x{0:X2}", e.BitField)
-        ///               Console.WriteLine("Compression Method: 0x{0:X2}", e.CompressionMethod)
-        ///               Console.WriteLine(ChrW(10) &amp; "{1,-22} {2,-6} {3,4}   {4,-8}  {0}", _
-        ///                 "Filename", "Modified", "Size", "Ratio", "Packed" )
-        ///               Console.WriteLine(New String("-"c, 72))
-        ///               header = False
-        ///           End If
-        ///           Console.WriteLine("{1,-22} {2,-6} {3,4:F0}%   {4,-8}  {0}", _
-        ///             e.FileName, _
-        ///             e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"), _
-        ///             e.UncompressedSize, _
-        ///             e.CompressionRatio, _
-        ///             e.CompressedSize )
-        ///           e.Extract
-        ///       Next
-        ///   End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <returns>A generic enumerator suitable for use  within a foreach loop.</returns>
-        public System.Collections.Generic.IEnumerator<ZipEntry> GetEnumerator()
-        {
-            foreach (ZipEntry e in _entries.Values)
-                yield return e;
-        }
-
-        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
-        {
-            return GetEnumerator();
-        }
-
-
-        /// <summary>
-        /// An IEnumerator, for use of a ZipFile in a foreach construct.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// This method is included for COM support.  An application generally does not call
-        /// this method directly.  It is called implicitly by COM clients when enumerating
-        /// the entries in the ZipFile instance.  In VBScript, this is done with a <c>For Each</c>
-        /// statement.  In Javascript, this is done with <c>new Enumerator(zipfile)</c>.
-        /// </remarks>
-        ///
-        /// <returns>
-        /// The IEnumerator over the entries in the ZipFile.
-        /// </returns>
-        [System.Runtime.InteropServices.DispId(-4)]
-        public System.Collections.IEnumerator GetNewEnum()          // the name of this method is not significant
-        {
-            return GetEnumerator();
-        }
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipInputStream.cs b/EPPlus/Packaging/DotNetZip/ZipInputStream.cs
deleted file mode 100644
index 30d15ad..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipInputStream.cs
+++ /dev/null
@@ -1,829 +0,0 @@
-// ZipInputStream.cs
-//
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2010 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-31 14:48:30>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZipInputStream class, which is a stream metaphor for
-// reading zip files.  This class does not depend on Ionic.Zip.ZipFile, but rather
-// stands alongside it as an alternative "container" for ZipEntry, when reading zips.
-//
-// It adds one interesting method to the normal "stream" interface: GetNextEntry.
-//
-// ------------------------------------------------------------------
-//
-
-using System;
-using System.Threading;
-using System.Collections.Generic;
-using System.IO;
-using Ionic.Zip;
-using OfficeOpenXml.Packaging.Ionic.Zip;
-using OfficeOpenXml.Packaging.Ionic.Crc;
-
-namespace  Ionic.Zip
-{
-    /// <summary>
-    ///   Provides a stream metaphor for reading zip files.
-    /// </summary>
-    ///
-    /// <remarks>
-    /// <para>
-    ///   This class provides an alternative programming model for reading zip files to
-    ///   the one enabled by the <see cref="ZipFile"/> class.  Use this when reading zip
-    ///   files, as an alternative to the <see cref="ZipFile"/> class, when you would
-    ///   like to use a Stream class to read the file.
-    /// </para>
-    ///
-    /// <para>
-    ///   Some application designs require a readable stream for input. This stream can
-    ///   be used to read a zip file, and extract entries.
-    /// </para>
-    ///
-    /// <para>
-    ///   Both the <c>ZipInputStream</c> class and the <c>ZipFile</c> class can be used
-    ///   to read and extract zip files.  Both of them support many of the common zip
-    ///   features, including Unicode, different compression levels, and ZIP64.  The
-    ///   programming models differ. For example, when extracting entries via calls to
-    ///   the <c>GetNextEntry()</c> and <c>Read()</c> methods on the
-    ///   <c>ZipInputStream</c> class, the caller is responsible for creating the file,
-    ///   writing the bytes into the file, setting the attributes on the file, and
-    ///   setting the created, last modified, and last accessed timestamps on the
-    ///   file. All of these things are done automatically by a call to <see
-    ///   cref="ZipEntry.Extract()">ZipEntry.Extract()</see>.  For this reason, the
-    ///   <c>ZipInputStream</c> is generally recommended for when your application wants
-    ///   to extract the data, without storing that data into a file.
-    /// </para>
-    ///
-    /// <para>
-    ///   Aside from the obvious differences in programming model, there are some
-    ///   differences in capability between the <c>ZipFile</c> class and the
-    ///   <c>ZipInputStream</c> class.
-    /// </para>
-    ///
-    /// <list type="bullet">
-    ///   <item>
-    ///     <c>ZipFile</c> can be used to create or update zip files, or read and
-    ///     extract zip files. <c>ZipInputStream</c> can be used only to read and
-    ///     extract zip files. If you want to use a stream to create zip files, check
-    ///     out the <see cref="ZipOutputStream"/>.
-    ///   </item>
-    ///
-    ///   <item>
-    ///     <c>ZipInputStream</c> cannot read segmented or spanned
-    ///     zip files.
-    ///   </item>
-    ///
-    ///   <item>
-    ///     <c>ZipInputStream</c> will not read Zip file comments.
-    ///   </item>
-    ///
-    ///   <item>
-    ///     When reading larger files, <c>ZipInputStream</c> will always underperform
-    ///     <c>ZipFile</c>. This is because the <c>ZipInputStream</c> does a full scan on the
-    ///     zip file, while the <c>ZipFile</c> class reads the central directory of the
-    ///     zip file.
-    ///   </item>
-    ///
-    /// </list>
-    ///
-    /// </remarks>
-    internal class ZipInputStream : Stream
-    {
-        /// <summary>
-        ///   Create a <c>ZipInputStream</c>, wrapping it around an existing stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   While the <see cref="ZipFile"/> class is generally easier
-        ///   to use, this class provides an alternative to those
-        ///   applications that want to read from a zipfile directly,
-        ///   using a <see cref="System.IO.Stream"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   Both the <c>ZipInputStream</c> class and the <c>ZipFile</c> class can be used
-        ///   to read and extract zip files.  Both of them support many of the common zip
-        ///   features, including Unicode, different compression levels, and ZIP64.  The
-        ///   programming models differ. For example, when extracting entries via calls to
-        ///   the <c>GetNextEntry()</c> and <c>Read()</c> methods on the
-        ///   <c>ZipInputStream</c> class, the caller is responsible for creating the file,
-        ///   writing the bytes into the file, setting the attributes on the file, and
-        ///   setting the created, last modified, and last accessed timestamps on the
-        ///   file. All of these things are done automatically by a call to <see
-        ///   cref="ZipEntry.Extract()">ZipEntry.Extract()</see>.  For this reason, the
-        ///   <c>ZipInputStream</c> is generally recommended for when your application wants
-        ///   to extract the data, without storing that data into a file.
-        /// </para>
-        ///
-        /// <para>
-        ///   Aside from the obvious differences in programming model, there are some
-        ///   differences in capability between the <c>ZipFile</c> class and the
-        ///   <c>ZipInputStream</c> class.
-        /// </para>
-        ///
-        /// <list type="bullet">
-        ///   <item>
-        ///   <c>ZipFile</c> can be used to create or update zip files, or read and extract
-        ///   zip files. <c>ZipInputStream</c> can be used only to read and extract zip
-        ///     files. If you want to use a stream to create zip files, check out the <see
-        ///     cref="ZipOutputStream"/>.
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <c>ZipInputStream</c> cannot read segmented or spanned
-        ///     zip files.
-        ///   </item>
-        ///
-        ///   <item>
-        ///     <c>ZipInputStream</c> will not read Zip file comments.
-        ///   </item>
-        ///
-        ///   <item>
-        ///     When reading larger files, <c>ZipInputStream</c> will always underperform
-        ///     <c>ZipFile</c>. This is because the <c>ZipInputStream</c> does a full scan on the
-        ///     zip file, while the <c>ZipFile</c> class reads the central directory of the
-        ///     zip file.
-        ///   </item>
-        ///
-        /// </list>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="stream">
-        ///   The stream to read. It must be readable. This stream will be closed at
-        ///   the time the <c>ZipInputStream</c> is closed.
-        /// </param>
-        ///
-        /// <example>
-        ///
-        ///   This example shows how to read a zip file, and extract entries, using the
-        ///   <c>ZipInputStream</c> class.
-        ///
-        /// <code lang="C#">
-        /// private void Unzip()
-        /// {
-        ///     byte[] buffer= new byte[2048];
-        ///     int n;
-        ///     using (var raw = File.Open(inputFileName, FileMode.Open, FileAccess.Read))
-        ///     {
-        ///         using (var input= new ZipInputStream(raw))
-        ///         {
-        ///             ZipEntry e;
-        ///             while (( e = input.GetNextEntry()) != null)
-        ///             {
-        ///                 if (e.IsDirectory) continue;
-        ///                 string outputPath = Path.Combine(extractDir, e.FileName);
-        ///                 using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
-        ///                 {
-        ///                     while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
-        ///                     {
-        ///                         output.Write(buffer,0,n);
-        ///                     }
-        ///                 }
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Private Sub UnZip()
-        ///     Dim inputFileName As String = "MyArchive.zip"
-        ///     Dim extractDir As String = "extract"
-        ///     Dim buffer As Byte() = New Byte(2048) {}
-        ///     Using raw As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read)
-        ///         Using input As ZipInputStream = New ZipInputStream(raw)
-        ///             Dim e As ZipEntry
-        ///             Do While (Not e = input.GetNextEntry Is Nothing)
-        ///                 If Not e.IsDirectory Then
-        ///                     Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
-        ///                                                            FileMode.Create, FileAccess.ReadWrite)
-        ///                         Dim n As Integer
-        ///                         Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
-        ///                             output.Write(buffer, 0, n)
-        ///                         Loop
-        ///                     End Using
-        ///                 End If
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        /// End Sub
-        /// </code>
-        /// </example>
-        public ZipInputStream(Stream stream)  : this (stream, false) { }
-
-
-
-        /// <summary>
-        ///   Create a <c>ZipInputStream</c>, given the name of an existing zip file.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This constructor opens a <c>FileStream</c> for the given zipfile, and
-        ///   wraps a <c>ZipInputStream</c> around that.  See the documentation for the
-        ///   <see cref="ZipInputStream(Stream)"/> constructor for full details.
-        /// </para>
-        ///
-        /// <para>
-        ///   While the <see cref="ZipFile"/> class is generally easier
-        ///   to use, this class provides an alternative to those
-        ///   applications that want to read from a zipfile directly,
-        ///   using a <see cref="System.IO.Stream"/>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="fileName">
-        ///   The name of the filesystem file to read.
-        /// </param>
-        ///
-        /// <example>
-        ///
-        ///   This example shows how to read a zip file, and extract entries, using the
-        ///   <c>ZipInputStream</c> class.
-        ///
-        /// <code lang="C#">
-        /// private void Unzip()
-        /// {
-        ///     byte[] buffer= new byte[2048];
-        ///     int n;
-        ///     using (var input= new ZipInputStream(inputFileName))
-        ///     {
-        ///         ZipEntry e;
-        ///         while (( e = input.GetNextEntry()) != null)
-        ///         {
-        ///             if (e.IsDirectory) continue;
-        ///             string outputPath = Path.Combine(extractDir, e.FileName);
-        ///             using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
-        ///             {
-        ///                 while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
-        ///                 {
-        ///                     output.Write(buffer,0,n);
-        ///                 }
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Private Sub UnZip()
-        ///     Dim inputFileName As String = "MyArchive.zip"
-        ///     Dim extractDir As String = "extract"
-        ///     Dim buffer As Byte() = New Byte(2048) {}
-        ///     Using input As ZipInputStream = New ZipInputStream(inputFileName)
-        ///         Dim e As ZipEntry
-        ///         Do While (Not e = input.GetNextEntry Is Nothing)
-        ///             If Not e.IsDirectory Then
-        ///                 Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
-        ///                                                        FileMode.Create, FileAccess.ReadWrite)
-        ///                     Dim n As Integer
-        ///                     Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
-        ///                         output.Write(buffer, 0, n)
-        ///                     Loop
-        ///                 End Using
-        ///             End If
-        ///         Loop
-        ///     End Using
-        /// End Sub
-        /// </code>
-        /// </example>
-        public ZipInputStream(String fileName)
-        {
-            Stream stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read );
-            _Init(stream, false, fileName);
-        }
-
-
-        /// <summary>
-        ///   Create a <c>ZipInputStream</c>, explicitly specifying whether to
-        ///   keep the underlying stream open.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   See the documentation for the <see
-        ///   cref="ZipInputStream(Stream)">ZipInputStream(Stream)</see>
-        ///   constructor for a discussion of the class, and an example of how to use the class.
-        /// </remarks>
-        ///
-        /// <param name="stream">
-        ///   The stream to read from. It must be readable.
-        /// </param>
-        ///
-        /// <param name="leaveOpen">
-        ///   true if the application would like the stream
-        ///   to remain open after the <c>ZipInputStream</c> has been closed.
-        /// </param>
-        public ZipInputStream(Stream stream, bool leaveOpen)
-        {
-            _Init(stream, leaveOpen, null);
-        }
-
-        private void _Init(Stream stream, bool leaveOpen, string name)
-        {
-            _inputStream = stream;
-            if (!_inputStream.CanRead)
-                throw new ZipException("The stream must be readable.");
-            _container= new ZipContainer(this);
-            _provisionalAlternateEncoding = System.Text.Encoding.ASCII;
-            _leaveUnderlyingStreamOpen = leaveOpen;
-            _findRequired= true;
-            _name = name ?? "(stream)";
-        }
-
-
-        /// <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 ("ZipInputStream::{0}(leaveOpen({1})))", _name, _leaveUnderlyingStreamOpen);
-        }
-
-
-        /// <summary>
-        ///   The text encoding to use when reading 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 read zip archives that use something other than
-        ///   UTF-8 or IBM437, set this property to specify the code page to use when
-        ///   reading encoded filenames and comments for each <c>ZipEntry</c> in the zip
-        ///   file.
-        /// </para>
-        ///
-        /// <para>
-        ///   This property is "provisional". When the entry in the zip archive is not
-        ///   explicitly marked as using UTF-8, then IBM437 is used to decode filenames
-        ///   and comments. If a loss of data would result from using IBM436 -
-        ///   specifically when encoding and decoding is not reflexive - the codepage
-        ///   specified here is used. 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>
-        ///   When a zip file uses an arbitrary, non-UTF8 code page for encoding, there
-        ///   is no standard way for the reader application - whether DotNetZip, WinZip,
-        ///   WinRar, or something else - to know which codepage has been used for the
-        ///   entries. 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>
-        ///
-        /// </remarks>
-        public System.Text.Encoding ProvisionalAlternateEncoding
-        {
-            get
-            {
-                return _provisionalAlternateEncoding;
-            }
-            set
-            {
-                _provisionalAlternateEncoding = value;
-            }
-        }
-
-
-        /// <summary>
-        ///   Size of the work buffer to use for the ZLIB codec during decompression.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Setting this affects the performance and memory efficiency of compression
-        ///   and decompression.  For larger files, setting this to a larger size may
-        ///   improve performance, but the exact numbers vary depending on available
-        ///   memory, and a bunch of other variables. I don't have good firm
-        ///   recommendations on how to set it.  You'll have to test it yourself. Or
-        ///   just leave it alone and accept the default.
-        /// </remarks>
-        public int CodecBufferSize
-        {
-            get;
-            set;
-        }
-
-
-        /// <summary>
-        ///   Sets the password to be used on the <c>ZipInputStream</c> instance.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When reading a zip archive, this password is used to read and decrypt the
-        ///   entries that are encrypted within the zip file. When entries within a zip
-        ///   file use different passwords, set the appropriate password for the entry
-        ///   before the first call to <c>Read()</c> for each entry.
-        /// </para>
-        ///
-        /// <para>
-        ///   When reading an entry that is not encrypted, the value of this property is
-        ///   ignored.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example uses the ZipInputStream to read and extract entries from a
-        ///   zip file, using a potentially different password for each entry.
-        ///
-        /// <code lang="C#">
-        /// byte[] buffer= new byte[2048];
-        /// int n;
-        /// using (var raw = File.Open(_inputFileName, FileMode.Open, FileAccess.Read ))
-        /// {
-        ///     using (var input= new ZipInputStream(raw))
-        ///     {
-        ///         ZipEntry e;
-        ///         while (( e = input.GetNextEntry()) != null)
-        ///         {
-        ///             input.Password = PasswordForEntry(e.FileName);
-        ///             if (e.IsDirectory) continue;
-        ///             string outputPath = Path.Combine(_extractDir, e.FileName);
-        ///             using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
-        ///             {
-        ///                 while ((n= input.Read(buffer,0,buffer.Length)) > 0)
-        ///                 {
-        ///                     output.Write(buffer,0,n);
-        ///                 }
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        ///
-        /// </code>
-        /// </example>
-        public String Password
-        {
-            set
-            {
-                if (_closed)
-                {
-                    _exceptionPending = true;
-                    throw new System.InvalidOperationException("The stream has been closed.");
-                }
-                _Password = value;
-            }
-        }
-
-
-        private void SetupStream()
-        {
-            // Seek to the correct posn in the file, and open a
-            // stream that can be read.
-            _crcStream= _currentEntry.InternalOpenReader(_Password);
-            _LeftToRead = _crcStream.Length;
-            _needSetup = false;
-        }
-
-
-
-        internal Stream ReadStream
-        {
-            get
-            {
-                return _inputStream;
-            }
-        }
-
-
-        /// <summary>
-        ///   Read the data from the stream into the buffer.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The data for the zipentry will be decrypted and uncompressed, as
-        ///   necessary, before being copied into the buffer.
-        /// </para>
-        ///
-        /// <para>
-        ///   You must set the <see cref="Password"/> property before calling
-        ///   <c>Read()</c> the first time for an encrypted entry.  To determine if an
-        ///   entry is encrypted and requires a password, check the <see
-        ///   cref="ZipEntry.Encryption">ZipEntry.Encryption</see> property.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="buffer">The buffer to hold the data read from the stream.</param>
-        /// <param name="offset">the offset within the buffer to copy the first byte read.</param>
-        /// <param name="count">the number of bytes to read.</param>
-        /// <returns>the number of bytes read, after decryption and decompression.</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            if (_closed)
-            {
-                _exceptionPending = true;
-                throw new System.InvalidOperationException("The stream has been closed.");
-            }
-
-            if (_needSetup)
-                SetupStream();
-
-            if (_LeftToRead == 0) return 0;
-
-            int len = (_LeftToRead > count) ? count : (int)_LeftToRead;
-            int n = _crcStream.Read(buffer, offset, len);
-
-            _LeftToRead -= n;
-
-            if (_LeftToRead == 0)
-            {
-                int CrcResult = _crcStream.Crc;
-                _currentEntry.VerifyCrcAfterExtract(CrcResult);
-                _inputStream.Seek(_endOfEntry, SeekOrigin.Begin);
-                // workitem 10178
-                SharedUtilities.Workaround_Ladybug318918(_inputStream);
-            }
-
-            return n;
-        }
-
-
-
-        /// <summary>
-        ///   Read the next entry from the zip file.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Call this method just before calling <see cref="Read(byte[], int, int)"/>,
-        ///   to position the pointer in the zip file to the next entry that can be
-        ///   read.  Subsequent calls to <c>Read()</c>, will decrypt and decompress the
-        ///   data in the zip file, until <c>Read()</c> returns 0.
-        /// </para>
-        ///
-        /// <para>
-        ///   Each time you call <c>GetNextEntry()</c>, the pointer in the wrapped
-        ///   stream is moved to the next entry in the zip file.  If you call <see
-        ///   cref="Seek(long, SeekOrigin)"/>, and thus re-position the pointer within
-        ///   the file, you will need to call <c>GetNextEntry()</c> again, to insure
-        ///   that the file pointer is positioned at the beginning of a zip entry.
-        /// </para>
-        ///
-        /// <para>
-        ///   This method returns the <c>ZipEntry</c>. Using a stream approach, you will
-        ///   read the raw bytes for an entry in a zip file via calls to <c>Read()</c>.
-        ///   Alternatively, you can extract an entry into a file, or a stream, by
-        ///   calling <see cref="ZipEntry.Extract()"/>, or one of its siblings.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <returns>
-        ///   The <c>ZipEntry</c> read. Returns null (or Nothing in VB) if there are no more
-        ///   entries in the zip file.
-        /// </returns>
-        ///
-        public ZipEntry GetNextEntry()
-        {
-            if (_findRequired)
-            {
-                // find the next signature
-                long d = SharedUtilities.FindSignature(_inputStream, ZipConstants.ZipEntrySignature);
-                if (d == -1) return null;
-                // back up 4 bytes: ReadEntry assumes the file pointer is positioned before the entry signature
-                _inputStream.Seek(-4, SeekOrigin.Current);
-                // workitem 10178
-                SharedUtilities.Workaround_Ladybug318918(_inputStream);
-            }
-            // workitem 10923
-            else if (_firstEntry)
-            {
-                // we've already read one entry.
-                // Seek to the end of it.
-                _inputStream.Seek(_endOfEntry, SeekOrigin.Begin);
-                SharedUtilities.Workaround_Ladybug318918(_inputStream);
-            }
-
-            _currentEntry = ZipEntry.ReadEntry(_container, !_firstEntry);
-            // ReadEntry leaves the file position after all the entry
-            // data and the optional bit-3 data descriptpr.  This is
-            // where the next entry would normally start.
-            _endOfEntry = _inputStream.Position;
-            _firstEntry = true;
-            _needSetup = true;
-            _findRequired= false;
-            return _currentEntry;
-        }
-
-
-        /// <summary>
-        ///   Dispose the stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This method disposes the ZipInputStream.  It may also close the
-        ///   underlying stream, depending on which constructor was used.
-        /// </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>
-        ///
-        ///   <para>
-        ///     Application code won't call this code directly.  This method may
-        ///     be invoked in two distinct scenarios.  If disposing == true, the
-        ///     method has been called directly or indirectly by a user's code,
-        ///     for example via the public Dispose() method. In this case, both
-        ///     managed and unmanaged resources can be referenced and disposed.
-        ///     If disposing == false, the method has been called by the runtime
-        ///     from inside the object finalizer and this method should not
-        ///     reference other objects; in that case only unmanaged resources
-        ///     must be referenced or disposed.
-        ///   </para>
-        /// </remarks>
-        ///
-        /// <param name="disposing">
-        ///   true if the Dispose method was invoked by user code.
-        /// </param>
-        protected override void Dispose(bool disposing)
-        {
-            if (_closed) return;
-
-            if (disposing) // not called from finalizer
-            {
-                // When ZipInputStream is used within a using clause, and an
-                // exception is thrown, Close() is invoked.  But we don't want to
-                // try to write anything in that case.  Eventually the exception
-                // will be propagated to the application.
-                if (_exceptionPending) return;
-
-                if (!_leaveUnderlyingStreamOpen)
-                {
-#if NETCF
-                    _inputStream.Close();
-#else
-                    _inputStream.Dispose();
-#endif
-                }
-            }
-            _closed= true;
-        }
-
-
-        /// <summary>
-        /// Always returns true.
-        /// </summary>
-        public override bool CanRead  { get { return true; }}
-
-        /// <summary>
-        /// Returns the value of <c>CanSeek</c> for the underlying (wrapped) stream.
-        /// </summary>
-        public override bool CanSeek  { get { return _inputStream.CanSeek; } }
-
-        /// <summary>
-        /// Always returns false.
-        /// </summary>
-        public override bool CanWrite { get { return false; } }
-
-        /// <summary>
-        /// Returns the length of the underlying stream.
-        /// </summary>
-        public override long Length   { get { return _inputStream.Length; }}
-
-        /// <summary>
-        /// Gets or sets the position of the underlying stream.
-        /// </summary>
-        /// <remarks>
-        /// Setting the position is equivalent to calling <c>Seek(value, SeekOrigin.Begin)</c>.
-        /// </remarks>
-        public override long Position
-        {
-            get { return _inputStream.Position;}
-            set { Seek(value, SeekOrigin.Begin); }
-        }
-
-        /// <summary>
-        /// This is a no-op.
-        /// </summary>
-        public override void Flush()
-        {
-            throw new NotSupportedException("Flush");
-        }
-
-
-        /// <summary>
-        /// This method always throws a NotSupportedException.
-        /// </summary>
-        /// <param name="buffer">ignored</param>
-        /// <param name="offset">ignored</param>
-        /// <param name="count">ignored</param>
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            throw new NotSupportedException("Write");
-        }
-
-
-        /// <summary>
-        ///   This method seeks in the underlying stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   Call this method if you want to seek around within the zip file for random access.
-        /// </para>
-        ///
-        /// <para>
-        ///   Applications can intermix calls to <c>Seek()</c> with calls to <see
-        ///   cref="GetNextEntry()"/>.  After a call to <c>Seek()</c>,
-        ///   <c>GetNextEntry()</c> will get the next <c>ZipEntry</c> that falls after
-        ///   the current position in the input stream. You're on your own for finding
-        ///   out just where to seek in the stream, to get to the various entries.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="offset">the offset point to seek to</param>
-        /// <param name="origin">the reference point from which to seek</param>
-        /// <returns>The new position</returns>
-        public override long Seek(long offset, SeekOrigin origin)
-        {
-            _findRequired= true;
-            var x = _inputStream.Seek(offset, origin);
-            // workitem 10178
-            SharedUtilities.Workaround_Ladybug318918(_inputStream);
-            return x;
-        }
-
-        /// <summary>
-        /// This method always throws a NotSupportedException.
-        /// </summary>
-        /// <param name="value">ignored</param>
-        public override void SetLength(long value)
-        {
-            throw new NotSupportedException();
-        }
-
-
-        private Stream _inputStream;
-        private System.Text.Encoding _provisionalAlternateEncoding;
-        private ZipEntry _currentEntry;
-        private bool _firstEntry;
-        private bool _needSetup;
-        private ZipContainer _container;
-        private CrcCalculatorStream _crcStream;
-        private Int64 _LeftToRead;
-        internal String _Password;
-        private Int64 _endOfEntry;
-        private string _name;
-
-        private bool _leaveUnderlyingStreamOpen;
-        private bool _closed;
-        private bool _findRequired;
-        private bool _exceptionPending;
-    }
-
-
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipOutputStream.cs b/EPPlus/Packaging/DotNetZip/ZipOutputStream.cs
deleted file mode 100644
index 6ad801a..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipOutputStream.cs
+++ /dev/null
@@ -1,1818 +0,0 @@
-// 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;
-            }
-        }
-    }
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/ZipSegmentedStream.cs b/EPPlus/Packaging/DotNetZip/ZipSegmentedStream.cs
deleted file mode 100644
index 4afc634..0000000
--- a/EPPlus/Packaging/DotNetZip/ZipSegmentedStream.cs
+++ /dev/null
@@ -1,571 +0,0 @@
-// ZipSegmentedStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 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-13 22:25:45>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for zip streams that span disk files.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zip
-{
-    internal class ZipSegmentedStream : System.IO.Stream
-    {
-        enum RwMode
-        {
-            None = 0,
-            ReadOnly = 1,
-            Write = 2,
-            //Update = 3
-        }
-
-        private RwMode rwMode;
-        private bool _exceptionPending; // **see note below
-        private string _baseName;
-        private string _baseDir;
-        //private bool _isDisposed;
-        private string _currentName;
-        private string _currentTempName;
-        private uint _currentDiskNumber;
-        private uint _maxDiskNumber;
-        private int _maxSegmentSize;
-        private System.IO.Stream _innerStream;
-
-        // **Note regarding exceptions:
-        //
-        // When ZipSegmentedStream is employed within a using clause,
-        // which is the typical scenario, and an exception is thrown
-        // within the scope of the using, Dispose() is invoked
-        // implicitly before processing the initial exception.  If that
-        // happens, this class sets _exceptionPending to true, and then
-        // within the Dispose(bool), takes special action as
-        // appropriate. Need to be careful: any additional exceptions
-        // will mask the original one.
-
-        private ZipSegmentedStream() : base()
-        {
-            _exceptionPending = false;
-        }
-
-        public static ZipSegmentedStream ForReading(string name,
-                                                    uint initialDiskNumber,
-                                                    uint maxDiskNumber)
-        {
-            ZipSegmentedStream zss = new ZipSegmentedStream()
-                {
-                    rwMode = RwMode.ReadOnly,
-                    CurrentSegment = initialDiskNumber,
-                    _maxDiskNumber = maxDiskNumber,
-                    _baseName = name,
-                };
-
-            // Console.WriteLine("ZSS: ForReading ({0})",
-            //                    Path.GetFileName(zss.CurrentName));
-
-            zss._SetReadStream();
-
-            return zss;
-        }
-
-
-        public static ZipSegmentedStream ForWriting(string name, int maxSegmentSize)
-        {
-            ZipSegmentedStream zss = new ZipSegmentedStream()
-                {
-                    rwMode = RwMode.Write,
-                    CurrentSegment = 0,
-                    _baseName = name,
-                    _maxSegmentSize = maxSegmentSize,
-                    _baseDir = Path.GetDirectoryName(name)
-                };
-
-            // workitem 9522
-            if (zss._baseDir=="") zss._baseDir=".";
-
-            zss._SetWriteStream(0);
-
-            // Console.WriteLine("ZSS: ForWriting ({0})",
-            //                    Path.GetFileName(zss.CurrentName));
-
-            return zss;
-        }
-
-
-        /// <summary>
-        ///   Sort-of like a factory method, ForUpdate is used only when
-        ///   the application needs to update the zip entry metadata for
-        ///   a segmented zip file, when the starting segment is earlier
-        ///   than the ending segment, for a particular entry.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The update is always contiguous, never rolls over.  As a
-        ///     result, this method doesn't need to return a ZSS; it can
-        ///     simply return a FileStream.  That's why it's "sort of"
-        ///     like a Factory method.
-        ///   </para>
-        ///   <para>
-        ///     Caller must Close/Dispose the stream object returned by
-        ///     this method.
-        ///   </para>
-        /// </remarks>
-        public static Stream ForUpdate(string name, uint diskNumber)
-        {
-            if (diskNumber >= 99)
-                throw new ArgumentOutOfRangeException("diskNumber");
-
-            string fname =
-                String.Format("{0}.z{1:D2}",
-                                 Path.Combine(Path.GetDirectoryName(name),
-                                              Path.GetFileNameWithoutExtension(name)),
-                                 diskNumber + 1);
-
-            // Console.WriteLine("ZSS: ForUpdate ({0})",
-            //                   Path.GetFileName(fname));
-
-            // This class assumes that the update will not expand the
-            // size of the segment. Update is used only for an in-place
-            // update of zip metadata. It never will try to write beyond
-            // the end of a segment.
-
-            return File.Open(fname,
-                             FileMode.Open,
-                             FileAccess.ReadWrite,
-                             FileShare.None);
-        }
-
-        public bool ContiguousWrite
-        {
-            get;
-            set;
-        }
-
-
-        public UInt32 CurrentSegment
-        {
-            get
-            {
-                return _currentDiskNumber;
-            }
-            private set
-            {
-                _currentDiskNumber = value;
-                _currentName = null; // it will get updated next time referenced
-            }
-        }
-
-        /// <summary>
-        ///   Name of the filesystem file corresponding to the current segment.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     The name is not always the name currently being used in the
-        ///     filesystem.  When rwMode is RwMode.Write, the filesystem file has a
-        ///     temporary name until the stream is closed or until the next segment is
-        ///     started.
-        ///   </para>
-        /// </remarks>
-        public String CurrentName
-        {
-            get
-            {
-                if (_currentName==null)
-                    _currentName = _NameForSegment(CurrentSegment);
-
-                return _currentName;
-            }
-        }
-
-
-        public String CurrentTempName
-        {
-            get
-            {
-                return _currentTempName;
-            }
-        }
-
-        private string _NameForSegment(uint diskNumber)
-        {
-            if (diskNumber >= 99)
-            {
-                _exceptionPending = true;
-                throw new OverflowException("The number of zip segments would exceed 99.");
-            }
-
-            return String.Format("{0}.z{1:D2}",
-                                 Path.Combine(Path.GetDirectoryName(_baseName),
-                                              Path.GetFileNameWithoutExtension(_baseName)),
-                                 diskNumber + 1);
-        }
-
-
-        // Returns the segment that WILL be current if writing
-        // a block of the given length.
-        // This isn't exactly true. It could roll over beyond
-        // this number.
-        public UInt32 ComputeSegment(int length)
-        {
-            if (_innerStream.Position + length > _maxSegmentSize)
-                // the block will go AT LEAST into the next segment
-                return CurrentSegment + 1;
-
-            // it will fit in the current segment
-            return CurrentSegment;
-        }
-
-
-        public override String ToString()
-        {
-            return String.Format("{0}[{1}][{2}], pos=0x{3:X})",
-                                 "ZipSegmentedStream", CurrentName,
-                                 rwMode.ToString(),
-                                 this.Position);
-        }
-
-
-        private void _SetReadStream()
-        {
-            if (_innerStream != null)
-            {
-#if NETCF
-                _innerStream.Close();
-#else
-                _innerStream.Dispose();
-#endif
-            }
-
-            if (CurrentSegment + 1 == _maxDiskNumber)
-                _currentName = _baseName;
-
-            // Console.WriteLine("ZSS: SRS ({0})",
-            //                   Path.GetFileName(CurrentName));
-
-            _innerStream = File.OpenRead(CurrentName);
-        }
-
-
-        /// <summary>
-        /// Read from the stream
-        /// </summary>
-        /// <param name="buffer">the buffer to read</param>
-        /// <param name="offset">the offset at which to start</param>
-        /// <param name="count">the number of bytes to read</param>
-        /// <returns>the number of bytes actually read</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            if (rwMode != RwMode.ReadOnly)
-            {
-                _exceptionPending = true;
-                throw new InvalidOperationException("Stream Error: Cannot Read.");
-            }
-
-            int r = _innerStream.Read(buffer, offset, count);
-            int r1 = r;
-
-            while (r1 != count)
-            {
-                if (_innerStream.Position != _innerStream.Length)
-                {
-                    _exceptionPending = true;
-                    throw new ZipException(String.Format("Read error in file {0}", CurrentName));
-
-                }
-
-                if (CurrentSegment + 1 == _maxDiskNumber)
-                    return r; // no more to read
-
-                CurrentSegment++;
-                _SetReadStream();
-                offset += r1;
-                count -= r1;
-                r1 = _innerStream.Read(buffer, offset, count);
-                r += r1;
-            }
-            return r;
-        }
-
-
-
-        private void _SetWriteStream(uint increment)
-        {
-            if (_innerStream != null)
-            {
-#if NETCF
-                _innerStream.Close();
-#else
-                _innerStream.Dispose();
-#endif
-                if (File.Exists(CurrentName))
-                    File.Delete(CurrentName);
-                File.Move(_currentTempName, CurrentName);
-                // Console.WriteLine("ZSS: SWS close ({0})",
-                //                   Path.GetFileName(CurrentName));
-            }
-
-            if (increment > 0)
-                CurrentSegment += increment;
-
-            SharedUtilities.CreateAndOpenUniqueTempFile(_baseDir,
-                                                        out _innerStream,
-                                                        out _currentTempName);
-
-            // Console.WriteLine("ZSS: SWS open ({0})",
-            //                   Path.GetFileName(_currentTempName));
-
-            if (CurrentSegment == 0)
-                _innerStream.Write(BitConverter.GetBytes(ZipConstants.SplitArchiveSignature), 0, 4);
-        }
-
-
-        /// <summary>
-        /// Write to the stream.
-        /// </summary>
-        /// <param name="buffer">the buffer from which to write</param>
-        /// <param name="offset">the offset at which to start writing</param>
-        /// <param name="count">the number of bytes to write</param>
-        public override void Write(byte[] buffer, int offset, int count)
-        {
-            if (rwMode != RwMode.Write)
-            {
-                _exceptionPending = true;
-                throw new InvalidOperationException("Stream Error: Cannot Write.");
-            }
-
-
-            if (ContiguousWrite)
-            {
-                // enough space for a contiguous write?
-                if (_innerStream.Position + count > _maxSegmentSize)
-                    _SetWriteStream(1);
-            }
-            else
-            {
-                while (_innerStream.Position + count > _maxSegmentSize)
-                {
-                    int c = unchecked(_maxSegmentSize - (int)_innerStream.Position);
-                    _innerStream.Write(buffer, offset, c);
-                    _SetWriteStream(1);
-                    count -= c;
-                    offset += c;
-                }
-            }
-
-            _innerStream.Write(buffer, offset, count);
-        }
-
-
-        public long TruncateBackward(uint diskNumber, long offset)
-        {
-            // Console.WriteLine("***ZSS.Trunc to disk {0}", diskNumber);
-            // Console.WriteLine("***ZSS.Trunc:  current disk {0}", CurrentSegment);
-            if (diskNumber >= 99)
-                throw new ArgumentOutOfRangeException("diskNumber");
-
-            if (rwMode != RwMode.Write)
-            {
-                _exceptionPending = true;
-                throw new ZipException("bad state.");
-            }
-
-            // Seek back in the segmented stream to a (maybe) prior segment.
-
-            // Check if it is the same segment.  If it is, very simple.
-            if (diskNumber == CurrentSegment)
-            {
-                var x =_innerStream.Seek(offset, SeekOrigin.Begin);
-                // workitem 10178
-                Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_innerStream);
-                return x;
-            }
-
-            // Seeking back to a prior segment.
-            // The current segment and any intervening segments must be removed.
-            // First, close the current segment, and then remove it.
-            if (_innerStream != null)
-            {
-#if NETCF
-                _innerStream.Close();
-#else
-                _innerStream.Dispose();
-#endif
-                if (File.Exists(_currentTempName))
-                    File.Delete(_currentTempName);
-            }
-
-            // Now, remove intervening segments.
-            for (uint j= CurrentSegment-1; j > diskNumber; j--)
-            {
-                string s = _NameForSegment(j);
-                // Console.WriteLine("***ZSS.Trunc:  removing file {0}", s);
-                if (File.Exists(s))
-                    File.Delete(s);
-            }
-
-            // now, open the desired segment.  It must exist.
-            CurrentSegment = diskNumber;
-
-            // get a new temp file, try 3 times:
-            for (int i = 0; i < 3; i++)
-            {
-                try
-                {
-                    _currentTempName = SharedUtilities.InternalGetTempFileName();
-                    // move the .z0x file back to a temp name
-                    File.Move(CurrentName, _currentTempName);
-                    break; // workitem 12403
-                }
-                catch(IOException)
-                {
-                    if (i == 2) throw;
-                }
-            }
-
-            // open it
-            _innerStream = new FileStream(_currentTempName, FileMode.Open);
-
-            var r =  _innerStream.Seek(offset, SeekOrigin.Begin);
-
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_innerStream);
-
-            return r;
-        }
-
-
-
-        public override bool CanRead
-        {
-            get
-            {
-                return (rwMode == RwMode.ReadOnly &&
-                        (_innerStream != null) &&
-                        _innerStream.CanRead);
-            }
-        }
-
-
-        public override bool CanSeek
-        {
-            get
-            {
-                return (_innerStream != null) &&
-                        _innerStream.CanSeek;
-            }
-        }
-
-
-        public override bool CanWrite
-        {
-            get
-            {
-                return (rwMode == RwMode.Write) &&
-                        (_innerStream != null) &&
-                        _innerStream.CanWrite;
-            }
-        }
-
-        public override void Flush()
-        {
-            _innerStream.Flush();
-        }
-
-        public override long Length
-        {
-            get
-            {
-                return _innerStream.Length;
-            }
-        }
-
-        public override long Position
-        {
-            get { return _innerStream.Position; }
-            set { _innerStream.Position = value; }
-        }
-
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            var x = _innerStream.Seek(offset, origin);
-            // workitem 10178
-            Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_innerStream);
-            return x;
-        }
-
-        public override void SetLength(long value)
-        {
-            if (rwMode != RwMode.Write)
-            {
-                _exceptionPending = true;
-                throw new InvalidOperationException();
-            }
-            _innerStream.SetLength(value);
-        }
-
-
-        protected override void Dispose(bool disposing)
-        {
-            // this gets called by Stream.Close()
-
-            // if (_isDisposed) return;
-            // _isDisposed = true;
-            //Console.WriteLine("Dispose (mode={0})\n", rwMode.ToString());
-
-            try
-            {
-                if (_innerStream != null)
-                {
-#if NETCF
-                    _innerStream.Close();
-#else
-                    _innerStream.Dispose();
-#endif
-                    //_innerStream = null;
-                    if (rwMode == RwMode.Write)
-                    {
-                        if (_exceptionPending)
-                        {
-                            // possibly could try to clean up all the
-                            // temp files created so far...
-                        }
-                        else
-                        {
-                            // // move the final temp file to the .zNN name
-                            // if (File.Exists(CurrentName))
-                            //     File.Delete(CurrentName);
-                            // if (File.Exists(_currentTempName))
-                            //     File.Move(_currentTempName, CurrentName);
-                        }
-                    }
-                }
-            }
-            finally
-            {
-                base.Dispose(disposing);
-            }
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/Deflate.cs b/EPPlus/Packaging/DotNetZip/Zlib/Deflate.cs
deleted file mode 100644
index d5d32ad..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/Deflate.cs
+++ /dev/null
@@ -1,1879 +0,0 @@
-// Deflate.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
-// 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-August-03 19:52:15>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for handling the Deflate or compression.
-//
-// This code is based on multiple sources:
-// - the original zlib v1.2.3 source, which is Copyright (C) 1995-2005 Jean-loup Gailly.
-// - the original jzlib, which is Copyright (c) 2000-2003 ymnk, JCraft,Inc.
-//
-// However, this code is significantly different from both.
-// The object model is not the same, and many of the behaviors are different.
-//
-// In keeping with the license for these other works, the copyrights for
-// jzlib and zlib are here.
-//
-// -----------------------------------------------------------------------
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the distribution.
-//
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// -----------------------------------------------------------------------
-//
-// This program is based on zlib-1.1.3; credit to authors
-// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-// and contributors of zlib.
-//
-// -----------------------------------------------------------------------
-
-
-using System;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-
-    internal enum BlockState
-    {
-        NeedMore = 0,       // block not completed, need more input or more output
-        BlockDone,          // block flush performed
-        FinishStarted,              // finish started, need only more output at next deflate
-        FinishDone          // finish done, accept no more input or output
-    }
-
-    internal enum DeflateFlavor
-    {
-        Store,
-        Fast,
-        Slow
-    }
-
-    internal sealed class DeflateManager
-    {
-        private static readonly int MEM_LEVEL_MAX = 9;
-        private static readonly int MEM_LEVEL_DEFAULT = 8;
-
-        internal delegate BlockState CompressFunc(FlushType flush);
-
-        internal class Config
-        {
-            // Use a faster search when the previous match is longer than this
-            internal int GoodLength; // reduce lazy search above this match length
-
-            // Attempt to find a better match only when the current match is
-            // strictly smaller than this value. This mechanism is used only for
-            // compression levels >= 4.  For levels 1,2,3: MaxLazy is actually
-            // MaxInsertLength. (See DeflateFast)
-
-            internal int MaxLazy;    // do not perform lazy search above this match length
-
-            internal int NiceLength; // quit search above this match length
-
-            // To speed up deflation, hash chains are never searched beyond this
-            // length.  A higher limit improves compression ratio but degrades the speed.
-
-            internal int MaxChainLength;
-
-            internal DeflateFlavor Flavor;
-
-            private Config(int goodLength, int maxLazy, int niceLength, int maxChainLength, DeflateFlavor flavor)
-            {
-                this.GoodLength = goodLength;
-                this.MaxLazy = maxLazy;
-                this.NiceLength = niceLength;
-                this.MaxChainLength = maxChainLength;
-                this.Flavor = flavor;
-            }
-
-            public static Config Lookup(CompressionLevel level)
-            {
-                return Table[(int)level];
-            }
-
-
-            static Config()
-            {
-                Table = new Config[] {
-                    new Config(0, 0, 0, 0, DeflateFlavor.Store),
-                    new Config(4, 4, 8, 4, DeflateFlavor.Fast),
-                    new Config(4, 5, 16, 8, DeflateFlavor.Fast),
-                    new Config(4, 6, 32, 32, DeflateFlavor.Fast),
-
-                    new Config(4, 4, 16, 16, DeflateFlavor.Slow),
-                    new Config(8, 16, 32, 32, DeflateFlavor.Slow),
-                    new Config(8, 16, 128, 128, DeflateFlavor.Slow),
-                    new Config(8, 32, 128, 256, DeflateFlavor.Slow),
-                    new Config(32, 128, 258, 1024, DeflateFlavor.Slow),
-                    new Config(32, 258, 258, 4096, DeflateFlavor.Slow),
-                };
-            }
-
-            private static readonly Config[] Table;
-        }
-
-
-        private CompressFunc DeflateFunction;
-
-        private static readonly System.String[] _ErrorMessage = new System.String[]
-        {
-            "need dictionary",
-            "stream end",
-            "",
-            "file error",
-            "stream error",
-            "data error",
-            "insufficient memory",
-            "buffer error",
-            "incompatible version",
-            ""
-        };
-
-        // preset dictionary flag in zlib header
-        private static readonly int PRESET_DICT = 0x20;
-
-        private static readonly int INIT_STATE = 42;
-        private static readonly int BUSY_STATE = 113;
-        private static readonly int FINISH_STATE = 666;
-
-        // The deflate compression method
-        private static readonly int Z_DEFLATED = 8;
-
-        private static readonly int STORED_BLOCK = 0;
-        private static readonly int STATIC_TREES = 1;
-        private static readonly int DYN_TREES = 2;
-
-        // The three kinds of block type
-        private static readonly int Z_BINARY = 0;
-        private static readonly int Z_ASCII = 1;
-        private static readonly int Z_UNKNOWN = 2;
-
-        private static readonly int Buf_size = 8 * 2;
-
-        private static readonly int MIN_MATCH = 3;
-        private static readonly int MAX_MATCH = 258;
-
-        private static readonly int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
-
-        private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
-
-        private static readonly int END_BLOCK = 256;
-
-        internal ZlibCodec _codec; // the zlib encoder/decoder
-        internal int status;       // as the name implies
-        internal byte[] pending;   // output still pending - waiting to be compressed
-        internal int nextPending;  // index of next pending byte to output to the stream
-        internal int pendingCount; // number of bytes in the pending buffer
-
-        internal sbyte data_type;  // UNKNOWN, BINARY or ASCII
-        internal int last_flush;   // value of flush param for previous deflate call
-
-        internal int w_size;       // LZ77 window size (32K by default)
-        internal int w_bits;       // log2(w_size)  (8..16)
-        internal int w_mask;       // w_size - 1
-
-        //internal byte[] dictionary;
-        internal byte[] window;
-
-        // Sliding window. Input bytes are read into the second half of the window,
-        // and move to the first half later to keep a dictionary of at least wSize
-        // bytes. With this organization, matches are limited to a distance of
-        // wSize-MAX_MATCH bytes, but this ensures that IO is always
-        // performed with a length multiple of the block size.
-        //
-        // To do: use the user input buffer as sliding window.
-
-        internal int window_size;
-        // Actual size of window: 2*wSize, except when the user input buffer
-        // is directly used as sliding window.
-
-        internal short[] prev;
-        // Link to older string with same hash index. To limit the size of this
-        // array to 64K, this link is maintained only for the last 32K strings.
-        // An index in this array is thus a window index modulo 32K.
-
-        internal short[] head;  // Heads of the hash chains or NIL.
-
-        internal int ins_h;     // hash index of string to be inserted
-        internal int hash_size; // number of elements in hash table
-        internal int hash_bits; // log2(hash_size)
-        internal int hash_mask; // hash_size-1
-
-        // Number of bits by which ins_h must be shifted at each input
-        // step. It must be such that after MIN_MATCH steps, the oldest
-        // byte no longer takes part in the hash key, that is:
-        // hash_shift * MIN_MATCH >= hash_bits
-        internal int hash_shift;
-
-        // Window position at the beginning of the current output block. Gets
-        // negative when the window is moved backwards.
-
-        internal int block_start;
-
-        Config config;
-        internal int match_length;    // length of best match
-        internal int prev_match;      // previous match
-        internal int match_available; // set if previous match exists
-        internal int strstart;        // start of string to insert into.....????
-        internal int match_start;     // start of matching string
-        internal int lookahead;       // number of valid bytes ahead in window
-
-        // Length of the best match at previous step. Matches not greater than this
-        // are discarded. This is used in the lazy match evaluation.
-        internal int prev_length;
-
-        // Insert new strings in the hash table only if the match length is not
-        // greater than this length. This saves time but degrades compression.
-        // max_insert_length is used only for compression levels <= 3.
-
-        internal CompressionLevel compressionLevel; // compression level (1..9)
-        internal CompressionStrategy compressionStrategy; // favor or force Huffman coding
-
-
-        internal short[] dyn_ltree;         // literal and length tree
-        internal short[] dyn_dtree;         // distance tree
-        internal short[] bl_tree;           // Huffman tree for bit lengths
-
-        internal Tree treeLiterals = new Tree();  // desc for literal tree
-        internal Tree treeDistances = new Tree();  // desc for distance tree
-        internal Tree treeBitLengths = new Tree(); // desc for bit length tree
-
-        // number of codes at each bit length for an optimal tree
-        internal short[] bl_count = new short[InternalConstants.MAX_BITS + 1];
-
-        // heap used to build the Huffman trees
-        internal int[] heap = new int[2 * InternalConstants.L_CODES + 1];
-
-        internal int heap_len;              // number of elements in the heap
-        internal int heap_max;              // element of largest frequency
-
-        // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-        // The same heap array is used to build all trees.
-
-        // Depth of each subtree used as tie breaker for trees of equal frequency
-        internal sbyte[] depth = new sbyte[2 * InternalConstants.L_CODES + 1];
-
-        internal int _lengthOffset;                 // index for literals or lengths
-
-
-        // Size of match buffer for literals/lengths.  There are 4 reasons for
-        // limiting lit_bufsize to 64K:
-        //   - frequencies can be kept in 16 bit counters
-        //   - if compression is not successful for the first block, all input
-        //     data is still in the window so we can still emit a stored block even
-        //     when input comes from standard input.  (This can also be done for
-        //     all blocks if lit_bufsize is not greater than 32K.)
-        //   - if compression is not successful for a file smaller than 64K, we can
-        //     even emit a stored file instead of a stored block (saving 5 bytes).
-        //     This is applicable only for zip (not gzip or zlib).
-        //   - creating new Huffman trees less frequently may not provide fast
-        //     adaptation to changes in the input data statistics. (Take for
-        //     example a binary file with poorly compressible code followed by
-        //     a highly compressible string table.) Smaller buffer sizes give
-        //     fast adaptation but have of course the overhead of transmitting
-        //     trees more frequently.
-
-        internal int lit_bufsize;
-
-        internal int last_lit;     // running index in l_buf
-
-        // Buffer for distances. To simplify the code, d_buf and l_buf have
-        // the same number of elements. To use different lengths, an extra flag
-        // array would be necessary.
-
-        internal int _distanceOffset;        // index into pending; points to distance data??
-
-        internal int opt_len;      // bit length of current block with optimal trees
-        internal int static_len;   // bit length of current block with static trees
-        internal int matches;      // number of string matches in current block
-        internal int last_eob_len; // bit length of EOB code for last block
-
-        // Output buffer. bits are inserted starting at the bottom (least
-        // significant bits).
-        internal short bi_buf;
-
-        // Number of valid bits in bi_buf.  All bits above the last valid bit
-        // are always zero.
-        internal int bi_valid;
-
-
-        internal DeflateManager()
-        {
-            dyn_ltree = new short[HEAP_SIZE * 2];
-            dyn_dtree = new short[(2 * InternalConstants.D_CODES + 1) * 2]; // distance tree
-            bl_tree = new short[(2 * InternalConstants.BL_CODES + 1) * 2]; // Huffman tree for bit lengths
-        }
-
-
-        // lm_init
-        private void _InitializeLazyMatch()
-        {
-            window_size = 2 * w_size;
-
-            // clear the hash - workitem 9063
-            Array.Clear(head, 0, hash_size);
-            //for (int i = 0; i < hash_size; i++) head[i] = 0;
-
-            config = Config.Lookup(compressionLevel);
-            SetDeflater();
-
-            strstart = 0;
-            block_start = 0;
-            lookahead = 0;
-            match_length = prev_length = MIN_MATCH - 1;
-            match_available = 0;
-            ins_h = 0;
-        }
-
-        // Initialize the tree data structures for a new zlib stream.
-        private void _InitializeTreeData()
-        {
-            treeLiterals.dyn_tree = dyn_ltree;
-            treeLiterals.staticTree = StaticTree.Literals;
-
-            treeDistances.dyn_tree = dyn_dtree;
-            treeDistances.staticTree = StaticTree.Distances;
-
-            treeBitLengths.dyn_tree = bl_tree;
-            treeBitLengths.staticTree = StaticTree.BitLengths;
-
-            bi_buf = 0;
-            bi_valid = 0;
-            last_eob_len = 8; // enough lookahead for inflate
-
-            // Initialize the first block of the first file:
-            _InitializeBlocks();
-        }
-
-        internal void _InitializeBlocks()
-        {
-            // Initialize the trees.
-            for (int i = 0; i < InternalConstants.L_CODES; i++)
-                dyn_ltree[i * 2] = 0;
-            for (int i = 0; i < InternalConstants.D_CODES; i++)
-                dyn_dtree[i * 2] = 0;
-            for (int i = 0; i < InternalConstants.BL_CODES; i++)
-                bl_tree[i * 2] = 0;
-
-            dyn_ltree[END_BLOCK * 2] = 1;
-            opt_len = static_len = 0;
-            last_lit = matches = 0;
-        }
-
-        // Restore the heap property by moving down the tree starting at node k,
-        // exchanging a node with the smallest of its two sons if necessary, stopping
-        // when the heap property is re-established (each father smaller than its
-        // two sons).
-        internal void pqdownheap(short[] tree, int k)
-        {
-            int v = heap[k];
-            int j = k << 1; // left son of k
-            while (j <= heap_len)
-            {
-                // Set j to the smallest of the two sons:
-                if (j < heap_len && _IsSmaller(tree, heap[j + 1], heap[j], depth))
-                {
-                    j++;
-                }
-                // Exit if v is smaller than both sons
-                if (_IsSmaller(tree, v, heap[j], depth))
-                    break;
-
-                // Exchange v with the smallest son
-                heap[k] = heap[j]; k = j;
-                // And continue down the tree, setting j to the left son of k
-                j <<= 1;
-            }
-            heap[k] = v;
-        }
-
-        internal static bool _IsSmaller(short[] tree, int n, int m, sbyte[] depth)
-        {
-            short tn2 = tree[n * 2];
-            short tm2 = tree[m * 2];
-            return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
-        }
-
-
-        // Scan a literal or distance tree to determine the frequencies of the codes
-        // in the bit length tree.
-        internal void scan_tree(short[] tree, int max_code)
-        {
-            int n; // iterates over all tree elements
-            int prevlen = -1; // last emitted length
-            int curlen; // length of current code
-            int nextlen = (int)tree[0 * 2 + 1]; // length of next code
-            int count = 0; // repeat count of the current code
-            int max_count = 7; // max repeat count
-            int min_count = 4; // min repeat count
-
-            if (nextlen == 0)
-            {
-                max_count = 138; min_count = 3;
-            }
-            tree[(max_code + 1) * 2 + 1] = (short)0x7fff; // guard //??
-
-            for (n = 0; n <= max_code; n++)
-            {
-                curlen = nextlen; nextlen = (int)tree[(n + 1) * 2 + 1];
-                if (++count < max_count && curlen == nextlen)
-                {
-                    continue;
-                }
-                else if (count < min_count)
-                {
-                    bl_tree[curlen * 2] = (short)(bl_tree[curlen * 2] + count);
-                }
-                else if (curlen != 0)
-                {
-                    if (curlen != prevlen)
-                        bl_tree[curlen * 2]++;
-                    bl_tree[InternalConstants.REP_3_6 * 2]++;
-                }
-                else if (count <= 10)
-                {
-                    bl_tree[InternalConstants.REPZ_3_10 * 2]++;
-                }
-                else
-                {
-                    bl_tree[InternalConstants.REPZ_11_138 * 2]++;
-                }
-                count = 0; prevlen = curlen;
-                if (nextlen == 0)
-                {
-                    max_count = 138; min_count = 3;
-                }
-                else if (curlen == nextlen)
-                {
-                    max_count = 6; min_count = 3;
-                }
-                else
-                {
-                    max_count = 7; min_count = 4;
-                }
-            }
-        }
-
-        // Construct the Huffman tree for the bit lengths and return the index in
-        // bl_order of the last bit length code to send.
-        internal int build_bl_tree()
-        {
-            int max_blindex; // index of last bit length code of non zero freq
-
-            // Determine the bit length frequencies for literal and distance trees
-            scan_tree(dyn_ltree, treeLiterals.max_code);
-            scan_tree(dyn_dtree, treeDistances.max_code);
-
-            // Build the bit length tree:
-            treeBitLengths.build_tree(this);
-            // opt_len now includes the length of the tree representations, except
-            // the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-
-            // Determine the number of bit length codes to send. The pkzip format
-            // requires that at least 4 bit length codes be sent. (appnote.txt says
-            // 3 but the actual value used is 4.)
-            for (max_blindex = InternalConstants.BL_CODES - 1; max_blindex >= 3; max_blindex--)
-            {
-                if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0)
-                    break;
-            }
-            // Update opt_len to include the bit length tree and counts
-            opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
-
-            return max_blindex;
-        }
-
-
-        // Send the header for a block using dynamic Huffman trees: the counts, the
-        // lengths of the bit length codes, the literal tree and the distance tree.
-        // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
-        internal void send_all_trees(int lcodes, int dcodes, int blcodes)
-        {
-            int rank; // index in bl_order
-
-            send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
-            send_bits(dcodes - 1, 5);
-            send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
-            for (rank = 0; rank < blcodes; rank++)
-            {
-                send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
-            }
-            send_tree(dyn_ltree, lcodes - 1); // literal tree
-            send_tree(dyn_dtree, dcodes - 1); // distance tree
-        }
-
-        // Send a literal or distance tree in compressed form, using the codes in
-        // bl_tree.
-        internal void send_tree(short[] tree, int max_code)
-        {
-            int n;                           // iterates over all tree elements
-            int prevlen   = -1;              // last emitted length
-            int curlen;                      // length of current code
-            int nextlen   = tree[0 * 2 + 1]; // length of next code
-            int count     = 0;               // repeat count of the current code
-            int max_count = 7;               // max repeat count
-            int min_count = 4;               // min repeat count
-
-            if (nextlen == 0)
-            {
-                max_count = 138; min_count = 3;
-            }
-
-            for (n = 0; n <= max_code; n++)
-            {
-                curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1];
-                if (++count < max_count && curlen == nextlen)
-                {
-                    continue;
-                }
-                else if (count < min_count)
-                {
-                    do
-                    {
-                        send_code(curlen, bl_tree);
-                    }
-                    while (--count != 0);
-                }
-                else if (curlen != 0)
-                {
-                    if (curlen != prevlen)
-                    {
-                        send_code(curlen, bl_tree); count--;
-                    }
-                    send_code(InternalConstants.REP_3_6, bl_tree);
-                    send_bits(count - 3, 2);
-                }
-                else if (count <= 10)
-                {
-                    send_code(InternalConstants.REPZ_3_10, bl_tree);
-                    send_bits(count - 3, 3);
-                }
-                else
-                {
-                    send_code(InternalConstants.REPZ_11_138, bl_tree);
-                    send_bits(count - 11, 7);
-                }
-                count = 0; prevlen = curlen;
-                if (nextlen == 0)
-                {
-                    max_count = 138; min_count = 3;
-                }
-                else if (curlen == nextlen)
-                {
-                    max_count = 6; min_count = 3;
-                }
-                else
-                {
-                    max_count = 7; min_count = 4;
-                }
-            }
-        }
-
-        // Output a block of bytes on the stream.
-        // IN assertion: there is enough room in pending_buf.
-        private void put_bytes(byte[] p, int start, int len)
-        {
-            Array.Copy(p, start, pending, pendingCount, len);
-            pendingCount += len;
-        }
-
-#if NOTNEEDED
-        private void put_byte(byte c)
-        {
-            pending[pendingCount++] = c;
-        }
-        internal void put_short(int b)
-        {
-            unchecked
-            {
-                pending[pendingCount++] = (byte)b;
-                pending[pendingCount++] = (byte)(b >> 8);
-            }
-        }
-        internal void putShortMSB(int b)
-        {
-            unchecked
-            {
-                pending[pendingCount++] = (byte)(b >> 8);
-                pending[pendingCount++] = (byte)b;
-            }
-        }
-#endif
-
-        internal void send_code(int c, short[] tree)
-        {
-            int c2 = c * 2;
-            send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff));
-        }
-
-        internal void send_bits(int value, int length)
-        {
-            int len = length;
-            unchecked
-            {
-                if (bi_valid > (int)Buf_size - len)
-                {
-                    //int val = value;
-                    //      bi_buf |= (val << bi_valid);
-
-                    bi_buf |= (short)((value << bi_valid) & 0xffff);
-                    //put_short(bi_buf);
-                        pending[pendingCount++] = (byte)bi_buf;
-                        pending[pendingCount++] = (byte)(bi_buf >> 8);
-
-
-                    bi_buf = (short)((uint)value >> (Buf_size - bi_valid));
-                    bi_valid += len - Buf_size;
-                }
-                else
-                {
-                    //      bi_buf |= (value) << bi_valid;
-                    bi_buf |= (short)((value << bi_valid) & 0xffff);
-                    bi_valid += len;
-                }
-            }
-        }
-
-        // Send one empty static block to give enough lookahead for inflate.
-        // This takes 10 bits, of which 7 may remain in the bit buffer.
-        // The current inflate code requires 9 bits of lookahead. If the
-        // last two codes for the previous block (real code plus EOB) were coded
-        // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
-        // the last real code. In this case we send two empty static blocks instead
-        // of one. (There are no problems if the previous block is stored or fixed.)
-        // To simplify the code, we assume the worst case of last real code encoded
-        // on one bit only.
-        internal void _tr_align()
-        {
-            send_bits(STATIC_TREES << 1, 3);
-            send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes);
-
-            bi_flush();
-
-            // Of the 10 bits for the empty block, we have already sent
-            // (10 - bi_valid) bits. The lookahead for the last real code (before
-            // the EOB of the previous block) was thus at least one plus the length
-            // of the EOB plus what we have just sent of the empty static block.
-            if (1 + last_eob_len + 10 - bi_valid < 9)
-            {
-                send_bits(STATIC_TREES << 1, 3);
-                send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes);
-                bi_flush();
-            }
-            last_eob_len = 7;
-        }
-
-
-        // Save the match info and tally the frequency counts. Return true if
-        // the current block must be flushed.
-        internal bool _tr_tally(int dist, int lc)
-        {
-            pending[_distanceOffset + last_lit * 2] = unchecked((byte) ( (uint)dist >> 8 ) );
-            pending[_distanceOffset + last_lit * 2 + 1] = unchecked((byte)dist);
-            pending[_lengthOffset + last_lit] = unchecked((byte)lc);
-            last_lit++;
-
-            if (dist == 0)
-            {
-                // lc is the unmatched char
-                dyn_ltree[lc * 2]++;
-            }
-            else
-            {
-                matches++;
-                // Here, lc is the match length - MIN_MATCH
-                dist--; // dist = match distance - 1
-                dyn_ltree[(Tree.LengthCode[lc] + InternalConstants.LITERALS + 1) * 2]++;
-                dyn_dtree[Tree.DistanceCode(dist) * 2]++;
-            }
-
-            if ((last_lit & 0x1fff) == 0 && (int)compressionLevel > 2)
-            {
-                // Compute an upper bound for the compressed length
-                int out_length = last_lit << 3;
-                int in_length = strstart - block_start;
-                int dcode;
-                for (dcode = 0; dcode < InternalConstants.D_CODES; dcode++)
-                {
-                    out_length = (int)(out_length + (int)dyn_dtree[dcode * 2] * (5L + Tree.ExtraDistanceBits[dcode]));
-                }
-                out_length >>= 3;
-                if ((matches < (last_lit / 2)) && out_length < in_length / 2)
-                    return true;
-            }
-
-            return (last_lit == lit_bufsize - 1) || (last_lit == lit_bufsize);
-            // dinoch - wraparound?
-            // We avoid equality with lit_bufsize because of wraparound at 64K
-            // on 16 bit machines and because stored blocks are restricted to
-            // 64K-1 bytes.
-        }
-
-
-
-        // Send the block data compressed using the given Huffman trees
-        internal void send_compressed_block(short[] ltree, short[] dtree)
-        {
-            int distance; // distance of matched string
-            int lc;       // match length or unmatched char (if dist == 0)
-            int lx = 0;   // running index in l_buf
-            int code;     // the code to send
-            int extra;    // number of extra bits to send
-
-            if (last_lit != 0)
-            {
-                do
-                {
-                    int ix = _distanceOffset + lx * 2;
-                    distance = ((pending[ix] << 8) & 0xff00) |
-                        (pending[ix + 1] & 0xff);
-                    lc = (pending[_lengthOffset + lx]) & 0xff;
-                    lx++;
-
-                    if (distance == 0)
-                    {
-                        send_code(lc, ltree); // send a literal byte
-                    }
-                    else
-                    {
-                        // literal or match pair
-                        // Here, lc is the match length - MIN_MATCH
-                        code = Tree.LengthCode[lc];
-
-                        // send the length code
-                        send_code(code + InternalConstants.LITERALS + 1, ltree);
-                        extra = Tree.ExtraLengthBits[code];
-                        if (extra != 0)
-                        {
-                            // send the extra length bits
-                            lc -= Tree.LengthBase[code];
-                            send_bits(lc, extra);
-                        }
-                        distance--; // dist is now the match distance - 1
-                        code = Tree.DistanceCode(distance);
-
-                        // send the distance code
-                        send_code(code, dtree);
-
-                        extra = Tree.ExtraDistanceBits[code];
-                        if (extra != 0)
-                        {
-                            // send the extra distance bits
-                            distance -= Tree.DistanceBase[code];
-                            send_bits(distance, extra);
-                        }
-                    }
-
-                    // Check that the overlay between pending and d_buf+l_buf is ok:
-                }
-                while (lx < last_lit);
-            }
-
-            send_code(END_BLOCK, ltree);
-            last_eob_len = ltree[END_BLOCK * 2 + 1];
-        }
-
-
-
-        // Set the data type to ASCII or BINARY, using a crude approximation:
-        // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
-        // IN assertion: the fields freq of dyn_ltree are set and the total of all
-        // frequencies does not exceed 64K (to fit in an int on 16 bit machines).
-        internal void set_data_type()
-        {
-            int n = 0;
-            int ascii_freq = 0;
-            int bin_freq = 0;
-            while (n < 7)
-            {
-                bin_freq += dyn_ltree[n * 2]; n++;
-            }
-            while (n < 128)
-            {
-                ascii_freq += dyn_ltree[n * 2]; n++;
-            }
-            while (n < InternalConstants.LITERALS)
-            {
-                bin_freq += dyn_ltree[n * 2]; n++;
-            }
-            data_type = (sbyte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-        }
-
-
-
-        // Flush the bit buffer, keeping at most 7 bits in it.
-        internal void bi_flush()
-        {
-            if (bi_valid == 16)
-            {
-                pending[pendingCount++] = (byte)bi_buf;
-                pending[pendingCount++] = (byte)(bi_buf >> 8);
-                bi_buf = 0;
-                bi_valid = 0;
-            }
-            else if (bi_valid >= 8)
-            {
-                //put_byte((byte)bi_buf);
-                pending[pendingCount++] = (byte)bi_buf;
-                bi_buf >>= 8;
-                bi_valid -= 8;
-            }
-        }
-
-        // Flush the bit buffer and align the output on a byte boundary
-        internal void bi_windup()
-        {
-            if (bi_valid > 8)
-            {
-                pending[pendingCount++] = (byte)bi_buf;
-                pending[pendingCount++] = (byte)(bi_buf >> 8);
-            }
-            else if (bi_valid > 0)
-            {
-                //put_byte((byte)bi_buf);
-                pending[pendingCount++] = (byte)bi_buf;
-            }
-            bi_buf = 0;
-            bi_valid = 0;
-        }
-
-        // Copy a stored block, storing first the length and its
-        // one's complement if requested.
-        internal void copy_block(int buf, int len, bool header)
-        {
-            bi_windup(); // align on byte boundary
-            last_eob_len = 8; // enough lookahead for inflate
-
-            if (header)
-                unchecked
-                {
-                    //put_short((short)len);
-                    pending[pendingCount++] = (byte)len;
-                    pending[pendingCount++] = (byte)(len >> 8);
-                    //put_short((short)~len);
-                    pending[pendingCount++] = (byte)~len;
-                    pending[pendingCount++] = (byte)(~len >> 8);
-                }
-
-            put_bytes(window, buf, len);
-        }
-
-        internal void flush_block_only(bool eof)
-        {
-            _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
-            block_start = strstart;
-            _codec.flush_pending();
-        }
-
-        // Copy without compression as much as possible from the input stream, return
-        // the current block state.
-        // This function does not insert new strings in the dictionary since
-        // uncompressible data is probably not useful. This function is used
-        // only for the level=0 compression option.
-        // NOTE: this function should be optimized to avoid extra copying from
-        // window to pending_buf.
-        internal BlockState DeflateNone(FlushType flush)
-        {
-            // Stored blocks are limited to 0xffff bytes, pending is limited
-            // to pending_buf_size, and each stored block has a 5 byte header:
-
-            int max_block_size = 0xffff;
-            int max_start;
-
-            if (max_block_size > pending.Length - 5)
-            {
-                max_block_size = pending.Length - 5;
-            }
-
-            // Copy as much as possible from input to output:
-            while (true)
-            {
-                // Fill the window as much as possible:
-                if (lookahead <= 1)
-                {
-                    _fillWindow();
-                    if (lookahead == 0 && flush == FlushType.None)
-                        return BlockState.NeedMore;
-                    if (lookahead == 0)
-                        break; // flush the current block
-                }
-
-                strstart += lookahead;
-                lookahead = 0;
-
-                // Emit a stored block if pending will be full:
-                max_start = block_start + max_block_size;
-                if (strstart == 0 || strstart >= max_start)
-                {
-                    // strstart == 0 is possible when wraparound on 16-bit machine
-                    lookahead = (int)(strstart - max_start);
-                    strstart = (int)max_start;
-
-                    flush_block_only(false);
-                    if (_codec.AvailableBytesOut == 0)
-                        return BlockState.NeedMore;
-                }
-
-                // Flush if we may have to slide, otherwise block_start may become
-                // negative and the data will be gone:
-                if (strstart - block_start >= w_size - MIN_LOOKAHEAD)
-                {
-                    flush_block_only(false);
-                    if (_codec.AvailableBytesOut == 0)
-                        return BlockState.NeedMore;
-                }
-            }
-
-            flush_block_only(flush == FlushType.Finish);
-            if (_codec.AvailableBytesOut == 0)
-                return (flush == FlushType.Finish) ? BlockState.FinishStarted : BlockState.NeedMore;
-
-            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
-        }
-
-
-        // Send a stored block
-        internal void _tr_stored_block(int buf, int stored_len, bool eof)
-        {
-            send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
-            copy_block(buf, stored_len, true); // with header
-        }
-
-        // Determine the best encoding for the current block: dynamic trees, static
-        // trees or store, and output the encoded block to the zip file.
-        internal void _tr_flush_block(int buf, int stored_len, bool eof)
-        {
-            int opt_lenb, static_lenb; // opt_len and static_len in bytes
-            int max_blindex = 0; // index of last bit length code of non zero freq
-
-            // Build the Huffman trees unless a stored block is forced
-            if (compressionLevel > 0)
-            {
-                // Check if the file is ascii or binary
-                if (data_type == Z_UNKNOWN)
-                    set_data_type();
-
-                // Construct the literal and distance trees
-                treeLiterals.build_tree(this);
-
-                treeDistances.build_tree(this);
-
-                // At this point, opt_len and static_len are the total bit lengths of
-                // the compressed block data, excluding the tree representations.
-
-                // Build the bit length tree for the above two trees, and get the index
-                // in bl_order of the last bit length code to send.
-                max_blindex = build_bl_tree();
-
-                // Determine the best encoding. Compute first the block length in bytes
-                opt_lenb = (opt_len + 3 + 7) >> 3;
-                static_lenb = (static_len + 3 + 7) >> 3;
-
-                if (static_lenb <= opt_lenb)
-                    opt_lenb = static_lenb;
-            }
-            else
-            {
-                opt_lenb = static_lenb = stored_len + 5; // force a stored block
-            }
-
-            if (stored_len + 4 <= opt_lenb && buf != -1)
-            {
-                // 4: two words for the lengths
-                // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-                // Otherwise we can't have processed more than WSIZE input bytes since
-                // the last block flush, because compression would have been
-                // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-                // transform a block into a stored block.
-                _tr_stored_block(buf, stored_len, eof);
-            }
-            else if (static_lenb == opt_lenb)
-            {
-                send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
-                send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes);
-            }
-            else
-            {
-                send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
-                send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, max_blindex + 1);
-                send_compressed_block(dyn_ltree, dyn_dtree);
-            }
-
-            // The above check is made mod 2^32, for files larger than 512 MB
-            // and uLong implemented on 32 bits.
-
-            _InitializeBlocks();
-
-            if (eof)
-            {
-                bi_windup();
-            }
-        }
-
-        // Fill the window when the lookahead becomes insufficient.
-        // Updates strstart and lookahead.
-        //
-        // IN assertion: lookahead < MIN_LOOKAHEAD
-        // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
-        //    At least one byte has been read, or avail_in == 0; reads are
-        //    performed for at least two bytes (required for the zip translate_eol
-        //    option -- not supported here).
-        private void _fillWindow()
-        {
-            int n, m;
-            int p;
-            int more; // Amount of free space at the end of the window.
-
-            do
-            {
-                more = (window_size - lookahead - strstart);
-
-                // Deal with !@#$% 64K limit:
-                if (more == 0 && strstart == 0 && lookahead == 0)
-                {
-                    more = w_size;
-                }
-                else if (more == -1)
-                {
-                    // Very unlikely, but possible on 16 bit machine if strstart == 0
-                    // and lookahead == 1 (input done one byte at time)
-                    more--;
-
-                    // If the window is almost full and there is insufficient lookahead,
-                    // move the upper half to the lower one to make room in the upper half.
-                }
-                else if (strstart >= w_size + w_size - MIN_LOOKAHEAD)
-                {
-                    Array.Copy(window, w_size, window, 0, w_size);
-                    match_start -= w_size;
-                    strstart -= w_size; // we now have strstart >= MAX_DIST
-                    block_start -= w_size;
-
-                    // Slide the hash table (could be avoided with 32 bit values
-                    // at the expense of memory usage). We slide even when level == 0
-                    // to keep the hash table consistent if we switch back to level > 0
-                    // later. (Using level 0 permanently is not an optimal usage of
-                    // zlib, so we don't care about this pathological case.)
-
-                    n = hash_size;
-                    p = n;
-                    do
-                    {
-                        m = (head[--p] & 0xffff);
-                        head[p] = (short)((m >= w_size) ? (m - w_size) : 0);
-                    }
-                    while (--n != 0);
-
-                    n = w_size;
-                    p = n;
-                    do
-                    {
-                        m = (prev[--p] & 0xffff);
-                        prev[p] = (short)((m >= w_size) ? (m - w_size) : 0);
-                        // If n is not on any hash chain, prev[n] is garbage but
-                        // its value will never be used.
-                    }
-                    while (--n != 0);
-                    more += w_size;
-                }
-
-                if (_codec.AvailableBytesIn == 0)
-                    return;
-
-                // If there was no sliding:
-                //    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-                //    more == window_size - lookahead - strstart
-                // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-                // => more >= window_size - 2*WSIZE + 2
-                // In the BIG_MEM or MMAP case (not yet supported),
-                //   window_size == input_size + MIN_LOOKAHEAD  &&
-                //   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-                // Otherwise, window_size == 2*WSIZE so more >= 2.
-                // If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-
-                n = _codec.read_buf(window, strstart + lookahead, more);
-                lookahead += n;
-
-                // Initialize the hash value now that we have some input:
-                if (lookahead >= MIN_MATCH)
-                {
-                    ins_h = window[strstart] & 0xff;
-                    ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
-                }
-                // If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-                // but this is not important since only literal bytes will be emitted.
-            }
-            while (lookahead < MIN_LOOKAHEAD && _codec.AvailableBytesIn != 0);
-        }
-
-        // Compress as much as possible from the input stream, return the current
-        // block state.
-        // This function does not perform lazy evaluation of matches and inserts
-        // new strings in the dictionary only for unmatched strings or for short
-        // matches. It is used only for the fast compression options.
-        internal BlockState DeflateFast(FlushType flush)
-        {
-            //    short hash_head = 0; // head of the hash chain
-            int hash_head = 0; // head of the hash chain
-            bool bflush; // set if current block must be flushed
-
-            while (true)
-            {
-                // Make sure that we always have enough lookahead, except
-                // at the end of the input file. We need MAX_MATCH bytes
-                // for the next match, plus MIN_MATCH bytes to insert the
-                // string following the next match.
-                if (lookahead < MIN_LOOKAHEAD)
-                {
-                    _fillWindow();
-                    if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
-                    {
-                        return BlockState.NeedMore;
-                    }
-                    if (lookahead == 0)
-                        break; // flush the current block
-                }
-
-                // Insert the string window[strstart .. strstart+2] in the
-                // dictionary, and set hash_head to the head of the hash chain:
-                if (lookahead >= MIN_MATCH)
-                {
-                    ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-
-                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
-                    hash_head = (head[ins_h] & 0xffff);
-                    prev[strstart & w_mask] = head[ins_h];
-                    head[ins_h] = unchecked((short)strstart);
-                }
-
-                // Find the longest match, discarding those <= prev_length.
-                // At this point we have always match_length < MIN_MATCH
-
-                if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
-                {
-                    // To simplify the code, we prevent matches with the string
-                    // of window index 0 (in particular we have to avoid a match
-                    // of the string with itself at the start of the input file).
-                    if (compressionStrategy != CompressionStrategy.HuffmanOnly)
-                    {
-                        match_length = longest_match(hash_head);
-                    }
-                    // longest_match() sets match_start
-                }
-                if (match_length >= MIN_MATCH)
-                {
-                    //        check_match(strstart, match_start, match_length);
-
-                    bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
-
-                    lookahead -= match_length;
-
-                    // Insert new strings in the hash table only if the match length
-                    // is not too large. This saves time but degrades compression.
-                    if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH)
-                    {
-                        match_length--; // string at strstart already in hash table
-                        do
-                        {
-                            strstart++;
-
-                            ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-                            //      prev[strstart&w_mask]=hash_head=head[ins_h];
-                            hash_head = (head[ins_h] & 0xffff);
-                            prev[strstart & w_mask] = head[ins_h];
-                            head[ins_h] = unchecked((short)strstart);
-
-                            // strstart never exceeds WSIZE-MAX_MATCH, so there are
-                            // always MIN_MATCH bytes ahead.
-                        }
-                        while (--match_length != 0);
-                        strstart++;
-                    }
-                    else
-                    {
-                        strstart += match_length;
-                        match_length = 0;
-                        ins_h = window[strstart] & 0xff;
-
-                        ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
-                        // If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-                        // matter since it will be recomputed at next deflate call.
-                    }
-                }
-                else
-                {
-                    // No match, output a literal byte
-
-                    bflush = _tr_tally(0, window[strstart] & 0xff);
-                    lookahead--;
-                    strstart++;
-                }
-                if (bflush)
-                {
-                    flush_block_only(false);
-                    if (_codec.AvailableBytesOut == 0)
-                        return BlockState.NeedMore;
-                }
-            }
-
-            flush_block_only(flush == FlushType.Finish);
-            if (_codec.AvailableBytesOut == 0)
-            {
-                if (flush == FlushType.Finish)
-                    return BlockState.FinishStarted;
-                else
-                    return BlockState.NeedMore;
-            }
-            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
-        }
-
-        // Same as above, but achieves better compression. We use a lazy
-        // evaluation for matches: a match is finally adopted only if there is
-        // no better match at the next window position.
-        internal BlockState DeflateSlow(FlushType flush)
-        {
-            //    short hash_head = 0;    // head of hash chain
-            int hash_head = 0; // head of hash chain
-            bool bflush; // set if current block must be flushed
-
-            // Process the input block.
-            while (true)
-            {
-                // Make sure that we always have enough lookahead, except
-                // at the end of the input file. We need MAX_MATCH bytes
-                // for the next match, plus MIN_MATCH bytes to insert the
-                // string following the next match.
-
-                if (lookahead < MIN_LOOKAHEAD)
-                {
-                    _fillWindow();
-                    if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
-                        return BlockState.NeedMore;
-
-                    if (lookahead == 0)
-                        break; // flush the current block
-                }
-
-                // Insert the string window[strstart .. strstart+2] in the
-                // dictionary, and set hash_head to the head of the hash chain:
-
-                if (lookahead >= MIN_MATCH)
-                {
-                    ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
-                    hash_head = (head[ins_h] & 0xffff);
-                    prev[strstart & w_mask] = head[ins_h];
-                    head[ins_h] = unchecked((short)strstart);
-                }
-
-                // Find the longest match, discarding those <= prev_length.
-                prev_length = match_length;
-                prev_match = match_start;
-                match_length = MIN_MATCH - 1;
-
-                if (hash_head != 0 && prev_length < config.MaxLazy &&
-                    ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
-                {
-                    // To simplify the code, we prevent matches with the string
-                    // of window index 0 (in particular we have to avoid a match
-                    // of the string with itself at the start of the input file).
-
-                    if (compressionStrategy != CompressionStrategy.HuffmanOnly)
-                    {
-                        match_length = longest_match(hash_head);
-                    }
-                    // longest_match() sets match_start
-
-                    if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered ||
-                                              (match_length == MIN_MATCH && strstart - match_start > 4096)))
-                    {
-
-                        // If prev_match is also MIN_MATCH, match_start is garbage
-                        // but we will ignore the current match anyway.
-                        match_length = MIN_MATCH - 1;
-                    }
-                }
-
-                // If there was a match at the previous step and the current
-                // match is not better, output the previous match:
-                if (prev_length >= MIN_MATCH && match_length <= prev_length)
-                {
-                    int max_insert = strstart + lookahead - MIN_MATCH;
-                    // Do not insert strings in hash table beyond this.
-
-                    //          check_match(strstart-1, prev_match, prev_length);
-
-                    bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
-
-                    // Insert in hash table all strings up to the end of the match.
-                    // strstart-1 and strstart are already inserted. If there is not
-                    // enough lookahead, the last two strings are not inserted in
-                    // the hash table.
-                    lookahead -= (prev_length - 1);
-                    prev_length -= 2;
-                    do
-                    {
-                        if (++strstart <= max_insert)
-                        {
-                            ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-                            //prev[strstart&w_mask]=hash_head=head[ins_h];
-                            hash_head = (head[ins_h] & 0xffff);
-                            prev[strstart & w_mask] = head[ins_h];
-                            head[ins_h] = unchecked((short)strstart);
-                        }
-                    }
-                    while (--prev_length != 0);
-                    match_available = 0;
-                    match_length = MIN_MATCH - 1;
-                    strstart++;
-
-                    if (bflush)
-                    {
-                        flush_block_only(false);
-                        if (_codec.AvailableBytesOut == 0)
-                            return BlockState.NeedMore;
-                    }
-                }
-                else if (match_available != 0)
-                {
-
-                    // If there was no match at the previous position, output a
-                    // single literal. If there was a match but the current match
-                    // is longer, truncate the previous match to a single literal.
-
-                    bflush = _tr_tally(0, window[strstart - 1] & 0xff);
-
-                    if (bflush)
-                    {
-                        flush_block_only(false);
-                    }
-                    strstart++;
-                    lookahead--;
-                    if (_codec.AvailableBytesOut == 0)
-                        return BlockState.NeedMore;
-                }
-                else
-                {
-                    // There is no previous match to compare with, wait for
-                    // the next step to decide.
-
-                    match_available = 1;
-                    strstart++;
-                    lookahead--;
-                }
-            }
-
-            if (match_available != 0)
-            {
-                bflush = _tr_tally(0, window[strstart - 1] & 0xff);
-                match_available = 0;
-            }
-            flush_block_only(flush == FlushType.Finish);
-
-            if (_codec.AvailableBytesOut == 0)
-            {
-                if (flush == FlushType.Finish)
-                    return BlockState.FinishStarted;
-                else
-                    return BlockState.NeedMore;
-            }
-
-            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
-        }
-
-
-        internal int longest_match(int cur_match)
-        {
-            int chain_length = config.MaxChainLength; // max hash chain length
-            int scan         = strstart;              // current string
-            int match;                                // matched string
-            int len;                                  // length of current match
-            int best_len     = prev_length;           // best match length so far
-            int limit        = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
-
-            int niceLength = config.NiceLength;
-
-            // Stop when cur_match becomes <= limit. To simplify the code,
-            // we prevent matches with the string of window index 0.
-
-            int wmask = w_mask;
-
-            int strend = strstart + MAX_MATCH;
-            byte scan_end1 = window[scan + best_len - 1];
-            byte scan_end = window[scan + best_len];
-
-            // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-            // It is easy to get rid of this optimization if necessary.
-
-            // Do not waste too much time if we already have a good match:
-            if (prev_length >= config.GoodLength)
-            {
-                chain_length >>= 2;
-            }
-
-            // Do not look for matches beyond the end of the input. This is necessary
-            // to make deflate deterministic.
-            if (niceLength > lookahead)
-                niceLength = lookahead;
-
-            do
-            {
-                match = cur_match;
-
-                // Skip to next match if the match length cannot increase
-                // or if the match length is less than 2:
-                if (window[match + best_len] != scan_end ||
-                    window[match + best_len - 1] != scan_end1 ||
-                    window[match] != window[scan] ||
-                    window[++match] != window[scan + 1])
-                    continue;
-
-                // The check at best_len-1 can be removed because it will be made
-                // again later. (This heuristic is not always a win.)
-                // It is not necessary to compare scan[2] and match[2] since they
-                // are always equal when the other bytes match, given that
-                // the hash keys are equal and that HASH_BITS >= 8.
-                scan += 2; match++;
-
-                // We check for insufficient lookahead only every 8th comparison;
-                // the 256th check will be made at strstart+258.
-                do
-                {
-                }
-                while (window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] &&
-                       window[++scan] == window[++match] && scan < strend);
-
-                len = MAX_MATCH - (int)(strend - scan);
-                scan = strend - MAX_MATCH;
-
-                if (len > best_len)
-                {
-                    match_start = cur_match;
-                    best_len = len;
-                    if (len >= niceLength)
-                        break;
-                    scan_end1 = window[scan + best_len - 1];
-                    scan_end = window[scan + best_len];
-                }
-            }
-            while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0);
-
-            if (best_len <= lookahead)
-                return best_len;
-            return lookahead;
-        }
-
-
-        private bool Rfc1950BytesEmitted = false;
-        private bool _WantRfc1950HeaderBytes = true;
-        internal bool WantRfc1950HeaderBytes
-        {
-            get { return _WantRfc1950HeaderBytes; }
-            set { _WantRfc1950HeaderBytes = value; }
-        }
-
-
-        internal int Initialize(ZlibCodec codec, CompressionLevel level)
-        {
-            return Initialize(codec, level, ZlibConstants.WindowBitsMax);
-        }
-
-        internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits)
-        {
-            return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, CompressionStrategy.Default);
-        }
-
-        internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits, CompressionStrategy compressionStrategy)
-        {
-            return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, compressionStrategy);
-        }
-
-        internal int Initialize(ZlibCodec codec, CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy)
-        {
-            _codec = codec;
-            _codec.Message = null;
-
-            // validation
-            if (windowBits < 9 || windowBits > 15)
-                throw new ZlibException("windowBits must be in the range 9..15.");
-
-            if (memLevel < 1 || memLevel > MEM_LEVEL_MAX)
-                throw new ZlibException(String.Format("memLevel must be in the range 1.. {0}", MEM_LEVEL_MAX));
-
-            _codec.dstate = this;
-
-            w_bits = windowBits;
-            w_size = 1 << w_bits;
-            w_mask = w_size - 1;
-
-            hash_bits = memLevel + 7;
-            hash_size = 1 << hash_bits;
-            hash_mask = hash_size - 1;
-            hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
-
-            window = new byte[w_size * 2];
-            prev = new short[w_size];
-            head = new short[hash_size];
-
-            // for memLevel==8, this will be 16384, 16k
-            lit_bufsize = 1 << (memLevel + 6);
-
-            // Use a single array as the buffer for data pending compression,
-            // the output distance codes, and the output length codes (aka tree).
-            // orig comment: This works just fine since the average
-            // output size for (length,distance) codes is <= 24 bits.
-            pending = new byte[lit_bufsize * 4];
-            _distanceOffset = lit_bufsize;
-            _lengthOffset = (1 + 2) * lit_bufsize;
-
-            // So, for memLevel 8, the length of the pending buffer is 65536. 64k.
-            // The first 16k are pending bytes.
-            // The middle slice, of 32k, is used for distance codes.
-            // The final 16k are length codes.
-
-            this.compressionLevel = level;
-            this.compressionStrategy = strategy;
-
-            Reset();
-            return ZlibConstants.Z_OK;
-        }
-
-
-        internal void Reset()
-        {
-            _codec.TotalBytesIn = _codec.TotalBytesOut = 0;
-            _codec.Message = null;
-            //strm.data_type = Z_UNKNOWN;
-
-            pendingCount = 0;
-            nextPending = 0;
-
-            Rfc1950BytesEmitted = false;
-
-            status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE;
-            _codec._Adler32 = Adler.Adler32(0, null, 0, 0);
-
-            last_flush = (int)FlushType.None;
-
-            _InitializeTreeData();
-            _InitializeLazyMatch();
-        }
-
-
-        internal int End()
-        {
-            if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE)
-            {
-                return ZlibConstants.Z_STREAM_ERROR;
-            }
-            // Deallocate in reverse order of allocations:
-            pending = null;
-            head = null;
-            prev = null;
-            window = null;
-            // free
-            // dstate=null;
-            return status == BUSY_STATE ? ZlibConstants.Z_DATA_ERROR : ZlibConstants.Z_OK;
-        }
-
-
-        private void SetDeflater()
-        {
-            switch (config.Flavor)
-            {
-                case DeflateFlavor.Store:
-                    DeflateFunction = DeflateNone;
-                    break;
-                case DeflateFlavor.Fast:
-                    DeflateFunction = DeflateFast;
-                    break;
-                case DeflateFlavor.Slow:
-                    DeflateFunction = DeflateSlow;
-                    break;
-            }
-        }
-
-
-        internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
-        {
-            int result = ZlibConstants.Z_OK;
-
-            if (compressionLevel != level)
-            {
-                Config newConfig = Config.Lookup(level);
-
-                // change in the deflate flavor (Fast vs slow vs none)?
-                if (newConfig.Flavor != config.Flavor && _codec.TotalBytesIn != 0)
-                {
-                    // Flush the last buffer:
-                    result = _codec.Deflate(FlushType.Partial);
-                }
-
-                compressionLevel = level;
-                config = newConfig;
-                SetDeflater();
-            }
-
-            // no need to flush with change in strategy?  Really?
-            compressionStrategy = strategy;
-
-            return result;
-        }
-
-
-        internal int SetDictionary(byte[] dictionary)
-        {
-            int length = dictionary.Length;
-            int index = 0;
-
-            if (dictionary == null || status != INIT_STATE)
-                throw new ZlibException("Stream error.");
-
-            _codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length);
-
-            if (length < MIN_MATCH)
-                return ZlibConstants.Z_OK;
-            if (length > w_size - MIN_LOOKAHEAD)
-            {
-                length = w_size - MIN_LOOKAHEAD;
-                index = dictionary.Length - length; // use the tail of the dictionary
-            }
-            Array.Copy(dictionary, index, window, 0, length);
-            strstart = length;
-            block_start = length;
-
-            // Insert all strings in the hash table (except for the last two bytes).
-            // s->lookahead stays null, so s->ins_h will be recomputed at the next
-            // call of fill_window.
-
-            ins_h = window[0] & 0xff;
-            ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
-
-            for (int n = 0; n <= length - MIN_MATCH; n++)
-            {
-                ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-                prev[n & w_mask] = head[ins_h];
-                head[ins_h] = (short)n;
-            }
-            return ZlibConstants.Z_OK;
-        }
-
-
-
-        internal int Deflate(FlushType flush)
-        {
-            int old_flush;
-
-            if (_codec.OutputBuffer == null ||
-                (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) ||
-                (status == FINISH_STATE && flush != FlushType.Finish))
-            {
-                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_STREAM_ERROR)];
-                throw new ZlibException(String.Format("Something is fishy. [{0}]", _codec.Message));
-            }
-            if (_codec.AvailableBytesOut == 0)
-            {
-                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
-                throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)");
-            }
-
-            old_flush = last_flush;
-            last_flush = (int)flush;
-
-            // Write the zlib (rfc1950) header bytes
-            if (status == INIT_STATE)
-            {
-                int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
-                int level_flags = (((int)compressionLevel - 1) & 0xff) >> 1;
-
-                if (level_flags > 3)
-                    level_flags = 3;
-                header |= (level_flags << 6);
-                if (strstart != 0)
-                    header |= PRESET_DICT;
-                header += 31 - (header % 31);
-
-                status = BUSY_STATE;
-                //putShortMSB(header);
-                unchecked
-                {
-                    pending[pendingCount++] = (byte)(header >> 8);
-                    pending[pendingCount++] = (byte)header;
-                }
-                // Save the adler32 of the preset dictionary:
-                if (strstart != 0)
-                {
-                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24);
-                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16);
-                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8);
-                    pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF);
-                }
-                _codec._Adler32 = Adler.Adler32(0, null, 0, 0);
-            }
-
-            // Flush as much pending output as possible
-            if (pendingCount != 0)
-            {
-                _codec.flush_pending();
-                if (_codec.AvailableBytesOut == 0)
-                {
-                    //System.out.println("  avail_out==0");
-                    // Since avail_out is 0, deflate will be called again with
-                    // more output space, but possibly with both pending and
-                    // avail_in equal to zero. There won't be anything to do,
-                    // but this is not an error situation so make sure we
-                    // return OK instead of BUF_ERROR at next call of deflate:
-                    last_flush = -1;
-                    return ZlibConstants.Z_OK;
-                }
-
-                // Make sure there is something to do and avoid duplicate consecutive
-                // flushes. For repeated and useless calls with Z_FINISH, we keep
-                // returning Z_STREAM_END instead of Z_BUFF_ERROR.
-            }
-            else if (_codec.AvailableBytesIn == 0 &&
-                     (int)flush <= old_flush &&
-                     flush != FlushType.Finish)
-            {
-                // workitem 8557
-                //
-                // Not sure why this needs to be an error.  pendingCount == 0, which
-                // means there's nothing to deflate.  And the caller has not asked
-                // for a FlushType.Finish, but...  that seems very non-fatal.  We
-                // can just say "OK" and do nothing.
-
-                // _codec.Message = z_errmsg[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
-                // throw new ZlibException("AvailableBytesIn == 0 && flush<=old_flush && flush != FlushType.Finish");
-
-                return ZlibConstants.Z_OK;
-            }
-
-            // User must not provide more input after the first FINISH:
-            if (status == FINISH_STATE && _codec.AvailableBytesIn != 0)
-            {
-                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
-                throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0");
-            }
-
-            // Start a new block or continue the current one.
-            if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != FlushType.None && status != FINISH_STATE))
-            {
-                BlockState bstate = DeflateFunction(flush);
-
-                if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone)
-                {
-                    status = FINISH_STATE;
-                }
-                if (bstate == BlockState.NeedMore || bstate == BlockState.FinishStarted)
-                {
-                    if (_codec.AvailableBytesOut == 0)
-                    {
-                        last_flush = -1; // avoid BUF_ERROR next call, see above
-                    }
-                    return ZlibConstants.Z_OK;
-                    // If flush != Z_NO_FLUSH && avail_out == 0, the next call
-                    // of deflate should use the same flush parameter to make sure
-                    // that the flush is complete. So we don't have to output an
-                    // empty block here, this will be done at next call. This also
-                    // ensures that for a very small output buffer, we emit at most
-                    // one empty block.
-                }
-
-                if (bstate == BlockState.BlockDone)
-                {
-                    if (flush == FlushType.Partial)
-                    {
-                        _tr_align();
-                    }
-                    else
-                    {
-                        // FlushType.Full or FlushType.Sync
-                        _tr_stored_block(0, 0, false);
-                        // For a full flush, this empty block will be recognized
-                        // as a special marker by inflate_sync().
-                        if (flush == FlushType.Full)
-                        {
-                            // clear hash (forget the history)
-                            for (int i = 0; i < hash_size; i++)
-                                head[i] = 0;
-                        }
-                    }
-                    _codec.flush_pending();
-                    if (_codec.AvailableBytesOut == 0)
-                    {
-                        last_flush = -1; // avoid BUF_ERROR at next call, see above
-                        return ZlibConstants.Z_OK;
-                    }
-                }
-            }
-
-            if (flush != FlushType.Finish)
-                return ZlibConstants.Z_OK;
-
-            if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted)
-                return ZlibConstants.Z_STREAM_END;
-
-            // Write the zlib trailer (adler32)
-            pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24);
-            pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16);
-            pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8);
-            pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF);
-            //putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16)));
-            //putShortMSB((int)(_codec._Adler32 & 0xffff));
-
-            _codec.flush_pending();
-
-            // If avail_out is zero, the application will call deflate again
-            // to flush the rest.
-
-            Rfc1950BytesEmitted = true; // write the trailer only once!
-
-            return pendingCount != 0 ? ZlibConstants.Z_OK : ZlibConstants.Z_STREAM_END;
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/DeflateStream.cs b/EPPlus/Packaging/DotNetZip/Zlib/DeflateStream.cs
deleted file mode 100644
index c846469..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/DeflateStream.cs
+++ /dev/null
@@ -1,740 +0,0 @@
-// DeflateStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2010 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-31 14:48:11>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the DeflateStream class, which can be used as a replacement for
-// the System.IO.Compression.DeflateStream class in the .NET BCL.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    /// <summary>
-    /// A class for compressing and decompressing streams using the Deflate algorithm.
-    /// </summary>
-    ///
-    /// <remarks>
-    ///
-    /// <para>
-    ///   The DeflateStream is a <see
-    ///   href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see
-    ///   cref="System.IO.Stream"/>.  It adds DEFLATE compression or decompression to any
-    ///   stream.
-    /// </para>
-    ///
-    /// <para>
-    ///   Using this stream, applications can compress or decompress data via stream
-    ///   <c>Read</c> and <c>Write</c> operations.  Either compresssion or decompression
-    ///   can occur through either reading or writing. The compression format used is
-    ///   DEFLATE, which is documented in <see
-    ///   href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE
-    ///   Compressed Data Format Specification version 1.3.".
-    /// </para>
-    ///
-    /// <para>
-    ///   This class is similar to <see cref="ZlibStream"/>, except that
-    ///   <c>ZlibStream</c> adds the <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
-    ///   1950 - ZLIB</see> framing bytes to a compressed stream when compressing, or
-    ///   expects the RFC1950 framing bytes when decompressing. The <c>DeflateStream</c>
-    ///   does not.
-    /// </para>
-    ///
-    /// </remarks>
-    ///
-    /// <seealso cref="ZlibStream" />
-    /// <seealso cref="GZipStream" />
-    public class DeflateStream : System.IO.Stream
-    {
-        internal ZlibBaseStream _baseStream;
-        internal System.IO.Stream _innerStream;
-        bool _disposed;
-
-        /// <summary>
-        ///   Create a DeflateStream using the specified CompressionMode.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   When mode is <c>CompressionMode.Compress</c>, the DeflateStream will use
-        ///   the default compression level. The "captive" stream will be closed when
-        ///   the DeflateStream is closed.
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example uses a DeflateStream to compress data from a file, and writes
-        /// the compressed data to another file.
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
-        ///     {
-        ///         using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")
-        ///         Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress)
-        ///             Dim buffer As Byte() = New Byte(4096) {}
-        ///             Dim n As Integer = -1
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="stream">The stream which will be read or written.</param>
-        /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>
-        public DeflateStream(System.IO.Stream stream, CompressionMode mode)
-            : this(stream, mode, CompressionLevel.Default, false)
-        {
-        }
-
-        /// <summary>
-        /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is
-        ///   ignored.  The "captive" stream will be closed when the DeflateStream is
-        ///   closed.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example uses a DeflateStream to compress data from a file, and writes
-        ///   the compressed data to another file.
-        ///
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
-        ///     {
-        ///         using (Stream compressor = new DeflateStream(raw,
-        ///                                                      CompressionMode.Compress,
-        ///                                                      CompressionLevel.BestCompression))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n= -1;
-        ///             while (n != 0)
-        ///             {
-        ///                 if (n &gt; 0)
-        ///                     compressor.Write(buffer, 0, n);
-        ///                 n= input.Read(buffer, 0, buffer.Length);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")
-        ///         Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
-        ///             Dim buffer As Byte() = New Byte(4096) {}
-        ///             Dim n As Integer = -1
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="stream">The stream to be read or written while deflating or inflating.</param>
-        /// <param name="mode">Indicates whether the <c>DeflateStream</c> will compress or decompress.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level)
-            : this(stream, mode, level, false)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>DeflateStream</c> using the specified
-        ///   <c>CompressionMode</c>, and explicitly specify whether the
-        ///   stream should be left open after Deflation or Inflation.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This constructor allows the application to request that the captive stream
-        ///   remain open after the deflation or inflation occurs.  By default, after
-        ///   <c>Close()</c> is called on the stream, the captive stream is also
-        ///   closed. In some cases this is not desired, for example if the stream is a
-        ///   memory stream that will be re-read after compression.  Specify true for
-        ///   the <paramref name="leaveOpen"/> parameter to leave the stream open.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <c>DeflateStream</c> will use the default compression level.
-        /// </para>
-        ///
-        /// <para>
-        ///   See the other overloads of this constructor for example code.
-        /// </para>
-        /// </remarks>
-        ///
-        /// <param name="stream">
-        ///   The stream which will be read or written. This is called the
-        ///   "captive" stream in other places in this documentation.
-        /// </param>
-        ///
-        /// <param name="mode">
-        ///   Indicates whether the <c>DeflateStream</c> will compress or decompress.
-        /// </param>
-        ///
-        /// <param name="leaveOpen">true if the application would like the stream to
-        /// remain open after inflation/deflation.</param>
-        public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen)
-            : this(stream, mode, CompressionLevel.Default, leaveOpen)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>DeflateStream</c> using the specified <c>CompressionMode</c>
-        ///   and the specified <c>CompressionLevel</c>, and explicitly specify whether
-        ///   the stream should be left open after Deflation or Inflation.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored.
-        /// </para>
-        ///
-        /// <para>
-        ///   This constructor allows the application to request that the captive stream
-        ///   remain open after the deflation or inflation occurs.  By default, after
-        ///   <c>Close()</c> is called on the stream, the captive stream is also
-        ///   closed. In some cases this is not desired, for example if the stream is a
-        ///   <see cref="System.IO.MemoryStream"/> that will be re-read after
-        ///   compression.  Specify true for the <paramref name="leaveOpen"/> parameter
-        ///   to leave the stream open.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        ///   This example shows how to use a <c>DeflateStream</c> to compress data from
-        ///   a file, and store the compressed data into another file.
-        ///
-        /// <code>
-        /// using (var output = System.IO.File.Create(fileToCompress + ".deflated"))
-        /// {
-        ///     using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        ///     {
-        ///         using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n= -1;
-        ///             while (n != 0)
-        ///             {
-        ///                 if (n &gt; 0)
-        ///                     compressor.Write(buffer, 0, n);
-        ///                 n= input.Read(buffer, 0, buffer.Length);
-        ///             }
-        ///         }
-        ///     }
-        ///     // can write additional data to the output stream here
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using output As FileStream = File.Create(fileToCompress &amp; ".deflated")
-        ///     Using input As Stream = File.OpenRead(fileToCompress)
-        ///         Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
-        ///             Dim buffer As Byte() = New Byte(4096) {}
-        ///             Dim n As Integer = -1
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        ///     ' can write additional data to the output stream here.
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="stream">The stream which will be read or written.</param>
-        /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>
-        /// <param name="leaveOpen">true if the application would like the stream to remain open after inflation/deflation.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
-        {
-            _innerStream = stream;
-            _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen);
-        }
-
-        #region Zlib properties
-
-        /// <summary>
-        /// This property sets the flush behavior on the stream.
-        /// </summary>
-        /// <remarks> See the ZLIB documentation for the meaning of the flush behavior.
-        /// </remarks>
-        virtual public FlushType FlushMode
-        {
-            get { return (this._baseStream._flushMode); }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("DeflateStream");
-                this._baseStream._flushMode = value;
-            }
-        }
-
-        /// <summary>
-        ///   The size of the working buffer for the compression codec.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The working buffer is used for all stream operations.  The default size is
-        ///   1024 bytes.  The minimum size is 128 bytes. You may get better performance
-        ///   with a larger buffer.  Then again, you might not.  You would have to test
-        ///   it.
-        /// </para>
-        ///
-        /// <para>
-        ///   Set this before the first call to <c>Read()</c> or <c>Write()</c> on the
-        ///   stream. If you try to set it afterwards, it will throw.
-        /// </para>
-        /// </remarks>
-        public int BufferSize
-        {
-            get
-            {
-                return this._baseStream._bufferSize;
-            }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("DeflateStream");
-                if (this._baseStream._workingBuffer != null)
-                    throw new ZlibException("The working buffer is already set.");
-                if (value < ZlibConstants.WorkingBufferSizeMin)
-                    throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));
-                this._baseStream._bufferSize = value;
-            }
-        }
-
-        /// <summary>
-        ///   The ZLIB strategy to be used during compression.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   By tweaking this parameter, you may be able to optimize the compression for
-        ///   data with particular characteristics.
-        /// </remarks>
-        public CompressionStrategy Strategy
-        {
-            get
-            {
-                return this._baseStream.Strategy;
-            }
-            set
-            {
-            if (_disposed) throw new ObjectDisposedException("DeflateStream");
-                this._baseStream.Strategy = value;
-            }
-        }
-
-        /// <summary> Returns the total number of bytes input so far.</summary>
-        virtual public long TotalIn
-        {
-            get
-            {
-                return this._baseStream._z.TotalBytesIn;
-            }
-        }
-
-        /// <summary> Returns the total number of bytes output so far.</summary>
-        virtual public long TotalOut
-        {
-            get
-            {
-                return this._baseStream._z.TotalBytesOut;
-            }
-        }
-
-        #endregion
-
-        #region System.IO.Stream methods
-        /// <summary>
-        ///   Dispose the stream.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     This may or may not result in a <c>Close()</c> call on the captive
-        ///     stream.  See the constructors that have a <c>leaveOpen</c> parameter
-        ///     for more information.
-        ///   </para>
-        ///   <para>
-        ///     Application code won't call this code directly.  This method may be
-        ///     invoked in two distinct scenarios.  If disposing == true, the method
-        ///     has been called directly or indirectly by a user's code, for example
-        ///     via the public Dispose() method. In this case, both managed and
-        ///     unmanaged resources can be referenced and disposed.  If disposing ==
-        ///     false, the method has been called by the runtime from inside the
-        ///     object finalizer and this method should not reference other objects;
-        ///     in that case only unmanaged resources must be referenced or
-        ///     disposed.
-        ///   </para>
-        /// </remarks>
-        /// <param name="disposing">
-        ///   true if the Dispose method was invoked by user code.
-        /// </param>
-        protected override void Dispose(bool disposing)
-        {
-            try
-            {
-                if (!_disposed)
-                {
-                    if (disposing && (this._baseStream != null))
-                        this._baseStream.Close();
-                    _disposed = true;
-                }
-            }
-            finally
-            {
-                base.Dispose(disposing);
-            }
-        }
-
-
-
-        /// <summary>
-        /// Indicates whether the stream can be read.
-        /// </summary>
-        /// <remarks>
-        /// The return value depends on whether the captive stream supports reading.
-        /// </remarks>
-        public override bool CanRead
-        {
-            get
-            {
-                if (_disposed) throw new ObjectDisposedException("DeflateStream");
-                return _baseStream._stream.CanRead;
-            }
-        }
-
-        /// <summary>
-        /// Indicates whether the stream supports Seek operations.
-        /// </summary>
-        /// <remarks>
-        /// Always returns false.
-        /// </remarks>
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-
-        /// <summary>
-        /// Indicates whether the stream can be written.
-        /// </summary>
-        /// <remarks>
-        /// The return value depends on whether the captive stream supports writing.
-        /// </remarks>
-        public override bool CanWrite
-        {
-            get
-            {
-                if (_disposed) throw new ObjectDisposedException("DeflateStream");
-                return _baseStream._stream.CanWrite;
-            }
-        }
-
-        /// <summary>
-        /// Flush the stream.
-        /// </summary>
-        public override void Flush()
-        {
-            if (_disposed) throw new ObjectDisposedException("DeflateStream");
-            _baseStream.Flush();
-        }
-
-        /// <summary>
-        /// Reading this property always throws a <see cref="NotImplementedException"/>.
-        /// </summary>
-        public override long Length
-        {
-            get { throw new NotImplementedException(); }
-        }
-
-        /// <summary>
-        /// The position of the stream pointer.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Setting this property always throws a <see
-        ///   cref="NotImplementedException"/>. Reading will return the total bytes
-        ///   written out, if used in writing, or the total bytes read in, if used in
-        ///   reading.  The count may refer to compressed bytes or uncompressed bytes,
-        ///   depending on how you've used the stream.
-        /// </remarks>
-        public override long Position
-        {
-            get
-            {
-                if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
-                    return this._baseStream._z.TotalBytesOut;
-                if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
-                    return this._baseStream._z.TotalBytesIn;
-                return 0;
-            }
-            set { throw new NotImplementedException(); }
-        }
-
-        /// <summary>
-        /// Read data from the stream.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   If you wish to use the <c>DeflateStream</c> to compress data while
-        ///   reading, you can create a <c>DeflateStream</c> with
-        ///   <c>CompressionMode.Compress</c>, providing an uncompressed data stream.
-        ///   Then call Read() on that <c>DeflateStream</c>, and the data read will be
-        ///   compressed as you read.  If you wish to use the <c>DeflateStream</c> to
-        ///   decompress data while reading, you can create a <c>DeflateStream</c> with
-        ///   <c>CompressionMode.Decompress</c>, providing a readable compressed data
-        ///   stream.  Then call Read() on that <c>DeflateStream</c>, and the data read
-        ///   will be decompressed as you read.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both.
-        /// </para>
-        ///
-        /// </remarks>
-        /// <param name="buffer">The buffer into which the read data should be placed.</param>
-        /// <param name="offset">the offset within that data array to put the first byte read.</param>
-        /// <param name="count">the number of bytes to read.</param>
-        /// <returns>the number of bytes actually read</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            if (_disposed) throw new ObjectDisposedException("DeflateStream");
-            return _baseStream.Read(buffer, offset, count);
-        }
-
-
-        /// <summary>
-        /// Calling this method always throws a <see cref="NotImplementedException"/>.
-        /// </summary>
-        /// <param name="offset">this is irrelevant, since it will always throw!</param>
-        /// <param name="origin">this is irrelevant, since it will always throw!</param>
-        /// <returns>irrelevant!</returns>
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotImplementedException();
-        }
-
-        /// <summary>
-        /// Calling this method always throws a <see cref="NotImplementedException"/>.
-        /// </summary>
-        /// <param name="value">this is irrelevant, since it will always throw!</param>
-        public override void SetLength(long value)
-        {
-            throw new NotImplementedException();
-        }
-
-        /// <summary>
-        ///   Write data to the stream.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   If you wish to use the <c>DeflateStream</c> to compress data while
-        ///   writing, you can create a <c>DeflateStream</c> with
-        ///   <c>CompressionMode.Compress</c>, and a writable output stream.  Then call
-        ///   <c>Write()</c> on that <c>DeflateStream</c>, providing uncompressed data
-        ///   as input.  The data sent to the output stream will be the compressed form
-        ///   of the data written.  If you wish to use the <c>DeflateStream</c> to
-        ///   decompress data while writing, you can create a <c>DeflateStream</c> with
-        ///   <c>CompressionMode.Decompress</c>, and a writable output stream.  Then
-        ///   call <c>Write()</c> on that stream, providing previously compressed
-        ///   data. The data sent to the output stream will be the decompressed form of
-        ///   the data written.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>,
-        ///   but not both.
-        /// </para>
-        ///
-        /// </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) throw new ObjectDisposedException("DeflateStream");
-            _baseStream.Write(buffer, offset, count);
-        }
-        #endregion
-
-
-
-
-        /// <summary>
-        ///   Compress a string into a byte array using DEFLATE (RFC 1951).
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Uncompress it with <see cref="DeflateStream.UncompressString(byte[])"/>.
-        /// </remarks>
-        ///
-        /// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso>
-        /// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso>
-        /// <seealso cref="GZipStream.CompressString(string)">GZipStream.CompressString(string)</seealso>
-        /// <seealso cref="ZlibStream.CompressString(string)">ZlibStream.CompressString(string)</seealso>
-        ///
-        /// <param name="s">
-        ///   A string to compress. The string will first be encoded
-        ///   using UTF8, then compressed.
-        /// </param>
-        ///
-        /// <returns>The string in compressed form</returns>
-        public static byte[] CompressString(String s)
-        {
-            using (var ms = new System.IO.MemoryStream())
-            {
-                System.IO.Stream compressor =
-                    new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression);
-                ZlibBaseStream.CompressString(s, compressor);
-                return ms.ToArray();
-            }
-        }
-
-
-        /// <summary>
-        ///   Compress a byte array into a new byte array using DEFLATE.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Uncompress it with <see cref="DeflateStream.UncompressBuffer(byte[])"/>.
-        /// </remarks>
-        ///
-        /// <seealso cref="DeflateStream.CompressString(string)">DeflateStream.CompressString(string)</seealso>
-        /// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso>
-        /// <seealso cref="GZipStream.CompressBuffer(byte[])">GZipStream.CompressBuffer(byte[])</seealso>
-        /// <seealso cref="ZlibStream.CompressBuffer(byte[])">ZlibStream.CompressBuffer(byte[])</seealso>
-        ///
-        /// <param name="b">
-        ///   A buffer to compress.
-        /// </param>
-        ///
-        /// <returns>The data in compressed form</returns>
-        public static byte[] CompressBuffer(byte[] b)
-        {
-            using (var ms = new System.IO.MemoryStream())
-            {
-                System.IO.Stream compressor =
-                    new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression );
-
-                ZlibBaseStream.CompressBuffer(b, compressor);
-                return ms.ToArray();
-            }
-        }
-
-
-        /// <summary>
-        ///   Uncompress a DEFLATE'd byte array into a single string.
-        /// </summary>
-        ///
-        /// <seealso cref="DeflateStream.CompressString(String)">DeflateStream.CompressString(String)</seealso>
-        /// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso>
-        /// <seealso cref="GZipStream.UncompressString(byte[])">GZipStream.UncompressString(byte[])</seealso>
-        /// <seealso cref="ZlibStream.UncompressString(byte[])">ZlibStream.UncompressString(byte[])</seealso>
-        ///
-        /// <param name="compressed">
-        ///   A buffer containing DEFLATE-compressed data.
-        /// </param>
-        ///
-        /// <returns>The uncompressed string</returns>
-        public static String UncompressString(byte[] compressed)
-        {
-            using (var input = new System.IO.MemoryStream(compressed))
-            {
-                System.IO.Stream decompressor =
-                    new DeflateStream(input, CompressionMode.Decompress);
-
-                return ZlibBaseStream.UncompressString(compressed, decompressor);
-            }
-        }
-
-
-        /// <summary>
-        ///   Uncompress a DEFLATE'd byte array into a byte array.
-        /// </summary>
-        ///
-        /// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso>
-        /// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso>
-        /// <seealso cref="GZipStream.UncompressBuffer(byte[])">GZipStream.UncompressBuffer(byte[])</seealso>
-        /// <seealso cref="ZlibStream.UncompressBuffer(byte[])">ZlibStream.UncompressBuffer(byte[])</seealso>
-        ///
-        /// <param name="compressed">
-        ///   A buffer containing data that has been compressed with DEFLATE.
-        /// </param>
-        ///
-        /// <returns>The data in uncompressed form</returns>
-        public static byte[] UncompressBuffer(byte[] compressed)
-        {
-            using (var input = new System.IO.MemoryStream(compressed))
-            {
-                System.IO.Stream decompressor =
-                    new DeflateStream( input, CompressionMode.Decompress );
-
-                return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
-            }
-        }
-
-    }
-
-}
-
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/GZipStream.cs b/EPPlus/Packaging/DotNetZip/Zlib/GZipStream.cs
deleted file mode 100644
index a83a496..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/GZipStream.cs
+++ /dev/null
@@ -1,1033 +0,0 @@
-// GZipStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
-// 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-August-08 18:14:39>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the GZipStream class, which can be used as a replacement for
-// the System.IO.Compression.GZipStream class in the .NET BCL.  NB: The design is not
-// completely OO clean: there is some intelligence in the ZlibBaseStream that reads the
-// GZip header.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    /// <summary>
-    ///   A class for compressing and decompressing GZIP streams.
-    /// </summary>
-    /// <remarks>
-    ///
-    /// <para>
-    ///   The <c>GZipStream</c> is a <see
-    ///   href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a
-    ///   <see cref="Stream"/>. It adds GZIP compression or decompression to any
-    ///   stream.
-    /// </para>
-    ///
-    /// <para>
-    ///   Like the <c>System.IO.Compression.GZipStream</c> in the .NET Base Class Library, the
-    ///   <c>Ionic.Zlib.GZipStream</c> can compress while writing, or decompress while
-    ///   reading, but not vice versa.  The compression method used is GZIP, which is
-    ///   documented in <see href="http://www.ietf.org/rfc/rfc1952.txt">IETF RFC
-    ///   1952</see>, "GZIP file format specification version 4.3".</para>
-    ///
-    /// <para>
-    ///   A <c>GZipStream</c> can be used to decompress data (through <c>Read()</c>) or
-    ///   to compress data (through <c>Write()</c>), but not both.
-    /// </para>
-    ///
-    /// <para>
-    ///   If you wish to use the <c>GZipStream</c> to compress data, you must wrap it
-    ///   around a write-able stream. As you call <c>Write()</c> on the <c>GZipStream</c>, the
-    ///   data will be compressed into the GZIP format.  If you want to decompress data,
-    ///   you must wrap the <c>GZipStream</c> around a readable stream that contains an
-    ///   IETF RFC 1952-compliant stream.  The data will be decompressed as you call
-    ///   <c>Read()</c> on the <c>GZipStream</c>.
-    /// </para>
-    ///
-    /// <para>
-    ///   Though the GZIP format allows data from multiple files to be concatenated
-    ///   together, this stream handles only a single segment of GZIP format, typically
-    ///   representing a single file.
-    /// </para>
-    ///
-    /// <para>
-    ///   This class is similar to <see cref="ZlibStream"/> and <see cref="DeflateStream"/>.
-    ///   <c>ZlibStream</c> handles RFC1950-compliant streams.  <see cref="DeflateStream"/>
-    ///   handles RFC1951-compliant streams. This class handles RFC1952-compliant streams.
-    /// </para>
-    ///
-    /// </remarks>
-    ///
-    /// <seealso cref="DeflateStream" />
-    /// <seealso cref="ZlibStream" />
-    public class GZipStream : System.IO.Stream
-    {
-        // GZip format
-        // source: http://tools.ietf.org/html/rfc1952
-        //
-        //  header id:           2 bytes    1F 8B
-        //  compress method      1 byte     8= DEFLATE (none other supported)
-        //  flag                 1 byte     bitfield (See below)
-        //  mtime                4 bytes    time_t (seconds since jan 1, 1970 UTC of the file.
-        //  xflg                 1 byte     2 = max compress used , 4 = max speed (can be ignored)
-        //  OS                   1 byte     OS for originating archive. set to 0xFF in compression.
-        //  extra field length   2 bytes    optional - only if FEXTRA is set.
-        //  extra field          varies
-        //  filename             varies     optional - if FNAME is set.  zero terminated. ISO-8859-1.
-        //  file comment         varies     optional - if FCOMMENT is set. zero terminated. ISO-8859-1.
-        //  crc16                1 byte     optional - present only if FHCRC bit is set
-        //  compressed data      varies
-        //  CRC32                4 bytes
-        //  isize                4 bytes    data size modulo 2^32
-        //
-        //     FLG (FLaGs)
-        //                bit 0   FTEXT - indicates file is ASCII text (can be safely ignored)
-        //                bit 1   FHCRC - there is a CRC16 for the header immediately following the header
-        //                bit 2   FEXTRA - extra fields are present
-        //                bit 3   FNAME - the zero-terminated filename is present. encoding; ISO-8859-1.
-        //                bit 4   FCOMMENT  - a zero-terminated file comment is present. encoding: ISO-8859-1
-        //                bit 5   reserved
-        //                bit 6   reserved
-        //                bit 7   reserved
-        //
-        // On consumption:
-        // Extra field is a bunch of nonsense and can be safely ignored.
-        // Header CRC and OS, likewise.
-        //
-        // on generation:
-        // all optional fields get 0, except for the OS, which gets 255.
-        //
-
-
-
-        /// <summary>
-        ///   The comment on the GZIP stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The GZIP format allows for each file to optionally have an associated
-        ///   comment stored with the file.  The comment is encoded with the ISO-8859-1
-        ///   code page.  To include a comment in a GZIP stream you create, set this
-        ///   property before calling <c>Write()</c> for the first time on the
-        ///   <c>GZipStream</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   When using <c>GZipStream</c> to decompress, you can retrieve this property
-        ///   after the first call to <c>Read()</c>.  If no comment has been set in the
-        ///   GZIP bytestream, the Comment property will return <c>null</c>
-        ///   (<c>Nothing</c> in VB).
-        /// </para>
-        /// </remarks>
-        public String Comment
-        {
-            get
-            {
-                return _Comment;
-            }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("GZipStream");
-                _Comment = value;
-            }
-        }
-
-        /// <summary>
-        ///   The FileName for the GZIP stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The GZIP format optionally allows each file to have an associated
-        ///   filename.  When compressing data (through <c>Write()</c>), set this
-        ///   FileName before calling <c>Write()</c> the first time on the <c>GZipStream</c>.
-        ///   The actual filename is encoded into the GZIP bytestream with the
-        ///   ISO-8859-1 code page, according to RFC 1952. It is the application's
-        ///   responsibility to insure that the FileName can be encoded and decoded
-        ///   correctly with this code page.
-        /// </para>
-        ///
-        /// <para>
-        ///   When decompressing (through <c>Read()</c>), you can retrieve this value
-        ///   any time after the first <c>Read()</c>.  In the case where there was no filename
-        ///   encoded into the GZIP bytestream, the property will return <c>null</c> (<c>Nothing</c>
-        ///   in VB).
-        /// </para>
-        /// </remarks>
-        public String FileName
-        {
-            get { return _FileName; }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("GZipStream");
-                _FileName = value;
-                if (_FileName == null) return;
-                if (_FileName.IndexOf("/") != -1)
-                {
-                    _FileName = _FileName.Replace("/", "\\");
-                }
-                if (_FileName.EndsWith("\\"))
-                    throw new Exception("Illegal filename");
-                if (_FileName.IndexOf("\\") != -1)
-                {
-                    // trim any leading path
-                    _FileName = Path.GetFileName(_FileName);
-                }
-            }
-        }
-
-        /// <summary>
-        ///   The last modified time for the GZIP stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   GZIP allows the storage of a last modified time with each GZIP entry.
-        ///   When compressing data, you can set this before the first call to
-        ///   <c>Write()</c>.  When decompressing, you can retrieve this value any time
-        ///   after the first call to <c>Read()</c>.
-        /// </remarks>
-        public DateTime? LastModified;
-
-        /// <summary>
-        /// The CRC on the GZIP stream.
-        /// </summary>
-        /// <remarks>
-        /// This is used for internal error checking. You probably don't need to look at this property.
-        /// </remarks>
-        public int Crc32 { get { return _Crc32; } }
-
-        private int _headerByteCount;
-        internal ZlibBaseStream _baseStream;
-        bool _disposed;
-        bool _firstReadDone;
-        string _FileName;
-        string _Comment;
-        int _Crc32;
-
-
-        /// <summary>
-        ///   Create a <c>GZipStream</c> using the specified <c>CompressionMode</c>.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Compress</c>, the <c>GZipStream</c> will use the
-        ///   default compression level.
-        /// </para>
-        ///
-        /// <para>
-        ///   As noted in the class documentation, the <c>CompressionMode</c> (Compress
-        ///   or Decompress) also establishes the "direction" of the stream.  A
-        ///   <c>GZipStream</c> with <c>CompressionMode.Compress</c> works only through
-        ///   <c>Write()</c>.  A <c>GZipStream</c> with
-        ///   <c>CompressionMode.Decompress</c> works only through <c>Read()</c>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example shows how to use a GZipStream to compress data.
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(outputFile))
-        ///     {
-        ///         using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Dim outputFile As String = (fileToCompress &amp; ".compressed")
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(outputFile)
-        ///     Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress)
-        ///         Dim buffer As Byte() = New Byte(4096) {}
-        ///         Dim n As Integer = -1
-        ///         Do While (n &lt;&gt; 0)
-        ///             If (n &gt; 0) Then
-        ///                 compressor.Write(buffer, 0, n)
-        ///             End If
-        ///             n = input.Read(buffer, 0, buffer.Length)
-        ///         Loop
-        ///     End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <example>
-        /// This example shows how to use a GZipStream to uncompress a file.
-        /// <code>
-        /// private void GunZipFile(string filename)
-        /// {
-        ///     if (!filename.EndsWith(".gz))
-        ///         throw new ArgumentException("filename");
-        ///     var DecompressedFile = filename.Substring(0,filename.Length-3);
-        ///     byte[] working = new byte[WORKING_BUFFER_SIZE];
-        ///     int n= 1;
-        ///     using (System.IO.Stream input = System.IO.File.OpenRead(filename))
-        ///     {
-        ///         using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true))
-        ///         {
-        ///             using (var output = System.IO.File.Create(DecompressedFile))
-        ///             {
-        ///                 while (n !=0)
-        ///                 {
-        ///                     n= decompressor.Read(working, 0, working.Length);
-        ///                     if (n > 0)
-        ///                     {
-        ///                         output.Write(working, 0, n);
-        ///                     }
-        ///                 }
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Private Sub GunZipFile(ByVal filename as String)
-        ///     If Not (filename.EndsWith(".gz)) Then
-        ///         Throw New ArgumentException("filename")
-        ///     End If
-        ///     Dim DecompressedFile as String = filename.Substring(0,filename.Length-3)
-        ///     Dim working(WORKING_BUFFER_SIZE) as Byte
-        ///     Dim n As Integer = 1
-        ///     Using input As Stream = File.OpenRead(filename)
-        ///         Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True)
-        ///             Using output As Stream = File.Create(UncompressedFile)
-        ///                 Do
-        ///                     n= decompressor.Read(working, 0, working.Length)
-        ///                     If n > 0 Then
-        ///                         output.Write(working, 0, n)
-        ///                     End IF
-        ///                 Loop While (n  > 0)
-        ///             End Using
-        ///         End Using
-        ///     End Using
-        /// End Sub
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="stream">The stream which will be read or written.</param>
-        /// <param name="mode">Indicates whether the GZipStream will compress or decompress.</param>
-        public GZipStream(Stream stream, CompressionMode mode)
-            : this(stream, mode, CompressionLevel.Default, false)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>GZipStream</c> using the specified <c>CompressionMode</c> and
-        ///   the specified <c>CompressionLevel</c>.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The <c>CompressionMode</c> (Compress or Decompress) also establishes the
-        ///   "direction" of the stream.  A <c>GZipStream</c> with
-        ///   <c>CompressionMode.Compress</c> works only through <c>Write()</c>.  A
-        ///   <c>GZipStream</c> with <c>CompressionMode.Decompress</c> works only
-        ///   through <c>Read()</c>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        /// This example shows how to use a <c>GZipStream</c> to compress a file into a .gz file.
-        ///
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(fileToCompress + ".gz"))
-        ///     {
-        ///         using (Stream compressor = new GZipStream(raw,
-        ///                                                   CompressionMode.Compress,
-        ///                                                   CompressionLevel.BestCompression))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".gz")
-        ///         Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
-        ///             Dim buffer As Byte() = New Byte(4096) {}
-        ///             Dim n As Integer = -1
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="stream">The stream to be read or written while deflating or inflating.</param>
-        /// <param name="mode">Indicates whether the <c>GZipStream</c> will compress or decompress.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level)
-            : this(stream, mode, level, false)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>GZipStream</c> using the specified <c>CompressionMode</c>, and
-        ///   explicitly specify whether the stream should be left open after Deflation
-        ///   or Inflation.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This constructor allows the application to request that the captive stream
-        ///   remain open after the deflation or inflation occurs.  By default, after
-        ///   <c>Close()</c> is called on the stream, the captive stream is also
-        ///   closed. In some cases this is not desired, for example if the stream is a
-        ///   memory stream that will be re-read after compressed data has been written
-        ///   to it.  Specify true for the <paramref name="leaveOpen"/> parameter to leave
-        ///   the stream open.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <see cref="CompressionMode"/> (Compress or Decompress) also
-        ///   establishes the "direction" of the stream.  A <c>GZipStream</c> with
-        ///   <c>CompressionMode.Compress</c> works only through <c>Write()</c>.  A <c>GZipStream</c>
-        ///   with <c>CompressionMode.Decompress</c> works only through <c>Read()</c>.
-        /// </para>
-        ///
-        /// <para>
-        ///   The <c>GZipStream</c> will use the default compression level. If you want
-        ///   to specify the compression level, see <see cref="GZipStream(Stream,
-        ///   CompressionMode, CompressionLevel, bool)"/>.
-        /// </para>
-        ///
-        /// <para>
-        ///   See the other overloads of this constructor for example code.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="stream">
-        ///   The stream which will be read or written. This is called the "captive"
-        ///   stream in other places in this documentation.
-        /// </param>
-        ///
-        /// <param name="mode">Indicates whether the GZipStream will compress or decompress.
-        /// </param>
-        ///
-        /// <param name="leaveOpen">
-        ///   true if the application would like the base stream to remain open after
-        ///   inflation/deflation.
-        /// </param>
-        public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen)
-            : this(stream, mode, CompressionLevel.Default, leaveOpen)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>GZipStream</c> using the specified <c>CompressionMode</c> and the
-        ///   specified <c>CompressionLevel</c>, and explicitly specify whether the
-        ///   stream should be left open after Deflation or Inflation.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This constructor allows the application to request that the captive stream
-        ///   remain open after the deflation or inflation occurs.  By default, after
-        ///   <c>Close()</c> is called on the stream, the captive stream is also
-        ///   closed. In some cases this is not desired, for example if the stream is a
-        ///   memory stream that will be re-read after compressed data has been written
-        ///   to it.  Specify true for the <paramref name="leaveOpen"/> parameter to
-        ///   leave the stream open.
-        /// </para>
-        ///
-        /// <para>
-        ///   As noted in the class documentation, the <c>CompressionMode</c> (Compress
-        ///   or Decompress) also establishes the "direction" of the stream.  A
-        ///   <c>GZipStream</c> with <c>CompressionMode.Compress</c> works only through
-        ///   <c>Write()</c>.  A <c>GZipStream</c> with <c>CompressionMode.Decompress</c> works only
-        ///   through <c>Read()</c>.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example shows how to use a <c>GZipStream</c> to compress data.
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(outputFile))
-        ///     {
-        ///         using (Stream compressor = new GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, true))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Dim outputFile As String = (fileToCompress &amp; ".compressed")
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(outputFile)
-        ///     Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, True)
-        ///         Dim buffer As Byte() = New Byte(4096) {}
-        ///         Dim n As Integer = -1
-        ///         Do While (n &lt;&gt; 0)
-        ///             If (n &gt; 0) Then
-        ///                 compressor.Write(buffer, 0, n)
-        ///             End If
-        ///             n = input.Read(buffer, 0, buffer.Length)
-        ///         Loop
-        ///     End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="stream">The stream which will be read or written.</param>
-        /// <param name="mode">Indicates whether the GZipStream will compress or decompress.</param>
-        /// <param name="leaveOpen">true if the application would like the stream to remain open after inflation/deflation.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
-        {
-            _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen);
-        }
-
-        #region Zlib properties
-
-        /// <summary>
-        /// This property sets the flush behavior on the stream.
-        /// </summary>
-        virtual public FlushType FlushMode
-        {
-            get { return (this._baseStream._flushMode); }
-            set {
-                if (_disposed) throw new ObjectDisposedException("GZipStream");
-                this._baseStream._flushMode = value;
-            }
-        }
-
-        /// <summary>
-        ///   The size of the working buffer for the compression codec.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The working buffer is used for all stream operations.  The default size is
-        ///   1024 bytes.  The minimum size is 128 bytes. You may get better performance
-        ///   with a larger buffer.  Then again, you might not.  You would have to test
-        ///   it.
-        /// </para>
-        ///
-        /// <para>
-        ///   Set this before the first call to <c>Read()</c> or <c>Write()</c> on the
-        ///   stream. If you try to set it afterwards, it will throw.
-        /// </para>
-        /// </remarks>
-        public int BufferSize
-        {
-            get
-            {
-                return this._baseStream._bufferSize;
-            }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("GZipStream");
-                if (this._baseStream._workingBuffer != null)
-                    throw new ZlibException("The working buffer is already set.");
-                if (value < ZlibConstants.WorkingBufferSizeMin)
-                    throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));
-                this._baseStream._bufferSize = value;
-            }
-        }
-
-
-        /// <summary> Returns the total number of bytes input so far.</summary>
-        virtual public long TotalIn
-        {
-            get
-            {
-                return this._baseStream._z.TotalBytesIn;
-            }
-        }
-
-        /// <summary> Returns the total number of bytes output so far.</summary>
-        virtual public long TotalOut
-        {
-            get
-            {
-                return this._baseStream._z.TotalBytesOut;
-            }
-        }
-
-        #endregion
-
-        #region Stream methods
-
-        /// <summary>
-        ///   Dispose the stream.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     This may or may not result in a <c>Close()</c> call on the captive
-        ///     stream.  See the constructors that have a <c>leaveOpen</c> parameter
-        ///     for more information.
-        ///   </para>
-        ///   <para>
-        ///     This method may be invoked in two distinct scenarios.  If disposing
-        ///     == true, the method has been called directly or indirectly by a
-        ///     user's code, for example via the public Dispose() method. In this
-        ///     case, both managed and unmanaged resources can be referenced and
-        ///     disposed.  If disposing == false, the method has been called by the
-        ///     runtime from inside the object finalizer and this method should not
-        ///     reference other objects; in that case only unmanaged resources must
-        ///     be referenced or disposed.
-        ///   </para>
-        /// </remarks>
-        /// <param name="disposing">
-        ///   indicates whether the Dispose method was invoked by user code.
-        /// </param>
-        protected override void Dispose(bool disposing)
-        {
-            try
-            {
-                if (!_disposed)
-                {
-                    if (disposing && (this._baseStream != null))
-                    {
-                        this._baseStream.Close();
-                        this._Crc32 = _baseStream.Crc32;
-                    }
-                    _disposed = true;
-                }
-            }
-            finally
-            {
-                base.Dispose(disposing);
-            }
-        }
-
-
-        /// <summary>
-        /// Indicates whether the stream can be read.
-        /// </summary>
-        /// <remarks>
-        /// The return value depends on whether the captive stream supports reading.
-        /// </remarks>
-        public override bool CanRead
-        {
-            get
-            {
-                if (_disposed) throw new ObjectDisposedException("GZipStream");
-                return _baseStream._stream.CanRead;
-            }
-        }
-
-        /// <summary>
-        /// Indicates whether the stream supports Seek operations.
-        /// </summary>
-        /// <remarks>
-        /// Always returns false.
-        /// </remarks>
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-
-        /// <summary>
-        /// Indicates whether the stream can be written.
-        /// </summary>
-        /// <remarks>
-        /// The return value depends on whether the captive stream supports writing.
-        /// </remarks>
-        public override bool CanWrite
-        {
-            get
-            {
-                if (_disposed) throw new ObjectDisposedException("GZipStream");
-                return _baseStream._stream.CanWrite;
-            }
-        }
-
-        /// <summary>
-        /// Flush the stream.
-        /// </summary>
-        public override void Flush()
-        {
-            if (_disposed) throw new ObjectDisposedException("GZipStream");
-            _baseStream.Flush();
-        }
-
-        /// <summary>
-        /// Reading this property always throws a <see cref="NotImplementedException"/>.
-        /// </summary>
-        public override long Length
-        {
-            get { throw new NotImplementedException(); }
-        }
-
-        /// <summary>
-        ///   The position of the stream pointer.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Setting this property always throws a <see
-        ///   cref="NotImplementedException"/>. Reading will return the total bytes
-        ///   written out, if used in writing, or the total bytes read in, if used in
-        ///   reading.  The count may refer to compressed bytes or uncompressed bytes,
-        ///   depending on how you've used the stream.
-        /// </remarks>
-        public override long Position
-        {
-            get
-            {
-                if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
-                    return this._baseStream._z.TotalBytesOut + _headerByteCount;
-                if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
-                    return this._baseStream._z.TotalBytesIn + this._baseStream._gzipHeaderByteCount;
-                return 0;
-            }
-
-            set { throw new NotImplementedException(); }
-        }
-
-        /// <summary>
-        ///   Read and decompress data from the source stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   With a <c>GZipStream</c>, decompression is done through reading.
-        /// </remarks>
-        ///
-        /// <example>
-        /// <code>
-        /// byte[] working = new byte[WORKING_BUFFER_SIZE];
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(_CompressedFile))
-        /// {
-        ///     using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true))
-        ///     {
-        ///         using (var output = System.IO.File.Create(_DecompressedFile))
-        ///         {
-        ///             int n;
-        ///             while ((n= decompressor.Read(working, 0, working.Length)) !=0)
-        ///             {
-        ///                 output.Write(working, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        /// </example>
-        /// <param name="buffer">The buffer into which the decompressed data should be placed.</param>
-        /// <param name="offset">the offset within that data array to put the first byte read.</param>
-        /// <param name="count">the number of bytes to read.</param>
-        /// <returns>the number of bytes actually read</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            if (_disposed) throw new ObjectDisposedException("GZipStream");
-            int n = _baseStream.Read(buffer, offset, count);
-
-            // Console.WriteLine("GZipStream::Read(buffer, off({0}), c({1}) = {2}", offset, count, n);
-            // Console.WriteLine( Util.FormatByteArray(buffer, offset, n) );
-
-            if (!_firstReadDone)
-            {
-                _firstReadDone = true;
-                FileName = _baseStream._GzipFileName;
-                Comment = _baseStream._GzipComment;
-            }
-            return n;
-        }
-
-
-
-        /// <summary>
-        ///   Calling this method always throws a <see cref="NotImplementedException"/>.
-        /// </summary>
-        /// <param name="offset">irrelevant; it will always throw!</param>
-        /// <param name="origin">irrelevant; it will always throw!</param>
-        /// <returns>irrelevant!</returns>
-        public override long Seek(long offset, SeekOrigin origin)
-        {
-            throw new NotImplementedException();
-        }
-
-        /// <summary>
-        ///   Calling this method always throws a <see cref="NotImplementedException"/>.
-        /// </summary>
-        /// <param name="value">irrelevant; this method will always throw!</param>
-        public override void SetLength(long value)
-        {
-            throw new NotImplementedException();
-        }
-
-        /// <summary>
-        ///   Write data to the stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   If you wish to use the <c>GZipStream</c> to compress data while writing,
-        ///   you can create a <c>GZipStream</c> with <c>CompressionMode.Compress</c>, and a
-        ///   writable output stream.  Then call <c>Write()</c> on that <c>GZipStream</c>,
-        ///   providing uncompressed data as input.  The data sent to the output stream
-        ///   will be the compressed form of the data written.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>GZipStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not
-        ///   both. Writing implies compression.  Reading implies decompression.
-        /// </para>
-        ///
-        /// </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) throw new ObjectDisposedException("GZipStream");
-            if (_baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Undefined)
-            {
-                //Console.WriteLine("GZipStream: First write");
-                if (_baseStream._wantCompress)
-                {
-                    // first write in compression, therefore, emit the GZIP header
-                    _headerByteCount = EmitHeader();
-                }
-                else
-                {
-                    throw new InvalidOperationException();
-                }
-            }
-
-            _baseStream.Write(buffer, offset, count);
-        }
-        #endregion
-
-
-        internal static readonly System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-#if SILVERLIGHT || NETCF
-        internal static readonly System.Text.Encoding iso8859dash1 = new Ionic.Encoding.Iso8859Dash1Encoding();
-#else
-        internal static readonly System.Text.Encoding iso8859dash1 = System.Text.Encoding.GetEncoding("iso-8859-1");
-#endif
-
-
-        private int EmitHeader()
-        {
-            byte[] commentBytes = (Comment == null) ? null : iso8859dash1.GetBytes(Comment);
-            byte[] filenameBytes = (FileName == null) ? null : iso8859dash1.GetBytes(FileName);
-
-            int cbLength = (Comment == null) ? 0 : commentBytes.Length + 1;
-            int fnLength = (FileName == null) ? 0 : filenameBytes.Length + 1;
-
-            int bufferLength = 10 + cbLength + fnLength;
-            byte[] header = new byte[bufferLength];
-            int i = 0;
-            // ID
-            header[i++] = 0x1F;
-            header[i++] = 0x8B;
-
-            // compression method
-            header[i++] = 8;
-            byte flag = 0;
-            if (Comment != null)
-                flag ^= 0x10;
-            if (FileName != null)
-                flag ^= 0x8;
-
-            // flag
-            header[i++] = flag;
-
-            // mtime
-            if (!LastModified.HasValue) LastModified = DateTime.Now;
-            System.TimeSpan delta = LastModified.Value - _unixEpoch;
-            Int32 timet = (Int32)delta.TotalSeconds;
-            Array.Copy(BitConverter.GetBytes(timet), 0, header, i, 4);
-            i += 4;
-
-            // xflg
-            header[i++] = 0;    // this field is totally useless
-            // OS
-            header[i++] = 0xFF; // 0xFF == unspecified
-
-            // extra field length - only if FEXTRA is set, which it is not.
-            //header[i++]= 0;
-            //header[i++]= 0;
-
-            // filename
-            if (fnLength != 0)
-            {
-                Array.Copy(filenameBytes, 0, header, i, fnLength - 1);
-                i += fnLength - 1;
-                header[i++] = 0; // terminate
-            }
-
-            // comment
-            if (cbLength != 0)
-            {
-                Array.Copy(commentBytes, 0, header, i, cbLength - 1);
-                i += cbLength - 1;
-                header[i++] = 0; // terminate
-            }
-
-            _baseStream._stream.Write(header, 0, header.Length);
-
-            return header.Length; // bytes written
-        }
-
-
-
-        /// <summary>
-        ///   Compress a string into a byte array using GZip.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Uncompress it with <see cref="GZipStream.UncompressString(byte[])"/>.
-        /// </remarks>
-        ///
-        /// <seealso cref="GZipStream.UncompressString(byte[])"/>
-        /// <seealso cref="GZipStream.CompressBuffer(byte[])"/>
-        ///
-        /// <param name="s">
-        ///   A string to compress. The string will first be encoded
-        ///   using UTF8, then compressed.
-        /// </param>
-        ///
-        /// <returns>The string in compressed form</returns>
-        public static byte[] CompressString(String s)
-        {
-            using (var ms = new MemoryStream())
-            {
-                System.IO.Stream compressor =
-                    new GZipStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression);
-                ZlibBaseStream.CompressString(s, compressor);
-                return ms.ToArray();
-            }
-        }
-
-
-        /// <summary>
-        ///   Compress a byte array into a new byte array using GZip.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Uncompress it with <see cref="GZipStream.UncompressBuffer(byte[])"/>.
-        /// </remarks>
-        ///
-        /// <seealso cref="GZipStream.CompressString(string)"/>
-        /// <seealso cref="GZipStream.UncompressBuffer(byte[])"/>
-        ///
-        /// <param name="b">
-        ///   A buffer to compress.
-        /// </param>
-        ///
-        /// <returns>The data in compressed form</returns>
-        public static byte[] CompressBuffer(byte[] b)
-        {
-            using (var ms = new MemoryStream())
-            {
-                System.IO.Stream compressor =
-                    new GZipStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression );
-
-                ZlibBaseStream.CompressBuffer(b, compressor);
-                return ms.ToArray();
-            }
-        }
-
-
-        /// <summary>
-        ///   Uncompress a GZip'ed byte array into a single string.
-        /// </summary>
-        ///
-        /// <seealso cref="GZipStream.CompressString(String)"/>
-        /// <seealso cref="GZipStream.UncompressBuffer(byte[])"/>
-        ///
-        /// <param name="compressed">
-        ///   A buffer containing GZIP-compressed data.
-        /// </param>
-        ///
-        /// <returns>The uncompressed string</returns>
-        public static String UncompressString(byte[] compressed)
-        {
-            using (var input = new MemoryStream(compressed))
-            {
-                Stream decompressor = new GZipStream(input, CompressionMode.Decompress);
-                return ZlibBaseStream.UncompressString(compressed, decompressor);
-            }
-        }
-
-
-        /// <summary>
-        ///   Uncompress a GZip'ed byte array into a byte array.
-        /// </summary>
-        ///
-        /// <seealso cref="GZipStream.CompressBuffer(byte[])"/>
-        /// <seealso cref="GZipStream.UncompressString(byte[])"/>
-        ///
-        /// <param name="compressed">
-        ///   A buffer containing data that has been compressed with GZip.
-        /// </param>
-        ///
-        /// <returns>The data in uncompressed form</returns>
-        public static byte[] UncompressBuffer(byte[] compressed)
-        {
-            using (var input = new System.IO.MemoryStream(compressed))
-            {
-                System.IO.Stream decompressor =
-                    new GZipStream( input, CompressionMode.Decompress );
-
-                return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
-            }
-        }
-
-
-    }
-}
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/InfTree.cs b/EPPlus/Packaging/DotNetZip/Zlib/InfTree.cs
deleted file mode 100644
index 431299c..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/InfTree.cs
+++ /dev/null
@@ -1,436 +0,0 @@
-// Inftree.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.  
-// 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: <2009-October-28 12:43:54>
-//
-// ------------------------------------------------------------------
-//
-// This module defines classes used in  decompression. This code is derived
-// from the jzlib implementation of zlib. In keeping with the license for jzlib, 
-// the copyright to that code is below.
-//
-// ------------------------------------------------------------------
-// 
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 
-// 2. Redistributions in binary form must reproduce the above copyright 
-// notice, this list of conditions and the following disclaimer in 
-// the documentation and/or other materials provided with the distribution.
-// 
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// -----------------------------------------------------------------------
-//
-// This program is based on zlib-1.1.3; credit to authors
-// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-// and contributors of zlib.
-//
-// -----------------------------------------------------------------------
-
-
-
-using System;
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-        
-        sealed class InfTree
-        {
-                
-                private const int MANY = 1440;
-                
-                private const int Z_OK = 0;
-                private const int Z_STREAM_END = 1;
-                private const int Z_NEED_DICT = 2;
-                private const int Z_ERRNO = - 1;
-                private const int Z_STREAM_ERROR = - 2;
-                private const int Z_DATA_ERROR = - 3;
-                private const int Z_MEM_ERROR = - 4;
-                private const int Z_BUF_ERROR = - 5;
-                private const int Z_VERSION_ERROR = - 6;
-                
-                internal const int fixed_bl = 9;
-                internal const int fixed_bd = 5;
-                
-                //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
-                internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 
-                        0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 
-                        14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255};
-                //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
-                internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577};
-                
-                // Tables for deflate from PKZIP's appnote.txt.
-                //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
-                internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-                
-                // see note #13 above about 258
-                //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
-                internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112};
-                
-                //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
-                internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
-                
-                //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
-                internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
-                
-                // If BMAX needs to be larger than 16, then h and x[] should be uLong.
-                internal const int BMAX = 15; // maximum bit length of any code
-                
-                internal int[] hn = null; // hufts used in space
-                internal int[] v = null; // work area for huft_build 
-                internal int[] c = null; // bit length count table
-                internal int[] r = null; // table entry for structure assignment
-                internal int[] u = null; // table stack
-                internal int[] x = null; // bit offsets, then code stack
-                
-                private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v)
-                {
-                        // Given a list of code lengths and a maximum table size, make a set of
-                        // tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
-                        // if the given code set is incomplete (the tables are still built in this
-                        // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
-                        // lengths), or Z_MEM_ERROR if not enough memory.
-                        
-                        int a; // counter for codes of length k
-                        int f; // i repeats in table every f entries
-                        int g; // maximum code length
-                        int h; // table level
-                        int i; // counter, current code
-                        int j; // counter
-                        int k; // number of bits in current code
-                        int l; // bits per table (returned in m)
-                        int mask; // (1 << w) - 1, to avoid cc -O bug on HP
-                        int p; // pointer into c[], b[], or v[]
-                        int q; // points to current table
-                        int w; // bits before this table == (l * h)
-                        int xp; // pointer into x
-                        int y; // number of dummy codes added
-                        int z; // number of entries in current table
-                        
-                        // Generate counts for each bit length
-                        
-                        p = 0; i = n;
-                        do 
-                        {
-                                c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX
-                        }
-                        while (i != 0);
-                        
-                        if (c[0] == n)
-                        {
-                                // null input--all zero length codes
-                                t[0] = - 1;
-                                m[0] = 0;
-                                return Z_OK;
-                        }
-                        
-                        // Find minimum and maximum length, bound *m by those
-                        l = m[0];
-                        for (j = 1; j <= BMAX; j++)
-                                if (c[j] != 0)
-                                        break;
-                        k = j; // minimum code length
-                        if (l < j)
-                        {
-                                l = j;
-                        }
-                        for (i = BMAX; i != 0; i--)
-                        {
-                                if (c[i] != 0)
-                                        break;
-                        }
-                        g = i; // maximum code length
-                        if (l > i)
-                        {
-                                l = i;
-                        }
-                        m[0] = l;
-                        
-                        // Adjust last length count to fill out codes, if needed
-                        for (y = 1 << j; j < i; j++, y <<= 1)
-                        {
-                                if ((y -= c[j]) < 0)
-                                {
-                                        return Z_DATA_ERROR;
-                                }
-                        }
-                        if ((y -= c[i]) < 0)
-                        {
-                                return Z_DATA_ERROR;
-                        }
-                        c[i] += y;
-                        
-                        // Generate starting offsets into the value table for each length
-                        x[1] = j = 0;
-                        p = 1; xp = 2;
-                        while (--i != 0)
-                        {
-                                // note that i == g from above
-                                x[xp] = (j += c[p]);
-                                xp++;
-                                p++;
-                        }
-                        
-                        // Make a table of values in order of bit lengths
-                        i = 0; p = 0;
-                        do 
-                        {
-                                if ((j = b[bindex + p]) != 0)
-                                {
-                                        v[x[j]++] = i;
-                                }
-                                p++;
-                        }
-                        while (++i < n);
-                        n = x[g]; // set n to length of v
-                        
-                        // Generate the Huffman codes and for each, make the table entries
-                        x[0] = i = 0; // first Huffman code is zero
-                        p = 0; // grab values in bit order
-                        h = - 1; // no tables yet--level -1
-                        w = - l; // bits decoded == (l * h)
-                        u[0] = 0; // just to keep compilers happy
-                        q = 0; // ditto
-                        z = 0; // ditto
-                        
-                        // go through the bit lengths (k already is bits in shortest code)
-                        for (; k <= g; k++)
-                        {
-                                a = c[k];
-                                while (a-- != 0)
-                                {
-                                        // here i is the Huffman code of length k bits for value *p
-                                        // make tables up to required level
-                                        while (k > w + l)
-                                        {
-                                                h++;
-                                                w += l; // previous table always l bits
-                                                // compute minimum size table less than or equal to l bits
-                                                z = g - w;
-                                                z = (z > l)?l:z; // table size upper limit
-                                                if ((f = 1 << (j = k - w)) > a + 1)
-                                                {
-                                                        // try a k-w bit table
-                                                        // too few codes for k-w bit table
-                                                        f -= (a + 1); // deduct codes from patterns left
-                                                        xp = k;
-                                                        if (j < z)
-                                                        {
-                                                                while (++j < z)
-                                                                {
-                                                                        // try smaller tables up to z bits
-                                                                        if ((f <<= 1) <= c[++xp])
-                                                                                break; // enough codes to use up j bits
-                                                                        f -= c[xp]; // else deduct codes from patterns
-                                                                }
-                                                        }
-                                                }
-                                                z = 1 << j; // table entries for j-bit table
-                                                
-                                                // allocate new table
-                                                if (hn[0] + z > MANY)
-                                                {
-                                                        // (note: doesn't matter for fixed)
-                                                        return Z_DATA_ERROR; // overflow of MANY
-                                                }
-                                                u[h] = q = hn[0]; // DEBUG
-                                                hn[0] += z;
-                                                
-                                                // connect to last table, if there is one
-                                                if (h != 0)
-                                                {
-                                                        x[h] = i; // save pattern for backing up
-                                                        r[0] = (sbyte) j; // bits in this table
-                                                        r[1] = (sbyte) l; // bits to dump before this table
-                                                        j = SharedUtils.URShift(i, (w - l));
-                                                        r[2] = (int) (q - u[h - 1] - j); // offset to this table
-                                                        Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table
-                                                }
-                                                else
-                                                {
-                                                        t[0] = q; // first table is returned result
-                                                }
-                                        }
-                                        
-                                        // set up table entry in r
-                                        r[1] = (sbyte) (k - w);
-                                        if (p >= n)
-                                        {
-                                                r[0] = 128 + 64; // out of values--invalid code
-                                        }
-                                        else if (v[p] < s)
-                                        {
-                                                r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block
-                                                r[2] = v[p++]; // simple code is just the value
-                                        }
-                                        else
-                                        {
-                                                r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists
-                                                r[2] = d[v[p++] - s];
-                                        }
-                                        
-                                        // fill code-like entries with r
-                                        f = 1 << (k - w);
-                                        for (j = SharedUtils.URShift(i, w); j < z; j += f)
-                                        {
-                                                Array.Copy(r, 0, hp, (q + j) * 3, 3);
-                                        }
-                                        
-                                        // backwards increment the k-bit code i
-                                        for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1))
-                                        {
-                                                i ^= j;
-                                        }
-                                        i ^= j;
-                                        
-                                        // backup over finished tables
-                                        mask = (1 << w) - 1; // needed on HP, cc -O bug
-                                        while ((i & mask) != x[h])
-                                        {
-                                                h--; // don't need to update q
-                                                w -= l;
-                                                mask = (1 << w) - 1;
-                                        }
-                                }
-                        }
-                        // Return Z_BUF_ERROR if we were given an incomplete table
-                        return y != 0 && g != 1?Z_BUF_ERROR:Z_OK;
-                }
-                
-                internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z)
-                {
-                        int result;
-                        initWorkArea(19);
-                        hn[0] = 0;
-                        result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
-                        
-                        if (result == Z_DATA_ERROR)
-                        {
-                                z.Message = "oversubscribed dynamic bit lengths tree";
-                        }
-                        else if (result == Z_BUF_ERROR || bb[0] == 0)
-                        {
-                                z.Message = "incomplete dynamic bit lengths tree";
-                                result = Z_DATA_ERROR;
-                        }
-                        return result;
-                }
-                
-                internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
-                {
-                        int result;
-                        
-                        // build literal/length tree
-                        initWorkArea(288);
-                        hn[0] = 0;
-                        result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
-                        if (result != Z_OK || bl[0] == 0)
-                        {
-                                if (result == Z_DATA_ERROR)
-                                {
-                                        z.Message = "oversubscribed literal/length tree";
-                                }
-                                else if (result != Z_MEM_ERROR)
-                                {
-                                        z.Message = "incomplete literal/length tree";
-                                        result = Z_DATA_ERROR;
-                                }
-                                return result;
-                        }
-                        
-                        // build distance tree
-                        initWorkArea(288);
-                        result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
-                        
-                        if (result != Z_OK || (bd[0] == 0 && nl > 257))
-                        {
-                                if (result == Z_DATA_ERROR)
-                                {
-                                        z.Message = "oversubscribed distance tree";
-                                }
-                                else if (result == Z_BUF_ERROR)
-                                {
-                                        z.Message = "incomplete distance tree";
-                                        result = Z_DATA_ERROR;
-                                }
-                                else if (result != Z_MEM_ERROR)
-                                {
-                                        z.Message = "empty distance tree with lengths";
-                                        result = Z_DATA_ERROR;
-                                }
-                                return result;
-                        }
-                        
-                        return Z_OK;
-                }
-                
-                internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
-                {
-                        bl[0] = fixed_bl;
-                        bd[0] = fixed_bd;
-                        tl[0] = fixed_tl;
-                        td[0] = fixed_td;
-                        return Z_OK;
-                }
-                
-                private void  initWorkArea(int vsize)
-                {
-                        if (hn == null)
-                        {
-                                hn = new int[1];
-                                v = new int[vsize];
-                                c = new int[BMAX + 1];
-                                r = new int[3];
-                                u = new int[BMAX];
-                                x = new int[BMAX + 1];
-                        }
-                        else
-                        {
-                            if (v.Length < vsize)
-                            {
-                                v = new int[vsize];
-                            }
-                            Array.Clear(v,0,vsize);
-                            Array.Clear(c,0,BMAX+1);
-                            r[0]=0; r[1]=0; r[2]=0;
-                            //  for(int i=0; i<BMAX; i++){u[i]=0;}
-                            //Array.Copy(c, 0, u, 0, BMAX);
-                            Array.Clear(u,0,BMAX);
-                            //  for(int i=0; i<BMAX+1; i++){x[i]=0;}
-                            //Array.Copy(c, 0, x, 0, BMAX + 1);
-                            Array.Clear(x,0,BMAX+1);
-                        }
-                }
-        }
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/Inflate.cs b/EPPlus/Packaging/DotNetZip/Zlib/Inflate.cs
deleted file mode 100644
index 47c8d6e..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/Inflate.cs
+++ /dev/null
@@ -1,1796 +0,0 @@
-// Inflate.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
-// 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: <2010-January-08 18:32:12>
-//
-// ------------------------------------------------------------------
-//
-// This module defines classes for decompression. This code is derived
-// from the jzlib implementation of zlib, but significantly modified.
-// The object model is not the same, and many of the behaviors are
-// different.  Nonetheless, in keeping with the license for jzlib, I am
-// reproducing the copyright to that code here.
-//
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the distribution.
-//
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// -----------------------------------------------------------------------
-//
-// This program is based on zlib-1.1.3; credit to authors
-// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-// and contributors of zlib.
-//
-// -----------------------------------------------------------------------
-
-
-using System;
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    sealed class InflateBlocks
-    {
-        private const int MANY = 1440;
-
-        // Table for deflate from PKZIP's appnote.txt.
-        internal static readonly int[] border = new int[]
-        { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
-
-        private enum InflateBlockMode
-        {
-            TYPE   = 0,                     // get type bits (3, including end bit)
-            LENS   = 1,                     // get lengths for stored
-            STORED = 2,                     // processing stored block
-            TABLE  = 3,                     // get table lengths
-            BTREE  = 4,                     // get bit lengths tree for a dynamic block
-            DTREE  = 5,                     // get length, distance trees for a dynamic block
-            CODES  = 6,                     // processing fixed or dynamic block
-            DRY    = 7,                     // output remaining window bytes
-            DONE   = 8,                     // finished last block, done
-            BAD    = 9,                     // ot a data error--stuck here
-        }
-
-        private InflateBlockMode mode;                    // current inflate_block mode
-
-        internal int left;                                // if STORED, bytes left to copy
-
-        internal int table;                               // table lengths (14 bits)
-        internal int index;                               // index into blens (or border)
-        internal int[] blens;                             // bit lengths of codes
-        internal int[] bb = new int[1];                   // bit length tree depth
-        internal int[] tb = new int[1];                   // bit length decoding tree
-
-        internal InflateCodes codes = new InflateCodes(); // if CODES, current state
-
-        internal int last;                                // true if this block is the last block
-
-        internal ZlibCodec _codec;                        // pointer back to this zlib stream
-
-                                                          // mode independent information
-        internal int bitk;                                // bits in bit buffer
-        internal int bitb;                                // bit buffer
-        internal int[] hufts;                             // single malloc for tree space
-        internal byte[] window;                           // sliding window
-        internal int end;                                 // one byte after sliding window
-        internal int readAt;                              // window read pointer
-        internal int writeAt;                             // window write pointer
-        internal System.Object checkfn;                   // check function
-        internal uint check;                              // check on output
-
-        internal InfTree inftree = new InfTree();
-
-        internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w)
-        {
-            _codec = codec;
-            hufts = new int[MANY * 3];
-            window = new byte[w];
-            end = w;
-            this.checkfn = checkfn;
-            mode = InflateBlockMode.TYPE;
-            Reset();
-        }
-
-        internal uint Reset()
-        {
-            uint oldCheck = check;
-            mode = InflateBlockMode.TYPE;
-            bitk = 0;
-            bitb = 0;
-            readAt = writeAt = 0;
-
-            if (checkfn != null)
-                _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0);
-            return oldCheck;
-        }
-
-
-        internal int Process(int r)
-        {
-            int t; // temporary storage
-            int b; // bit buffer
-            int k; // bits in bit buffer
-            int p; // input data pointer
-            int n; // bytes available there
-            int q; // output window write pointer
-            int m; // bytes to end of window or read pointer
-
-            // copy input/output information to locals (UPDATE macro restores)
-
-            p = _codec.NextIn;
-            n = _codec.AvailableBytesIn;
-            b = bitb;
-            k = bitk;
-
-            q = writeAt;
-            m = (int)(q < readAt ? readAt - q - 1 : end - q);
-
-
-            // process input based on current state
-            while (true)
-            {
-                switch (mode)
-                {
-                    case InflateBlockMode.TYPE:
-
-                        while (k < (3))
-                        {
-                            if (n != 0)
-                            {
-                                r = ZlibConstants.Z_OK;
-                            }
-                            else
-                            {
-                                bitb = b; bitk = k;
-                                _codec.AvailableBytesIn = n;
-                                _codec.TotalBytesIn += p - _codec.NextIn;
-                                _codec.NextIn = p;
-                                writeAt = q;
-                                return Flush(r);
-                            }
-
-                            n--;
-                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-                        t = (int)(b & 7);
-                        last = t & 1;
-
-                        switch ((uint)t >> 1)
-                        {
-                            case 0:  // stored
-                                b >>= 3; k -= (3);
-                                t = k & 7; // go to byte boundary
-                                b >>= t; k -= t;
-                                mode = InflateBlockMode.LENS; // get length of stored block
-                                break;
-
-                            case 1:  // fixed
-                                int[] bl = new int[1];
-                                int[] bd = new int[1];
-                                int[][] tl = new int[1][];
-                                int[][] td = new int[1][];
-                                InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec);
-                                codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
-                                b >>= 3; k -= 3;
-                                mode = InflateBlockMode.CODES;
-                                break;
-
-                            case 2:  // dynamic
-                                b >>= 3; k -= 3;
-                                mode = InflateBlockMode.TABLE;
-                                break;
-
-                            case 3:  // illegal
-                                b >>= 3; k -= 3;
-                                mode = InflateBlockMode.BAD;
-                                _codec.Message = "invalid block type";
-                                r = ZlibConstants.Z_DATA_ERROR;
-                                bitb = b; bitk = k;
-                                _codec.AvailableBytesIn = n;
-                                _codec.TotalBytesIn += p - _codec.NextIn;
-                                _codec.NextIn = p;
-                                writeAt = q;
-                                return Flush(r);
-                        }
-                        break;
-
-                    case InflateBlockMode.LENS:
-
-                        while (k < (32))
-                        {
-                            if (n != 0)
-                            {
-                                r = ZlibConstants.Z_OK;
-                            }
-                            else
-                            {
-                                bitb = b; bitk = k;
-                                _codec.AvailableBytesIn = n;
-                                _codec.TotalBytesIn += p - _codec.NextIn;
-                                _codec.NextIn = p;
-                                writeAt = q;
-                                return Flush(r);
-                            }
-                            ;
-                            n--;
-                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-
-                        if ( ( ((~b)>>16) & 0xffff) != (b & 0xffff))
-                        {
-                            mode = InflateBlockMode.BAD;
-                            _codec.Message = "invalid stored block lengths";
-                            r = ZlibConstants.Z_DATA_ERROR;
-
-                            bitb = b; bitk = k;
-                            _codec.AvailableBytesIn = n;
-                            _codec.TotalBytesIn += p - _codec.NextIn;
-                            _codec.NextIn = p;
-                            writeAt = q;
-                            return Flush(r);
-                        }
-                        left = (b & 0xffff);
-                        b = k = 0; // dump bits
-                        mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
-                        break;
-
-                    case InflateBlockMode.STORED:
-                        if (n == 0)
-                        {
-                            bitb = b; bitk = k;
-                            _codec.AvailableBytesIn = n;
-                            _codec.TotalBytesIn += p - _codec.NextIn;
-                            _codec.NextIn = p;
-                            writeAt = q;
-                            return Flush(r);
-                        }
-
-                        if (m == 0)
-                        {
-                            if (q == end && readAt != 0)
-                            {
-                                q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q);
-                            }
-                            if (m == 0)
-                            {
-                                writeAt = q;
-                                r = Flush(r);
-                                q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q);
-                                if (q == end && readAt != 0)
-                                {
-                                    q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q);
-                                }
-                                if (m == 0)
-                                {
-                                    bitb = b; bitk = k;
-                                    _codec.AvailableBytesIn = n;
-                                    _codec.TotalBytesIn += p - _codec.NextIn;
-                                    _codec.NextIn = p;
-                                    writeAt = q;
-                                    return Flush(r);
-                                }
-                            }
-                        }
-                        r = ZlibConstants.Z_OK;
-
-                        t = left;
-                        if (t > n)
-                            t = n;
-                        if (t > m)
-                            t = m;
-                        Array.Copy(_codec.InputBuffer, p, window, q, t);
-                        p += t; n -= t;
-                        q += t; m -= t;
-                        if ((left -= t) != 0)
-                            break;
-                        mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
-                        break;
-
-                    case InflateBlockMode.TABLE:
-
-                        while (k < (14))
-                        {
-                            if (n != 0)
-                            {
-                                r = ZlibConstants.Z_OK;
-                            }
-                            else
-                            {
-                                bitb = b; bitk = k;
-                                _codec.AvailableBytesIn = n;
-                                _codec.TotalBytesIn += p - _codec.NextIn;
-                                _codec.NextIn = p;
-                                writeAt = q;
-                                return Flush(r);
-                            }
-
-                            n--;
-                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-
-                        table = t = (b & 0x3fff);
-                        if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-                        {
-                            mode = InflateBlockMode.BAD;
-                            _codec.Message = "too many length or distance symbols";
-                            r = ZlibConstants.Z_DATA_ERROR;
-
-                            bitb = b; bitk = k;
-                            _codec.AvailableBytesIn = n;
-                            _codec.TotalBytesIn += p - _codec.NextIn;
-                            _codec.NextIn = p;
-                            writeAt = q;
-                            return Flush(r);
-                        }
-                        t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-                        if (blens == null || blens.Length < t)
-                        {
-                            blens = new int[t];
-                        }
-                        else
-                        {
-                            Array.Clear(blens, 0, t);
-                            // for (int i = 0; i < t; i++)
-                            // {
-                            //     blens[i] = 0;
-                            // }
-                        }
-
-                        b >>= 14;
-                        k -= 14;
-
-
-                        index = 0;
-                        mode = InflateBlockMode.BTREE;
-                        goto case InflateBlockMode.BTREE;
-
-                    case InflateBlockMode.BTREE:
-                        while (index < 4 + (table >> 10))
-                        {
-                            while (k < (3))
-                            {
-                                if (n != 0)
-                                {
-                                    r = ZlibConstants.Z_OK;
-                                }
-                                else
-                                {
-                                    bitb = b; bitk = k;
-                                    _codec.AvailableBytesIn = n;
-                                    _codec.TotalBytesIn += p - _codec.NextIn;
-                                    _codec.NextIn = p;
-                                    writeAt = q;
-                                    return Flush(r);
-                                }
-
-                                n--;
-                                b |= (_codec.InputBuffer[p++] & 0xff) << k;
-                                k += 8;
-                            }
-
-                            blens[border[index++]] = b & 7;
-
-                            b >>= 3; k -= 3;
-                        }
-
-                        while (index < 19)
-                        {
-                            blens[border[index++]] = 0;
-                        }
-
-                        bb[0] = 7;
-                        t = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
-                        if (t != ZlibConstants.Z_OK)
-                        {
-                            r = t;
-                            if (r == ZlibConstants.Z_DATA_ERROR)
-                            {
-                                blens = null;
-                                mode = InflateBlockMode.BAD;
-                            }
-
-                            bitb = b; bitk = k;
-                            _codec.AvailableBytesIn = n;
-                            _codec.TotalBytesIn += p - _codec.NextIn;
-                            _codec.NextIn = p;
-                            writeAt = q;
-                            return Flush(r);
-                        }
-
-                        index = 0;
-                        mode = InflateBlockMode.DTREE;
-                        goto case InflateBlockMode.DTREE;
-
-                    case InflateBlockMode.DTREE:
-                        while (true)
-                        {
-                            t = table;
-                            if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
-                            {
-                                break;
-                            }
-
-                            int i, j, c;
-
-                            t = bb[0];
-
-                            while (k < t)
-                            {
-                                if (n != 0)
-                                {
-                                    r = ZlibConstants.Z_OK;
-                                }
-                                else
-                                {
-                                    bitb = b; bitk = k;
-                                    _codec.AvailableBytesIn = n;
-                                    _codec.TotalBytesIn += p - _codec.NextIn;
-                                    _codec.NextIn = p;
-                                    writeAt = q;
-                                    return Flush(r);
-                                }
-
-                                n--;
-                                b |= (_codec.InputBuffer[p++] & 0xff) << k;
-                                k += 8;
-                            }
-
-                            t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1];
-                            c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2];
-
-                            if (c < 16)
-                            {
-                                b >>= t; k -= t;
-                                blens[index++] = c;
-                            }
-                            else
-                            {
-                                // c == 16..18
-                                i = c == 18 ? 7 : c - 14;
-                                j = c == 18 ? 11 : 3;
-
-                                while (k < (t + i))
-                                {
-                                    if (n != 0)
-                                    {
-                                        r = ZlibConstants.Z_OK;
-                                    }
-                                    else
-                                    {
-                                        bitb = b; bitk = k;
-                                        _codec.AvailableBytesIn = n;
-                                        _codec.TotalBytesIn += p - _codec.NextIn;
-                                        _codec.NextIn = p;
-                                        writeAt = q;
-                                        return Flush(r);
-                                    }
-
-                                    n--;
-                                    b |= (_codec.InputBuffer[p++] & 0xff) << k;
-                                    k += 8;
-                                }
-
-                                b >>= t; k -= t;
-
-                                j += (b & InternalInflateConstants.InflateMask[i]);
-
-                                b >>= i; k -= i;
-
-                                i = index;
-                                t = table;
-                                if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
-                                {
-                                    blens = null;
-                                    mode = InflateBlockMode.BAD;
-                                    _codec.Message = "invalid bit length repeat";
-                                    r = ZlibConstants.Z_DATA_ERROR;
-
-                                    bitb = b; bitk = k;
-                                    _codec.AvailableBytesIn = n;
-                                    _codec.TotalBytesIn += p - _codec.NextIn;
-                                    _codec.NextIn = p;
-                                    writeAt = q;
-                                    return Flush(r);
-                                }
-
-                                c = (c == 16) ? blens[i-1] : 0;
-                                do
-                                {
-                                    blens[i++] = c;
-                                }
-                                while (--j != 0);
-                                index = i;
-                            }
-                        }
-
-                        tb[0] = -1;
-                        {
-                            int[] bl = new int[] { 9 };  // must be <= 9 for lookahead assumptions
-                            int[] bd = new int[] { 6 }; // must be <= 9 for lookahead assumptions
-                            int[] tl = new int[1];
-                            int[] td = new int[1];
-
-                            t = table;
-                            t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, _codec);
-
-                            if (t != ZlibConstants.Z_OK)
-                            {
-                                if (t == ZlibConstants.Z_DATA_ERROR)
-                                {
-                                    blens = null;
-                                    mode = InflateBlockMode.BAD;
-                                }
-                                r = t;
-
-                                bitb = b; bitk = k;
-                                _codec.AvailableBytesIn = n;
-                                _codec.TotalBytesIn += p - _codec.NextIn;
-                                _codec.NextIn = p;
-                                writeAt = q;
-                                return Flush(r);
-                            }
-                            codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]);
-                        }
-                        mode = InflateBlockMode.CODES;
-                        goto case InflateBlockMode.CODES;
-
-                    case InflateBlockMode.CODES:
-                        bitb = b; bitk = k;
-                        _codec.AvailableBytesIn = n;
-                        _codec.TotalBytesIn += p - _codec.NextIn;
-                        _codec.NextIn = p;
-                        writeAt = q;
-
-                        r = codes.Process(this, r);
-                        if (r != ZlibConstants.Z_STREAM_END)
-                        {
-                            return Flush(r);
-                        }
-
-                        r = ZlibConstants.Z_OK;
-                        p = _codec.NextIn;
-                        n = _codec.AvailableBytesIn;
-                        b = bitb;
-                        k = bitk;
-                        q = writeAt;
-                        m = (int)(q < readAt ? readAt - q - 1 : end - q);
-
-                        if (last == 0)
-                        {
-                            mode = InflateBlockMode.TYPE;
-                            break;
-                        }
-                        mode = InflateBlockMode.DRY;
-                        goto case InflateBlockMode.DRY;
-
-                    case InflateBlockMode.DRY:
-                        writeAt = q;
-                        r = Flush(r);
-                        q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q);
-                        if (readAt != writeAt)
-                        {
-                            bitb = b; bitk = k;
-                            _codec.AvailableBytesIn = n;
-                            _codec.TotalBytesIn += p - _codec.NextIn;
-                            _codec.NextIn = p;
-                            writeAt = q;
-                            return Flush(r);
-                        }
-                        mode = InflateBlockMode.DONE;
-                        goto case InflateBlockMode.DONE;
-
-                    case InflateBlockMode.DONE:
-                        r = ZlibConstants.Z_STREAM_END;
-                        bitb = b;
-                        bitk = k;
-                        _codec.AvailableBytesIn = n;
-                        _codec.TotalBytesIn += p - _codec.NextIn;
-                        _codec.NextIn = p;
-                        writeAt = q;
-                        return Flush(r);
-
-                    case InflateBlockMode.BAD:
-                        r = ZlibConstants.Z_DATA_ERROR;
-
-                        bitb = b; bitk = k;
-                        _codec.AvailableBytesIn = n;
-                        _codec.TotalBytesIn += p - _codec.NextIn;
-                        _codec.NextIn = p;
-                        writeAt = q;
-                        return Flush(r);
-
-
-                    default:
-                        r = ZlibConstants.Z_STREAM_ERROR;
-
-                        bitb = b; bitk = k;
-                        _codec.AvailableBytesIn = n;
-                        _codec.TotalBytesIn += p - _codec.NextIn;
-                        _codec.NextIn = p;
-                        writeAt = q;
-                        return Flush(r);
-                }
-            }
-        }
-
-
-        internal void Free()
-        {
-            Reset();
-            window = null;
-            hufts = null;
-        }
-
-        internal void SetDictionary(byte[] d, int start, int n)
-        {
-            Array.Copy(d, start, window, 0, n);
-            readAt = writeAt = n;
-        }
-
-        // Returns true if inflate is currently at the end of a block generated
-        // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
-        internal int SyncPoint()
-        {
-            return mode == InflateBlockMode.LENS ? 1 : 0;
-        }
-
-        // copy as much as possible from the sliding window to the output area
-        internal int Flush(int r)
-        {
-            int nBytes;
-
-            for (int pass=0; pass < 2; pass++)
-            {
-                if (pass==0)
-                {
-                    // compute number of bytes to copy as far as end of window
-                    nBytes = (int)((readAt <= writeAt ? writeAt : end) - readAt);
-                }
-                else
-                {
-                    // compute bytes to copy
-                    nBytes = writeAt - readAt;
-                }
-
-                // workitem 8870
-                if (nBytes == 0)
-                {
-                    if (r == ZlibConstants.Z_BUF_ERROR)
-                        r = ZlibConstants.Z_OK;
-                    return r;
-                }
-
-                if (nBytes > _codec.AvailableBytesOut)
-                    nBytes = _codec.AvailableBytesOut;
-
-                if (nBytes != 0 && r == ZlibConstants.Z_BUF_ERROR)
-                    r = ZlibConstants.Z_OK;
-
-                // update counters
-                _codec.AvailableBytesOut -= nBytes;
-                _codec.TotalBytesOut += nBytes;
-
-                // update check information
-                if (checkfn != null)
-                    _codec._Adler32 = check = Adler.Adler32(check, window, readAt, nBytes);
-
-                // copy as far as end of window
-                Array.Copy(window, readAt, _codec.OutputBuffer, _codec.NextOut, nBytes);
-                _codec.NextOut += nBytes;
-                readAt += nBytes;
-
-                // see if more to copy at beginning of window
-                if (readAt == end && pass == 0)
-                {
-                    // wrap pointers
-                    readAt = 0;
-                    if (writeAt == end)
-                        writeAt = 0;
-                }
-                else pass++;
-            }
-
-            // done
-            return r;
-        }
-    }
-
-
-    internal static class InternalInflateConstants
-    {
-        // And'ing with mask[n] masks the lower n bits
-        internal static readonly int[] InflateMask = new int[] {
-            0x00000000, 0x00000001, 0x00000003, 0x00000007,
-            0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
-            0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
-            0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff };
-    }
-
-
-    sealed class InflateCodes
-    {
-        // waiting for "i:"=input,
-        //             "o:"=output,
-        //             "x:"=nothing
-        private const int START   = 0; // x: set up for LEN
-        private const int LEN     = 1; // i: get length/literal/eob next
-        private const int LENEXT  = 2; // i: getting length extra (have base)
-        private const int DIST    = 3; // i: get distance next
-        private const int DISTEXT = 4; // i: getting distance extra
-        private const int COPY    = 5; // o: copying bytes in window, waiting for space
-        private const int LIT     = 6; // o: got literal, waiting for output space
-        private const int WASH    = 7; // o: got eob, possibly still output waiting
-        private const int END     = 8; // x: got eob and all data flushed
-        private const int BADCODE = 9; // x: got error
-
-        internal int mode;        // current inflate_codes mode
-
-        // mode dependent information
-        internal int len;
-
-        internal int[] tree;      // pointer into tree
-        internal int tree_index = 0;
-        internal int need;        // bits needed
-
-        internal int lit;
-
-        // if EXT or COPY, where and how much
-        internal int bitsToGet;   // bits to get for extra
-        internal int dist;        // distance back to copy from
-
-        internal byte lbits;      // ltree bits decoded per branch
-        internal byte dbits;      // dtree bits decoder per branch
-        internal int[] ltree;     // literal/length/eob tree
-        internal int ltree_index; // literal/length/eob tree
-        internal int[] dtree;     // distance tree
-        internal int dtree_index; // distance tree
-
-        internal InflateCodes()
-        {
-        }
-
-        internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index)
-        {
-            mode = START;
-            lbits = (byte)bl;
-            dbits = (byte)bd;
-            ltree = tl;
-            ltree_index = tl_index;
-            dtree = td;
-            dtree_index = td_index;
-            tree = null;
-        }
-
-        internal int Process(InflateBlocks blocks, int r)
-        {
-            int j;      // temporary storage
-            int tindex; // temporary pointer
-            int e;      // extra bits or operation
-            int b = 0;  // bit buffer
-            int k = 0;  // bits in bit buffer
-            int p = 0;  // input data pointer
-            int n;      // bytes available there
-            int q;      // output window write pointer
-            int m;      // bytes to end of window or read pointer
-            int f;      // pointer to copy strings from
-
-            ZlibCodec z = blocks._codec;
-
-            // copy input/output information to locals (UPDATE macro restores)
-            p = z.NextIn;
-            n = z.AvailableBytesIn;
-            b = blocks.bitb;
-            k = blocks.bitk;
-            q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-
-            // process input and output based on current state
-            while (true)
-            {
-                switch (mode)
-                {
-                    // waiting for "i:"=input, "o:"=output, "x:"=nothing
-                    case START:  // x: set up for LEN
-                        if (m >= 258 && n >= 10)
-                        {
-                            blocks.bitb = b; blocks.bitk = k;
-                            z.AvailableBytesIn = n;
-                            z.TotalBytesIn += p - z.NextIn;
-                            z.NextIn = p;
-                            blocks.writeAt = q;
-                            r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z);
-
-                            p = z.NextIn;
-                            n = z.AvailableBytesIn;
-                            b = blocks.bitb;
-                            k = blocks.bitk;
-                            q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-
-                            if (r != ZlibConstants.Z_OK)
-                            {
-                                mode = (r == ZlibConstants.Z_STREAM_END) ? WASH : BADCODE;
-                                break;
-                            }
-                        }
-                        need = lbits;
-                        tree = ltree;
-                        tree_index = ltree_index;
-
-                        mode = LEN;
-                        goto case LEN;
-
-                    case LEN:  // i: get length/literal/eob next
-                        j = need;
-
-                        while (k < j)
-                        {
-                            if (n != 0)
-                                r = ZlibConstants.Z_OK;
-                            else
-                            {
-                                blocks.bitb = b; blocks.bitk = k;
-                                z.AvailableBytesIn = n;
-                                z.TotalBytesIn += p - z.NextIn;
-                                z.NextIn = p;
-                                blocks.writeAt = q;
-                                return blocks.Flush(r);
-                            }
-                            n--;
-                            b |= (z.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-
-                        tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3;
-
-                        b >>= (tree[tindex + 1]);
-                        k -= (tree[tindex + 1]);
-
-                        e = tree[tindex];
-
-                        if (e == 0)
-                        {
-                            // literal
-                            lit = tree[tindex + 2];
-                            mode = LIT;
-                            break;
-                        }
-                        if ((e & 16) != 0)
-                        {
-                            // length
-                            bitsToGet = e & 15;
-                            len = tree[tindex + 2];
-                            mode = LENEXT;
-                            break;
-                        }
-                        if ((e & 64) == 0)
-                        {
-                            // next table
-                            need = e;
-                            tree_index = tindex / 3 + tree[tindex + 2];
-                            break;
-                        }
-                        if ((e & 32) != 0)
-                        {
-                            // end of block
-                            mode = WASH;
-                            break;
-                        }
-                        mode = BADCODE; // invalid code
-                        z.Message = "invalid literal/length code";
-                        r = ZlibConstants.Z_DATA_ERROR;
-
-                        blocks.bitb = b; blocks.bitk = k;
-                        z.AvailableBytesIn = n;
-                        z.TotalBytesIn += p - z.NextIn;
-                        z.NextIn = p;
-                        blocks.writeAt = q;
-                        return blocks.Flush(r);
-
-
-                    case LENEXT:  // i: getting length extra (have base)
-                        j = bitsToGet;
-
-                        while (k < j)
-                        {
-                            if (n != 0)
-                                r = ZlibConstants.Z_OK;
-                            else
-                            {
-                                blocks.bitb = b; blocks.bitk = k;
-                                z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                                blocks.writeAt = q;
-                                return blocks.Flush(r);
-                            }
-                            n--; b |= (z.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-
-                        len += (b & InternalInflateConstants.InflateMask[j]);
-
-                        b >>= j;
-                        k -= j;
-
-                        need = dbits;
-                        tree = dtree;
-                        tree_index = dtree_index;
-                        mode = DIST;
-                        goto case DIST;
-
-                    case DIST:  // i: get distance next
-                        j = need;
-
-                        while (k < j)
-                        {
-                            if (n != 0)
-                                r = ZlibConstants.Z_OK;
-                            else
-                            {
-                                blocks.bitb = b; blocks.bitk = k;
-                                z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                                blocks.writeAt = q;
-                                return blocks.Flush(r);
-                            }
-                            n--; b |= (z.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-
-                        tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3;
-
-                        b >>= tree[tindex + 1];
-                        k -= tree[tindex + 1];
-
-                        e = (tree[tindex]);
-                        if ((e & 0x10) != 0)
-                        {
-                            // distance
-                            bitsToGet = e & 15;
-                            dist = tree[tindex + 2];
-                            mode = DISTEXT;
-                            break;
-                        }
-                        if ((e & 64) == 0)
-                        {
-                            // next table
-                            need = e;
-                            tree_index = tindex / 3 + tree[tindex + 2];
-                            break;
-                        }
-                        mode = BADCODE; // invalid code
-                        z.Message = "invalid distance code";
-                        r = ZlibConstants.Z_DATA_ERROR;
-
-                        blocks.bitb = b; blocks.bitk = k;
-                        z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                        blocks.writeAt = q;
-                        return blocks.Flush(r);
-
-
-                    case DISTEXT:  // i: getting distance extra
-                        j = bitsToGet;
-
-                        while (k < j)
-                        {
-                            if (n != 0)
-                                r = ZlibConstants.Z_OK;
-                            else
-                            {
-                                blocks.bitb = b; blocks.bitk = k;
-                                z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                                blocks.writeAt = q;
-                                return blocks.Flush(r);
-                            }
-                            n--; b |= (z.InputBuffer[p++] & 0xff) << k;
-                            k += 8;
-                        }
-
-                        dist += (b & InternalInflateConstants.InflateMask[j]);
-
-                        b >>= j;
-                        k -= j;
-
-                        mode = COPY;
-                        goto case COPY;
-
-                    case COPY:  // o: copying bytes in window, waiting for space
-                        f = q - dist;
-                        while (f < 0)
-                        {
-                            // modulo window size-"while" instead
-                            f += blocks.end; // of "if" handles invalid distances
-                        }
-                        while (len != 0)
-                        {
-                            if (m == 0)
-                            {
-                                if (q == blocks.end && blocks.readAt != 0)
-                                {
-                                    q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-                                }
-                                if (m == 0)
-                                {
-                                    blocks.writeAt = q; r = blocks.Flush(r);
-                                    q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-
-                                    if (q == blocks.end && blocks.readAt != 0)
-                                    {
-                                        q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-                                    }
-
-                                    if (m == 0)
-                                    {
-                                        blocks.bitb = b; blocks.bitk = k;
-                                        z.AvailableBytesIn = n;
-                                        z.TotalBytesIn += p - z.NextIn;
-                                        z.NextIn = p;
-                                        blocks.writeAt = q;
-                                        return blocks.Flush(r);
-                                    }
-                                }
-                            }
-
-                            blocks.window[q++] = blocks.window[f++]; m--;
-
-                            if (f == blocks.end)
-                                f = 0;
-                            len--;
-                        }
-                        mode = START;
-                        break;
-
-                    case LIT:  // o: got literal, waiting for output space
-                        if (m == 0)
-                        {
-                            if (q == blocks.end && blocks.readAt != 0)
-                            {
-                                q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-                            }
-                            if (m == 0)
-                            {
-                                blocks.writeAt = q; r = blocks.Flush(r);
-                                q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-
-                                if (q == blocks.end && blocks.readAt != 0)
-                                {
-                                    q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-                                }
-                                if (m == 0)
-                                {
-                                    blocks.bitb = b; blocks.bitk = k;
-                                    z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                                    blocks.writeAt = q;
-                                    return blocks.Flush(r);
-                                }
-                            }
-                        }
-                        r = ZlibConstants.Z_OK;
-
-                        blocks.window[q++] = (byte)lit; m--;
-
-                        mode = START;
-                        break;
-
-                    case WASH:  // o: got eob, possibly more output
-                        if (k > 7)
-                        {
-                            // return unused byte, if any
-                            k -= 8;
-                            n++;
-                            p--; // can always return one
-                        }
-
-                        blocks.writeAt = q; r = blocks.Flush(r);
-                        q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
-
-                        if (blocks.readAt != blocks.writeAt)
-                        {
-                            blocks.bitb = b; blocks.bitk = k;
-                            z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                            blocks.writeAt = q;
-                            return blocks.Flush(r);
-                        }
-                        mode = END;
-                        goto case END;
-
-                    case END:
-                        r = ZlibConstants.Z_STREAM_END;
-                        blocks.bitb = b; blocks.bitk = k;
-                        z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                        blocks.writeAt = q;
-                        return blocks.Flush(r);
-
-                    case BADCODE:  // x: got error
-
-                        r = ZlibConstants.Z_DATA_ERROR;
-
-                        blocks.bitb = b; blocks.bitk = k;
-                        z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                        blocks.writeAt = q;
-                        return blocks.Flush(r);
-
-                    default:
-                        r = ZlibConstants.Z_STREAM_ERROR;
-
-                        blocks.bitb = b; blocks.bitk = k;
-                        z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                        blocks.writeAt = q;
-                        return blocks.Flush(r);
-                }
-            }
-        }
-
-
-        // Called with number of bytes left to write in window at least 258
-        // (the maximum string length) and number of input bytes available
-        // at least ten.  The ten bytes are six bytes for the longest length/
-        // distance pair plus four bytes for overloading the bit buffer.
-
-        internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z)
-        {
-            int t;        // temporary pointer
-            int[] tp;     // temporary pointer
-            int tp_index; // temporary pointer
-            int e;        // extra bits or operation
-            int b;        // bit buffer
-            int k;        // bits in bit buffer
-            int p;        // input data pointer
-            int n;        // bytes available there
-            int q;        // output window write pointer
-            int m;        // bytes to end of window or read pointer
-            int ml;       // mask for literal/length tree
-            int md;       // mask for distance tree
-            int c;        // bytes to copy
-            int d;        // distance back to copy from
-            int r;        // copy source pointer
-
-            int tp_index_t_3; // (tp_index+t)*3
-
-            // load input, output, bit values
-            p = z.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk;
-            q = s.writeAt; m = q < s.readAt ? s.readAt - q - 1 : s.end - q;
-
-            // initialize masks
-            ml = InternalInflateConstants.InflateMask[bl];
-            md = InternalInflateConstants.InflateMask[bd];
-
-            // do until not enough input or output space for fast loop
-            do
-            {
-                // assume called with m >= 258 && n >= 10
-                // get literal/length code
-                while (k < (20))
-                {
-                    // max bits for literal/length code
-                    n--;
-                    b |= (z.InputBuffer[p++] & 0xff) << k; k += 8;
-                }
-
-                t = b & ml;
-                tp = tl;
-                tp_index = tl_index;
-                tp_index_t_3 = (tp_index + t) * 3;
-                if ((e = tp[tp_index_t_3]) == 0)
-                {
-                    b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);
-
-                    s.window[q++] = (byte)tp[tp_index_t_3 + 2];
-                    m--;
-                    continue;
-                }
-                do
-                {
-
-                    b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);
-
-                    if ((e & 16) != 0)
-                    {
-                        e &= 15;
-                        c = tp[tp_index_t_3 + 2] + ((int)b & InternalInflateConstants.InflateMask[e]);
-
-                        b >>= e; k -= e;
-
-                        // decode distance base of block to copy
-                        while (k < 15)
-                        {
-                            // max bits for distance code
-                            n--;
-                            b |= (z.InputBuffer[p++] & 0xff) << k; k += 8;
-                        }
-
-                        t = b & md;
-                        tp = td;
-                        tp_index = td_index;
-                        tp_index_t_3 = (tp_index + t) * 3;
-                        e = tp[tp_index_t_3];
-
-                        do
-                        {
-
-                            b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);
-
-                            if ((e & 16) != 0)
-                            {
-                                // get extra bits to add to distance base
-                                e &= 15;
-                                while (k < e)
-                                {
-                                    // get extra bits (up to 13)
-                                    n--;
-                                    b |= (z.InputBuffer[p++] & 0xff) << k; k += 8;
-                                }
-
-                                d = tp[tp_index_t_3 + 2] + (b & InternalInflateConstants.InflateMask[e]);
-
-                                b >>= e; k -= e;
-
-                                // do the copy
-                                m -= c;
-                                if (q >= d)
-                                {
-                                    // offset before dest
-                                    //  just copy
-                                    r = q - d;
-                                    if (q - r > 0 && 2 > (q - r))
-                                    {
-                                        s.window[q++] = s.window[r++]; // minimum count is three,
-                                        s.window[q++] = s.window[r++]; // so unroll loop a little
-                                        c -= 2;
-                                    }
-                                    else
-                                    {
-                                        Array.Copy(s.window, r, s.window, q, 2);
-                                        q += 2; r += 2; c -= 2;
-                                    }
-                                }
-                                else
-                                {
-                                    // else offset after destination
-                                    r = q - d;
-                                    do
-                                    {
-                                        r += s.end; // force pointer in window
-                                    }
-                                    while (r < 0); // covers invalid distances
-                                    e = s.end - r;
-                                    if (c > e)
-                                    {
-                                        // if source crosses,
-                                        c -= e; // wrapped copy
-                                        if (q - r > 0 && e > (q - r))
-                                        {
-                                            do
-                                            {
-                                                s.window[q++] = s.window[r++];
-                                            }
-                                            while (--e != 0);
-                                        }
-                                        else
-                                        {
-                                            Array.Copy(s.window, r, s.window, q, e);
-                                            q += e; r += e; e = 0;
-                                        }
-                                        r = 0; // copy rest from start of window
-                                    }
-                                }
-
-                                // copy all or what's left
-                                if (q - r > 0 && c > (q - r))
-                                {
-                                    do
-                                    {
-                                        s.window[q++] = s.window[r++];
-                                    }
-                                    while (--c != 0);
-                                }
-                                else
-                                {
-                                    Array.Copy(s.window, r, s.window, q, c);
-                                    q += c; r += c; c = 0;
-                                }
-                                break;
-                            }
-                            else if ((e & 64) == 0)
-                            {
-                                t += tp[tp_index_t_3 + 2];
-                                t += (b & InternalInflateConstants.InflateMask[e]);
-                                tp_index_t_3 = (tp_index + t) * 3;
-                                e = tp[tp_index_t_3];
-                            }
-                            else
-                            {
-                                z.Message = "invalid distance code";
-
-                                c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);
-
-                                s.bitb = b; s.bitk = k;
-                                z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                                s.writeAt = q;
-
-                                return ZlibConstants.Z_DATA_ERROR;
-                            }
-                        }
-                        while (true);
-                        break;
-                    }
-
-                    if ((e & 64) == 0)
-                    {
-                        t += tp[tp_index_t_3 + 2];
-                        t += (b & InternalInflateConstants.InflateMask[e]);
-                        tp_index_t_3 = (tp_index + t) * 3;
-                        if ((e = tp[tp_index_t_3]) == 0)
-                        {
-                            b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);
-                            s.window[q++] = (byte)tp[tp_index_t_3 + 2];
-                            m--;
-                            break;
-                        }
-                    }
-                    else if ((e & 32) != 0)
-                    {
-                        c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);
-
-                        s.bitb = b; s.bitk = k;
-                        z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                        s.writeAt = q;
-
-                        return ZlibConstants.Z_STREAM_END;
-                    }
-                    else
-                    {
-                        z.Message = "invalid literal/length code";
-
-                        c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);
-
-                        s.bitb = b; s.bitk = k;
-                        z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-                        s.writeAt = q;
-
-                        return ZlibConstants.Z_DATA_ERROR;
-                    }
-                }
-                while (true);
-            }
-            while (m >= 258 && n >= 10);
-
-            // not enough input or output--restore pointers and return
-            c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);
-
-            s.bitb = b; s.bitk = k;
-            z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
-            s.writeAt = q;
-
-            return ZlibConstants.Z_OK;
-        }
-    }
-
-
-    internal sealed class InflateManager
-    {
-        // preset dictionary flag in zlib header
-        private const int PRESET_DICT = 0x20;
-
-        private const int Z_DEFLATED = 8;
-
-        private enum InflateManagerMode
-        {
-            METHOD = 0,  // waiting for method byte
-            FLAG   = 1,  // waiting for flag byte
-            DICT4  = 2,  // four dictionary check bytes to go
-            DICT3  = 3,  // three dictionary check bytes to go
-            DICT2  = 4,  // two dictionary check bytes to go
-            DICT1  = 5,  // one dictionary check byte to go
-            DICT0  = 6,  // waiting for inflateSetDictionary
-            BLOCKS = 7,  // decompressing blocks
-            CHECK4 = 8,  // four check bytes to go
-            CHECK3 = 9,  // three check bytes to go
-            CHECK2 = 10, // two check bytes to go
-            CHECK1 = 11, // one check byte to go
-            DONE   = 12, // finished check, done
-            BAD    = 13, // got an error--stay here
-        }
-
-        private InflateManagerMode mode; // current inflate mode
-        internal ZlibCodec _codec; // pointer back to this zlib stream
-
-        // mode dependent information
-        internal int method; // if FLAGS, method byte
-
-        // if CHECK, check values to compare
-        internal uint computedCheck; // computed check value
-        internal uint expectedCheck; // stream check value
-
-        // if BAD, inflateSync's marker bytes count
-        internal int marker;
-
-        // mode independent information
-        //internal int nowrap; // flag for no wrapper
-        private bool _handleRfc1950HeaderBytes = true;
-        internal bool HandleRfc1950HeaderBytes
-        {
-            get { return _handleRfc1950HeaderBytes; }
-            set { _handleRfc1950HeaderBytes = value; }
-        }
-        internal int wbits; // log2(window size)  (8..15, defaults to 15)
-
-        internal InflateBlocks blocks; // current inflate_blocks state
-
-        public InflateManager() { }
-
-        public InflateManager(bool expectRfc1950HeaderBytes)
-        {
-            _handleRfc1950HeaderBytes = expectRfc1950HeaderBytes;
-        }
-
-        internal int Reset()
-        {
-            _codec.TotalBytesIn = _codec.TotalBytesOut = 0;
-            _codec.Message = null;
-            mode = HandleRfc1950HeaderBytes ? InflateManagerMode.METHOD : InflateManagerMode.BLOCKS;
-            blocks.Reset();
-            return ZlibConstants.Z_OK;
-        }
-
-        internal int End()
-        {
-            if (blocks != null)
-                blocks.Free();
-            blocks = null;
-            return ZlibConstants.Z_OK;
-        }
-
-        internal int Initialize(ZlibCodec codec, int w)
-        {
-            _codec = codec;
-            _codec.Message = null;
-            blocks = null;
-
-            // handle undocumented nowrap option (no zlib header or check)
-            //nowrap = 0;
-            //if (w < 0)
-            //{
-            //    w = - w;
-            //    nowrap = 1;
-            //}
-
-            // set window size
-            if (w < 8 || w > 15)
-            {
-                End();
-                throw new ZlibException("Bad window size.");
-
-                //return ZlibConstants.Z_STREAM_ERROR;
-            }
-            wbits = w;
-
-            blocks = new InflateBlocks(codec,
-                HandleRfc1950HeaderBytes ? this : null,
-                1 << w);
-
-            // reset state
-            Reset();
-            return ZlibConstants.Z_OK;
-        }
-
-
-        internal int Inflate(FlushType flush)
-        {
-            int b;
-
-            if (_codec.InputBuffer == null)
-                throw new ZlibException("InputBuffer is null. ");
-
-//             int f = (flush == FlushType.Finish)
-//                 ? ZlibConstants.Z_BUF_ERROR
-//                 : ZlibConstants.Z_OK;
-
-            // workitem 8870
-            int f = ZlibConstants.Z_OK;
-            int r = ZlibConstants.Z_BUF_ERROR;
-
-            while (true)
-            {
-                switch (mode)
-                {
-                    case InflateManagerMode.METHOD:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED)
-                        {
-                            mode = InflateManagerMode.BAD;
-                            _codec.Message = String.Format("unknown compression method (0x{0:X2})", method);
-                            marker = 5; // can't try inflateSync
-                            break;
-                        }
-                        if ((method >> 4) + 8 > wbits)
-                        {
-                            mode = InflateManagerMode.BAD;
-                            _codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8);
-                            marker = 5; // can't try inflateSync
-                            break;
-                        }
-                        mode = InflateManagerMode.FLAG;
-                        break;
-
-
-                    case InflateManagerMode.FLAG:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff;
-
-                        if ((((method << 8) + b) % 31) != 0)
-                        {
-                            mode = InflateManagerMode.BAD;
-                            _codec.Message = "incorrect header check";
-                            marker = 5; // can't try inflateSync
-                            break;
-                        }
-
-                        mode = ((b & PRESET_DICT) == 0)
-                            ? InflateManagerMode.BLOCKS
-                            : InflateManagerMode.DICT4;
-                        break;
-
-                    case InflateManagerMode.DICT4:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
-                        mode = InflateManagerMode.DICT3;
-                        break;
-
-                    case InflateManagerMode.DICT3:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
-                        mode = InflateManagerMode.DICT2;
-                        break;
-
-                    case InflateManagerMode.DICT2:
-
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
-                        mode = InflateManagerMode.DICT1;
-                        break;
-
-
-                    case InflateManagerMode.DICT1:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
-                        expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
-                        _codec._Adler32 = expectedCheck;
-                        mode = InflateManagerMode.DICT0;
-                        return ZlibConstants.Z_NEED_DICT;
-
-
-                    case InflateManagerMode.DICT0:
-                        mode = InflateManagerMode.BAD;
-                        _codec.Message = "need dictionary";
-                        marker = 0; // can try inflateSync
-                        return ZlibConstants.Z_STREAM_ERROR;
-
-
-                    case InflateManagerMode.BLOCKS:
-                        r = blocks.Process(r);
-                        if (r == ZlibConstants.Z_DATA_ERROR)
-                        {
-                            mode = InflateManagerMode.BAD;
-                            marker = 0; // can try inflateSync
-                            break;
-                        }
-
-                        if (r == ZlibConstants.Z_OK) r = f;
-
-                        if (r != ZlibConstants.Z_STREAM_END)
-                            return r;
-
-                        r = f;
-                        computedCheck = blocks.Reset();
-                        if (!HandleRfc1950HeaderBytes)
-                        {
-                            mode = InflateManagerMode.DONE;
-                            return ZlibConstants.Z_STREAM_END;
-                        }
-                        mode = InflateManagerMode.CHECK4;
-                        break;
-
-                    case InflateManagerMode.CHECK4:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
-                        mode = InflateManagerMode.CHECK3;
-                        break;
-
-                    case InflateManagerMode.CHECK3:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
-                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
-                        mode = InflateManagerMode.CHECK2;
-                        break;
-
-                    case InflateManagerMode.CHECK2:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--;
-                        _codec.TotalBytesIn++;
-                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
-                        mode = InflateManagerMode.CHECK1;
-                        break;
-
-                    case InflateManagerMode.CHECK1:
-                        if (_codec.AvailableBytesIn == 0) return r;
-                        r = f;
-                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
-                        expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
-                        if (computedCheck != expectedCheck)
-                        {
-                            mode = InflateManagerMode.BAD;
-                            _codec.Message = "incorrect data check";
-                            marker = 5; // can't try inflateSync
-                            break;
-                        }
-                        mode = InflateManagerMode.DONE;
-                        return ZlibConstants.Z_STREAM_END;
-
-                    case InflateManagerMode.DONE:
-                        return ZlibConstants.Z_STREAM_END;
-
-                    case InflateManagerMode.BAD:
-                        throw new ZlibException(String.Format("Bad state ({0})", _codec.Message));
-
-                    default:
-                        throw new ZlibException("Stream error.");
-
-                }
-            }
-        }
-
-
-
-        internal int SetDictionary(byte[] dictionary)
-        {
-            int index = 0;
-            int length = dictionary.Length;
-            if (mode != InflateManagerMode.DICT0)
-                throw new ZlibException("Stream error.");
-
-            if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
-            {
-                return ZlibConstants.Z_DATA_ERROR;
-            }
-
-            _codec._Adler32 = Adler.Adler32(0, null, 0, 0);
-
-            if (length >= (1 << wbits))
-            {
-                length = (1 << wbits) - 1;
-                index = dictionary.Length - length;
-            }
-            blocks.SetDictionary(dictionary, index, length);
-            mode = InflateManagerMode.BLOCKS;
-            return ZlibConstants.Z_OK;
-        }
-
-
-        private static readonly byte[] mark = new byte[] { 0, 0, 0xff, 0xff };
-
-        internal int Sync()
-        {
-            int n; // number of bytes to look at
-            int p; // pointer to bytes
-            int m; // number of marker bytes found in a row
-            long r, w; // temporaries to save total_in and total_out
-
-            // set up
-            if (mode != InflateManagerMode.BAD)
-            {
-                mode = InflateManagerMode.BAD;
-                marker = 0;
-            }
-            if ((n = _codec.AvailableBytesIn) == 0)
-                return ZlibConstants.Z_BUF_ERROR;
-            p = _codec.NextIn;
-            m = marker;
-
-            // search
-            while (n != 0 && m < 4)
-            {
-                if (_codec.InputBuffer[p] == mark[m])
-                {
-                    m++;
-                }
-                else if (_codec.InputBuffer[p] != 0)
-                {
-                    m = 0;
-                }
-                else
-                {
-                    m = 4 - m;
-                }
-                p++; n--;
-            }
-
-            // restore
-            _codec.TotalBytesIn += p - _codec.NextIn;
-            _codec.NextIn = p;
-            _codec.AvailableBytesIn = n;
-            marker = m;
-
-            // return no joy or set up to restart on a new block
-            if (m != 4)
-            {
-                return ZlibConstants.Z_DATA_ERROR;
-            }
-            r = _codec.TotalBytesIn;
-            w = _codec.TotalBytesOut;
-            Reset();
-            _codec.TotalBytesIn = r;
-            _codec.TotalBytesOut = w;
-            mode = InflateManagerMode.BLOCKS;
-            return ZlibConstants.Z_OK;
-        }
-
-
-        // Returns true if inflate is currently at the end of a block generated
-        // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
-        // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
-        // but removes the length bytes of the resulting empty stored block. When
-        // decompressing, PPP checks that at the end of input packet, inflate is
-        // waiting for these length bytes.
-        internal int SyncPoint(ZlibCodec z)
-        {
-            return blocks.SyncPoint();
-        }
-    }
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/ParallelDeflateOutputStream.cs b/EPPlus/Packaging/DotNetZip/Zlib/ParallelDeflateOutputStream.cs
deleted file mode 100644
index 3fc9685..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/ParallelDeflateOutputStream.cs
+++ /dev/null
@@ -1,1386 +0,0 @@
-//#define Trace
-
-// ParallelDeflateOutputStream.cs
-// ------------------------------------------------------------------
-//
-// A DeflateStream that does compression only, it uses a
-// divide-and-conquer approach with multiple threads to exploit multiple
-// CPUs for the DEFLATE computation.
-//
-// last saved: <2011-July-31 14:49:40>
-//
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 by 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
-//
-// ------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.IO;
-
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    internal class WorkItem
-    {
-        public byte[] buffer;
-        public byte[] compressed;
-        public int crc;
-        public int index;
-        public int ordinal;
-        public int inputBytesAvailable;
-        public int compressedBytesAvailable;
-        public ZlibCodec compressor;
-
-        public WorkItem(int size,
-                        Ionic.Zlib.CompressionLevel compressLevel,
-                        CompressionStrategy strategy,
-                        int ix)
-        {
-            this.buffer= new byte[size];
-            // alloc 5 bytes overhead for every block (margin of safety= 2)
-            int n = size + ((size / 32768)+1) * 5 * 2;
-            this.compressed = new byte[n];
-            this.compressor = new ZlibCodec();
-            this.compressor.InitializeDeflate(compressLevel, false);
-            this.compressor.OutputBuffer = this.compressed;
-            this.compressor.InputBuffer = this.buffer;
-            this.index = ix;
-        }
-    }
-
-    /// <summary>
-    ///   A class for compressing streams using the
-    ///   Deflate algorithm with multiple threads.
-    /// </summary>
-    ///
-    /// <remarks>
-    /// <para>
-    ///   This class performs DEFLATE compression through writing.  For
-    ///   more information on the Deflate algorithm, see IETF RFC 1951,
-    ///   "DEFLATE Compressed Data Format Specification version 1.3."
-    /// </para>
-    ///
-    /// <para>
-    ///   This class is similar to <see cref="Ionic.Zlib.DeflateStream"/>, except
-    ///   that this class is for compression only, and this implementation uses an
-    ///   approach that employs multiple worker threads to perform the DEFLATE.  On
-    ///   a multi-cpu or multi-core computer, the performance of this class can be
-    ///   significantly higher than the single-threaded DeflateStream, particularly
-    ///   for larger streams.  How large?  Anything over 10mb is a good candidate
-    ///   for parallel compression.
-    /// </para>
-    ///
-    /// <para>
-    ///   The tradeoff is that this class uses more memory and more CPU than the
-    ///   vanilla DeflateStream, and also is less efficient as a compressor. For
-    ///   large files the size of the compressed data stream can be less than 1%
-    ///   larger than the size of a compressed data stream from the vanialla
-    ///   DeflateStream.  For smaller files the difference can be larger.  The
-    ///   difference will also be larger if you set the BufferSize to be lower than
-    ///   the default value.  Your mileage may vary. Finally, for small files, the
-    ///   ParallelDeflateOutputStream can be much slower than the vanilla
-    ///   DeflateStream, because of the overhead associated to using the thread
-    ///   pool.
-    /// </para>
-    ///
-    /// </remarks>
-    /// <seealso cref="Ionic.Zlib.DeflateStream" />
-    public class ParallelDeflateOutputStream : System.IO.Stream
-    {
-
-        private static readonly int IO_BUFFER_SIZE_DEFAULT = 64 * 1024;  // 128k
-        private static readonly int BufferPairsPerCore = 4;
-
-        private System.Collections.Generic.List<WorkItem> _pool;
-        private bool                        _leaveOpen;
-        private bool                        emitting;
-        private System.IO.Stream            _outStream;
-        private int                         _maxBufferPairs;
-        private int                         _bufferSize = IO_BUFFER_SIZE_DEFAULT;
-        private AutoResetEvent              _newlyCompressedBlob;
-        //private ManualResetEvent            _writingDone;
-        //private ManualResetEvent            _sessionReset;
-        private object                      _outputLock = new object();
-        private bool                        _isClosed;
-        private bool                        _firstWriteDone;
-        private int                         _currentlyFilling;
-        private int                         _lastFilled;
-        private int                         _lastWritten;
-        private int                         _latestCompressed;
-        private int                         _Crc32;
-        private Ionic.Crc.CRC32             _runningCrc;
-        private object                      _latestLock = new object();
-        private System.Collections.Generic.Queue<int>     _toWrite;
-        private System.Collections.Generic.Queue<int>     _toFill;
-        private Int64                       _totalBytesProcessed;
-        private Ionic.Zlib.CompressionLevel _compressLevel;
-        private volatile Exception          _pendingException;
-        private bool                        _handlingException;
-        private object                      _eLock = new Object();  // protects _pendingException
-
-        // This bitfield is used only when Trace is defined.
-        //private TraceBits _DesiredTrace = TraceBits.Write | TraceBits.WriteBegin |
-        //TraceBits.WriteDone | TraceBits.Lifecycle | TraceBits.Fill | TraceBits.Flush |
-        //TraceBits.Session;
-
-        //private TraceBits _DesiredTrace = TraceBits.WriteBegin | TraceBits.WriteDone | TraceBits.Synch | TraceBits.Lifecycle  | TraceBits.Session ;
-
-        private TraceBits _DesiredTrace =
-            TraceBits.Session |
-            TraceBits.Compress |
-            TraceBits.WriteTake |
-            TraceBits.WriteEnter |
-            TraceBits.EmitEnter |
-            TraceBits.EmitDone |
-            TraceBits.EmitLock |
-            TraceBits.EmitSkip |
-            TraceBits.EmitBegin;
-
-        /// <summary>
-        /// Create a ParallelDeflateOutputStream.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This stream compresses data written into it via the DEFLATE
-        ///   algorithm (see RFC 1951), and writes out the compressed byte stream.
-        /// </para>
-        ///
-        /// <para>
-        ///   The instance will use the default compression level, the default
-        ///   buffer sizes and the default number of threads and buffers per
-        ///   thread.
-        /// </para>
-        ///
-        /// <para>
-        ///   This class is similar to <see cref="Ionic.Zlib.DeflateStream"/>,
-        ///   except that this implementation uses an approach that employs
-        ///   multiple worker threads to perform the DEFLATE.  On a multi-cpu or
-        ///   multi-core computer, the performance of this class can be
-        ///   significantly higher than the single-threaded DeflateStream,
-        ///   particularly for larger streams.  How large?  Anything over 10mb is
-        ///   a good candidate for parallel compression.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        /// This example shows how to use a ParallelDeflateOutputStream to compress
-        /// data.  It reads a file, compresses it, and writes the compressed data to
-        /// a second, output file.
-        ///
-        /// <code>
-        /// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        /// int n= -1;
-        /// String outputFile = fileToCompress + ".compressed";
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(outputFile))
-        ///     {
-        ///         using (Stream compressor = new ParallelDeflateOutputStream(raw))
-        ///         {
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Dim buffer As Byte() = New Byte(4096) {}
-        /// Dim n As Integer = -1
-        /// Dim outputFile As String = (fileToCompress &amp; ".compressed")
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(outputFile)
-        ///         Using compressor As Stream = New ParallelDeflateOutputStream(raw)
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        /// <param name="stream">The stream to which compressed data will be written.</param>
-        public ParallelDeflateOutputStream(System.IO.Stream stream)
-            : this(stream, CompressionLevel.Default, CompressionStrategy.Default, false)
-        {
-        }
-
-        /// <summary>
-        ///   Create a ParallelDeflateOutputStream using the specified CompressionLevel.
-        /// </summary>
-        /// <remarks>
-        ///   See the <see cref="ParallelDeflateOutputStream(System.IO.Stream)"/>
-        ///   constructor for example code.
-        /// </remarks>
-        /// <param name="stream">The stream to which compressed data will be written.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        public ParallelDeflateOutputStream(System.IO.Stream stream, CompressionLevel level)
-            : this(stream, level, CompressionStrategy.Default, false)
-        {
-        }
-
-        /// <summary>
-        /// Create a ParallelDeflateOutputStream and specify whether to leave the captive stream open
-        /// when the ParallelDeflateOutputStream is closed.
-        /// </summary>
-        /// <remarks>
-        ///   See the <see cref="ParallelDeflateOutputStream(System.IO.Stream)"/>
-        ///   constructor for example code.
-        /// </remarks>
-        /// <param name="stream">The stream to which compressed data will be written.</param>
-        /// <param name="leaveOpen">
-        ///    true if the application would like the stream to remain open after inflation/deflation.
-        /// </param>
-        public ParallelDeflateOutputStream(System.IO.Stream stream, bool leaveOpen)
-            : this(stream, CompressionLevel.Default, CompressionStrategy.Default, leaveOpen)
-        {
-        }
-
-        /// <summary>
-        /// Create a ParallelDeflateOutputStream and specify whether to leave the captive stream open
-        /// when the ParallelDeflateOutputStream is closed.
-        /// </summary>
-        /// <remarks>
-        ///   See the <see cref="ParallelDeflateOutputStream(System.IO.Stream)"/>
-        ///   constructor for example code.
-        /// </remarks>
-        /// <param name="stream">The stream to which compressed data will be written.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        /// <param name="leaveOpen">
-        ///    true if the application would like the stream to remain open after inflation/deflation.
-        /// </param>
-        public ParallelDeflateOutputStream(System.IO.Stream stream, CompressionLevel level, bool leaveOpen)
-            : this(stream, CompressionLevel.Default, CompressionStrategy.Default, leaveOpen)
-        {
-        }
-
-        /// <summary>
-        /// Create a ParallelDeflateOutputStream using the specified
-        /// CompressionLevel and CompressionStrategy, and specifying whether to
-        /// leave the captive stream open when the ParallelDeflateOutputStream is
-        /// closed.
-        /// </summary>
-        /// <remarks>
-        ///   See the <see cref="ParallelDeflateOutputStream(System.IO.Stream)"/>
-        ///   constructor for example code.
-        /// </remarks>
-        /// <param name="stream">The stream to which compressed data will be written.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        /// <param name="strategy">
-        ///   By tweaking this parameter, you may be able to optimize the compression for
-        ///   data with particular characteristics.
-        /// </param>
-        /// <param name="leaveOpen">
-        ///    true if the application would like the stream to remain open after inflation/deflation.
-        /// </param>
-        public ParallelDeflateOutputStream(System.IO.Stream stream,
-                                           CompressionLevel level,
-                                           CompressionStrategy strategy,
-                                           bool leaveOpen)
-        {
-            TraceOutput(TraceBits.Lifecycle | TraceBits.Session, "-------------------------------------------------------");
-            TraceOutput(TraceBits.Lifecycle | TraceBits.Session, "Create {0:X8}", this.GetHashCode());
-            _outStream = stream;
-            _compressLevel= level;
-            Strategy = strategy;
-            _leaveOpen = leaveOpen;
-            this.MaxBufferPairs = 16; // default
-        }
-
-
-        /// <summary>
-        ///   The ZLIB strategy to be used during compression.
-        /// </summary>
-        ///
-        public CompressionStrategy Strategy
-        {
-            get;
-            private set;
-        }
-
-        /// <summary>
-        ///   The maximum number of buffer pairs to use.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   This property sets an upper limit on the number of memory buffer
-        ///   pairs to create.  The implementation of this stream allocates
-        ///   multiple buffers to facilitate parallel compression.  As each buffer
-        ///   fills up, this 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="BufferSize"/>).  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 before the first call to Write(), which is when the buffers are
-        ///   allocated.
-        /// </para>
-        /// </remarks>
-        public int MaxBufferPairs
-        {
-            get
-            {
-                return _maxBufferPairs;
-            }
-            set
-            {
-                if (value < 4)
-                    throw new ArgumentException("MaxBufferPairs",
-                                                "Value must be 4 or greater.");
-                _maxBufferPairs = value;
-            }
-        }
-
-        /// <summary>
-        ///   The size of the buffers used by the compressor threads.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   The default buffer size is 128k. The application can set this value
-        ///   at any time, but it is effective only before the first Write().
-        /// </para>
-        ///
-        /// <para>
-        ///   Larger buffer sizes implies larger memory consumption but allows
-        ///   more efficient compression. Using smaller buffer sizes consumes less
-        ///   memory but may result in less effective compression.  For example,
-        ///   using the default buffer size of 128k, the compression delivered is
-        ///   within 1% of the compression delivered by the single-threaded <see
-        ///   cref="Ionic.Zlib.DeflateStream"/>.  On the other hand, using a
-        ///   BufferSize of 8k can result in a compressed data stream that is 5%
-        ///   larger than that delivered by the single-threaded
-        ///   <c>DeflateStream</c>.  Excessively small buffer sizes can also cause
-        ///   the speed of the ParallelDeflateOutputStream to drop, because of
-        ///   larger thread scheduling overhead dealing with many many small
-        ///   buffers.
-        /// </para>
-        ///
-        /// <para>
-        ///   The total amount of storage space allocated for buffering will be
-        ///   (N*S*2), where N is the number of buffer pairs, and S is the size of
-        ///   each buffer (this property). There are 2 buffers used by the
-        ///   compressor, one for input and one for output.  By default, DotNetZip
-        ///   allocates 4 buffer pairs per CPU core, so if your machine has 4
-        ///   cores, then the number of buffer pairs used will be 16. If you
-        ///   accept the default value of this property, 128k, then the
-        ///   ParallelDeflateOutputStream will use 16 * 2 * 128kb of buffer memory
-        ///   in total, or 4mb, in blocks of 128kb.  If you set this property to
-        ///   64kb, then the number will be 16 * 2 * 64kb of buffer memory, or
-        ///   2mb.
-        /// </para>
-        ///
-        /// </remarks>
-        public int BufferSize
-        {
-            get { return _bufferSize;}
-            set
-            {
-                if (value < 1024)
-                    throw new ArgumentOutOfRangeException("BufferSize",
-                                                          "BufferSize must be greater than 1024 bytes");
-                _bufferSize = value;
-            }
-        }
-
-        /// <summary>
-        /// The CRC32 for the data that was written out, prior to compression.
-        /// </summary>
-        /// <remarks>
-        /// This value is meaningful only after a call to Close().
-        /// </remarks>
-        public int Crc32 { get { return _Crc32; } }
-
-
-        /// <summary>
-        /// The total number of uncompressed bytes processed by the ParallelDeflateOutputStream.
-        /// </summary>
-        /// <remarks>
-        /// This value is meaningful only after a call to Close().
-        /// </remarks>
-        public Int64 BytesProcessed { get { return _totalBytesProcessed; } }
-
-
-        private void _InitializePoolOfWorkItems()
-        {
-            _toWrite = new Queue<int>();
-            _toFill = new Queue<int>();
-            _pool = new System.Collections.Generic.List<WorkItem>();
-            int nTasks = BufferPairsPerCore * Environment.ProcessorCount;
-            nTasks = Math.Min(nTasks, _maxBufferPairs);
-            for(int i=0; i < nTasks; i++)
-            {
-                _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy, i));
-                _toFill.Enqueue(i);
-            }
-
-            _newlyCompressedBlob = new AutoResetEvent(false);
-            _runningCrc = new Ionic.Crc.CRC32();
-            _currentlyFilling = -1;
-            _lastFilled = -1;
-            _lastWritten = -1;
-            _latestCompressed = -1;
-        }
-
-
-
-
-        /// <summary>
-        ///   Write data to the stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   To use the ParallelDeflateOutputStream to compress data, create a
-        ///   ParallelDeflateOutputStream with CompressionMode.Compress, passing a
-        ///   writable output stream.  Then call Write() on that
-        ///   ParallelDeflateOutputStream, providing uncompressed data as input.  The
-        ///   data sent to the output stream will be the compressed form of the data
-        ///   written.
-        /// </para>
-        ///
-        /// <para>
-        ///   To decompress data, use the <see cref="Ionic.Zlib.DeflateStream"/> class.
-        /// </para>
-        ///
-        /// </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)
-        {
-            bool mustWait = false;
-
-            // This method does this:
-            //   0. handles any pending exceptions
-            //   1. write any buffers that are ready to be written,
-            //   2. fills a work buffer; when full, flip state to 'Filled',
-            //   3. if more data to be written,  goto step 1
-
-            if (_isClosed)
-                throw new InvalidOperationException();
-
-            // dispense any exceptions that occurred on the BG threads
-            if (_pendingException != null)
-            {
-                _handlingException = true;
-                var pe = _pendingException;
-                _pendingException = null;
-                throw pe;
-            }
-
-            if (count == 0) return;
-
-            if (!_firstWriteDone)
-            {
-                // Want to do this on first Write, first session, and not in the
-                // constructor.  We want to allow MaxBufferPairs to
-                // change after construction, but before first Write.
-                _InitializePoolOfWorkItems();
-                _firstWriteDone = true;
-            }
-
-
-            do
-            {
-                // may need to make buffers available
-                EmitPendingBuffers(false, mustWait);
-
-                mustWait = false;
-                // use current buffer, or get a new buffer to fill
-                int ix = -1;
-                if (_currentlyFilling >= 0)
-                {
-                    ix = _currentlyFilling;
-                    TraceOutput(TraceBits.WriteTake,
-                                "Write    notake   wi({0}) lf({1})",
-                                ix,
-                                _lastFilled);
-                }
-                else
-                {
-                    TraceOutput(TraceBits.WriteTake, "Write    take?");
-                    if (_toFill.Count == 0)
-                    {
-                        // no available buffers, so... need to emit
-                        // compressed buffers.
-                        mustWait = true;
-                        continue;
-                    }
-
-                    ix = _toFill.Dequeue();
-                    TraceOutput(TraceBits.WriteTake,
-                                "Write    take     wi({0}) lf({1})",
-                                ix,
-                                _lastFilled);
-                    ++_lastFilled; // TODO: consider rollover?
-                }
-
-                WorkItem workitem = _pool[ix];
-
-                int limit = ((workitem.buffer.Length - workitem.inputBytesAvailable) > count)
-                    ? count
-                    : (workitem.buffer.Length - workitem.inputBytesAvailable);
-
-                workitem.ordinal = _lastFilled;
-
-                TraceOutput(TraceBits.Write,
-                            "Write    lock     wi({0}) ord({1}) iba({2})",
-                            workitem.index,
-                            workitem.ordinal,
-                            workitem.inputBytesAvailable
-                            );
-
-                // copy from the provided buffer to our workitem, starting at
-                // the tail end of whatever data we might have in there currently.
-                Buffer.BlockCopy(buffer,
-                                 offset,
-                                 workitem.buffer,
-                                 workitem.inputBytesAvailable,
-                                 limit);
-
-                count -= limit;
-                offset += limit;
-                workitem.inputBytesAvailable += limit;
-                if (workitem.inputBytesAvailable == workitem.buffer.Length)
-                {
-                    // No need for interlocked.increment: the Write()
-                    // method is documented as not multi-thread safe, so
-                    // we can assume Write() calls come in from only one
-                    // thread.
-                    TraceOutput(TraceBits.Write,
-                                "Write    QUWI     wi({0}) ord({1}) iba({2}) nf({3})",
-                                workitem.index,
-                                workitem.ordinal,
-                                workitem.inputBytesAvailable );
-
-                    if (!ThreadPool.QueueUserWorkItem( _DeflateOne, workitem ))
-                        throw new Exception("Cannot enqueue workitem");
-
-                    _currentlyFilling = -1; // will get a new buffer next time
-                }
-                else
-                    _currentlyFilling = ix;
-
-                if (count > 0)
-                    TraceOutput(TraceBits.WriteEnter, "Write    more");
-            }
-            while (count > 0);  // until no more to write
-
-            TraceOutput(TraceBits.WriteEnter, "Write    exit");
-            return;
-        }
-
-
-
-        private void _FlushFinish()
-        {
-            // After writing a series of compressed buffers, each one closed
-            // with Flush.Sync, we now write the final one as Flush.Finish,
-            // and then stop.
-            byte[] buffer = new byte[128];
-            var compressor = new ZlibCodec();
-            int rc = compressor.InitializeDeflate(_compressLevel, false);
-            compressor.InputBuffer = null;
-            compressor.NextIn = 0;
-            compressor.AvailableBytesIn = 0;
-            compressor.OutputBuffer = buffer;
-            compressor.NextOut = 0;
-            compressor.AvailableBytesOut = buffer.Length;
-            rc = compressor.Deflate(FlushType.Finish);
-
-            if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
-                throw new Exception("deflating: " + compressor.Message);
-
-            if (buffer.Length - compressor.AvailableBytesOut > 0)
-            {
-                TraceOutput(TraceBits.EmitBegin,
-                            "Emit     begin    flush bytes({0})",
-                            buffer.Length - compressor.AvailableBytesOut);
-
-                _outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
-
-                TraceOutput(TraceBits.EmitDone,
-                            "Emit     done     flush");
-            }
-
-            compressor.EndDeflate();
-
-            _Crc32 = _runningCrc.Crc32Result;
-        }
-
-
-        private void _Flush(bool lastInput)
-        {
-            if (_isClosed)
-                throw new InvalidOperationException();
-
-            if (emitting) return;
-
-            // compress any partial buffer
-            if (_currentlyFilling >= 0)
-            {
-                WorkItem workitem = _pool[_currentlyFilling];
-                _DeflateOne(workitem);
-                _currentlyFilling = -1; // get a new buffer next Write()
-            }
-
-            if (lastInput)
-            {
-                EmitPendingBuffers(true, false);
-                _FlushFinish();
-            }
-            else
-            {
-                EmitPendingBuffers(false, false);
-            }
-        }
-
-
-
-        /// <summary>
-        /// Flush the stream.
-        /// </summary>
-        public override void Flush()
-        {
-            if (_pendingException != null)
-            {
-                _handlingException = true;
-                var pe = _pendingException;
-                _pendingException = null;
-                throw pe;
-            }
-            if (_handlingException)
-                return;
-
-            _Flush(false);
-        }
-
-
-        /// <summary>
-        /// Close the stream.
-        /// </summary>
-        /// <remarks>
-        /// You must call Close on the stream to guarantee that all of the data written in has
-        /// been compressed, and the compressed data has been written out.
-        /// </remarks>
-        public override void Close()
-        {
-            TraceOutput(TraceBits.Session, "Close {0:X8}", this.GetHashCode());
-
-            if (_pendingException != null)
-            {
-                _handlingException = true;
-                var pe = _pendingException;
-                _pendingException = null;
-                throw pe;
-            }
-
-            if (_handlingException)
-                return;
-
-            if (_isClosed) return;
-
-            _Flush(true);
-
-            if (!_leaveOpen)
-                _outStream.Close();
-
-            _isClosed= true;
-        }
-
-
-
-        // workitem 10030 - implement a new Dispose method
-
-        /// <summary>Dispose the object</summary>
-        /// <remarks>
-        ///   <para>
-        ///     Because ParallelDeflateOutputStream is IDisposable, the
-        ///     application must call this method when finished using the instance.
-        ///   </para>
-        ///   <para>
-        ///     This method is generally called implicitly upon exit from
-        ///     a <c>using</c> scope in C# (<c>Using</c> in VB).
-        ///   </para>
-        /// </remarks>
-        new public void Dispose()
-        {
-            TraceOutput(TraceBits.Lifecycle, "Dispose  {0:X8}", this.GetHashCode());
-            Close();
-            _pool = null;
-            Dispose(true);
-        }
-
-
-
-        /// <summary>The Dispose method</summary>
-        /// <param name="disposing">
-        ///   indicates whether the Dispose method was invoked by user code.
-        /// </param>
-        protected override void Dispose(bool disposing)
-        {
-            base.Dispose(disposing);
-        }
-
-
-        /// <summary>
-        ///   Resets the stream for use with another stream.
-        /// </summary>
-        /// <remarks>
-        ///   Because the ParallelDeflateOutputStream is expensive to create, it
-        ///   has been designed so that it can be recycled and re-used.  You have
-        ///   to call Close() on the stream first, then you can call Reset() on
-        ///   it, to use it again on another stream.
-        /// </remarks>
-        ///
-        /// <param name="stream">
-        ///   The new output stream for this era.
-        /// </param>
-        ///
-        /// <example>
-        /// <code>
-        /// ParallelDeflateOutputStream deflater = null;
-        /// foreach (var inputFile in listOfFiles)
-        /// {
-        ///     string outputFile = inputFile + ".compressed";
-        ///     using (System.IO.Stream input = System.IO.File.OpenRead(inputFile))
-        ///     {
-        ///         using (var outStream = System.IO.File.Create(outputFile))
-        ///         {
-        ///             if (deflater == null)
-        ///                 deflater = new ParallelDeflateOutputStream(outStream,
-        ///                                                            CompressionLevel.Best,
-        ///                                                            CompressionStrategy.Default,
-        ///                                                            true);
-        ///             deflater.Reset(outStream);
-        ///
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 deflater.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        /// </example>
-        public void Reset(Stream stream)
-        {
-            TraceOutput(TraceBits.Session, "-------------------------------------------------------");
-            TraceOutput(TraceBits.Session, "Reset {0:X8} firstDone({1})", this.GetHashCode(), _firstWriteDone);
-
-            if (!_firstWriteDone) return;
-
-            // reset all status
-            _toWrite.Clear();
-            _toFill.Clear();
-            foreach (var workitem in _pool)
-            {
-                _toFill.Enqueue(workitem.index);
-                workitem.ordinal = -1;
-            }
-
-            _firstWriteDone = false;
-            _totalBytesProcessed = 0L;
-            _runningCrc = new Ionic.Crc.CRC32();
-            _isClosed= false;
-            _currentlyFilling = -1;
-            _lastFilled = -1;
-            _lastWritten = -1;
-            _latestCompressed = -1;
-            _outStream = stream;
-        }
-
-
-
-
-        private void EmitPendingBuffers(bool doAll, bool mustWait)
-        {
-            // When combining parallel deflation with a ZipSegmentedStream, it's
-            // possible for the ZSS to throw from within this method.  In that
-            // case, Close/Dispose will be called on this stream, if this stream
-            // is employed within a using or try/finally pair as required. But
-            // this stream is unaware of the pending exception, so the Close()
-            // method invokes this method AGAIN.  This can lead to a deadlock.
-            // Therefore, failfast if re-entering.
-
-            if (emitting) return;
-            emitting = true;
-            if (doAll || mustWait)
-                _newlyCompressedBlob.WaitOne();
-
-            do
-            {
-                int firstSkip = -1;
-                int millisecondsToWait = doAll ? 200 : (mustWait ? -1 : 0);
-                int nextToWrite = -1;
-
-                do
-                {
-                    if (Monitor.TryEnter(_toWrite, millisecondsToWait))
-                    {
-                        nextToWrite = -1;
-                        try
-                        {
-                            if (_toWrite.Count > 0)
-                                nextToWrite = _toWrite.Dequeue();
-                        }
-                        finally
-                        {
-                            Monitor.Exit(_toWrite);
-                        }
-
-                        if (nextToWrite >= 0)
-                        {
-                            WorkItem workitem = _pool[nextToWrite];
-                            if (workitem.ordinal != _lastWritten + 1)
-                            {
-                                // out of order. requeue and try again.
-                                TraceOutput(TraceBits.EmitSkip,
-                                            "Emit     skip     wi({0}) ord({1}) lw({2}) fs({3})",
-                                            workitem.index,
-                                            workitem.ordinal,
-                                            _lastWritten,
-                                            firstSkip);
-
-                                lock(_toWrite)
-                                {
-                                    _toWrite.Enqueue(nextToWrite);
-                                }
-
-                                if (firstSkip == nextToWrite)
-                                {
-                                    // We went around the list once.
-                                    // None of the items in the list is the one we want.
-                                    // Now wait for a compressor to signal again.
-                                    _newlyCompressedBlob.WaitOne();
-                                    firstSkip = -1;
-                                }
-                                else if (firstSkip == -1)
-                                    firstSkip = nextToWrite;
-
-                                continue;
-                            }
-
-                            firstSkip = -1;
-
-                            TraceOutput(TraceBits.EmitBegin,
-                                        "Emit     begin    wi({0}) ord({1})              cba({2})",
-                                        workitem.index,
-                                        workitem.ordinal,
-                                        workitem.compressedBytesAvailable);
-
-                            _outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable);
-                            _runningCrc.Combine(workitem.crc, workitem.inputBytesAvailable);
-                            _totalBytesProcessed += workitem.inputBytesAvailable;
-                            workitem.inputBytesAvailable = 0;
-
-                            TraceOutput(TraceBits.EmitDone,
-                                        "Emit     done     wi({0}) ord({1})              cba({2}) mtw({3})",
-                                        workitem.index,
-                                        workitem.ordinal,
-                                        workitem.compressedBytesAvailable,
-                                        millisecondsToWait);
-
-                            _lastWritten = workitem.ordinal;
-                            _toFill.Enqueue(workitem.index);
-
-                            // don't wait next time through
-                            if (millisecondsToWait == -1) millisecondsToWait = 0;
-                        }
-                    }
-                    else
-                        nextToWrite = -1;
-
-                } while (nextToWrite >= 0);
-
-            //} while (doAll && (_lastWritten != _latestCompressed));
-            } while (doAll && (_lastWritten != _latestCompressed || _lastWritten != _lastFilled));
-
-            emitting = false;
-        }
-
-
-
-#if OLD
-        private void _PerpetualWriterMethod(object state)
-        {
-            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod START");
-
-            try
-            {
-                do
-                {
-                    // wait for the next session
-                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    _sessionReset.WaitOne(begin) PWM");
-                    _sessionReset.WaitOne();
-                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    _sessionReset.WaitOne(done)  PWM");
-
-                    if (_isDisposed) break;
-
-                    TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch    _sessionReset.Reset()        PWM");
-                    _sessionReset.Reset();
-
-                    // repeatedly write buffers as they become ready
-                    WorkItem workitem = null;
-                    Ionic.Zlib.CRC32 c= new Ionic.Zlib.CRC32();
-                    do
-                    {
-                        workitem = _pool[_nextToWrite % _pc];
-                        lock(workitem)
-                        {
-                            if (_noMoreInputForThisSegment)
-                                TraceOutput(TraceBits.Write,
-                                               "Write    drain    wi({0}) stat({1}) canuse({2})  cba({3})",
-                                               workitem.index,
-                                               workitem.status,
-                                               (workitem.status == (int)WorkItem.Status.Compressed),
-                                               workitem.compressedBytesAvailable);
-
-                            do
-                            {
-                                if (workitem.status == (int)WorkItem.Status.Compressed)
-                                {
-                                    TraceOutput(TraceBits.WriteBegin,
-                                                   "Write    begin    wi({0}) stat({1})              cba({2})",
-                                                   workitem.index,
-                                                   workitem.status,
-                                                   workitem.compressedBytesAvailable);
-
-                                    workitem.status = (int)WorkItem.Status.Writing;
-                                    _outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable);
-                                    c.Combine(workitem.crc, workitem.inputBytesAvailable);
-                                    _totalBytesProcessed += workitem.inputBytesAvailable;
-                                    _nextToWrite++;
-                                    workitem.inputBytesAvailable= 0;
-                                    workitem.status = (int)WorkItem.Status.Done;
-
-                                    TraceOutput(TraceBits.WriteDone,
-                                                   "Write    done     wi({0}) stat({1})              cba({2})",
-                                                   workitem.index,
-                                                   workitem.status,
-                                                   workitem.compressedBytesAvailable);
-
-
-                                    Monitor.Pulse(workitem);
-                                    break;
-                                }
-                                else
-                                {
-                                    int wcycles = 0;
-                                    // I've locked a workitem I cannot use.
-                                    // Therefore, wake someone else up, and then release the lock.
-                                    while (workitem.status != (int)WorkItem.Status.Compressed)
-                                    {
-                                        TraceOutput(TraceBits.WriteWait,
-                                                       "Write    waiting  wi({0}) stat({1}) nw({2}) nf({3}) nomore({4})",
-                                                       workitem.index,
-                                                       workitem.status,
-                                                       _nextToWrite, _nextToFill,
-                                                       _noMoreInputForThisSegment );
-
-                                        if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
-                                            break;
-
-                                        wcycles++;
-
-                                        // wake up someone else
-                                        Monitor.Pulse(workitem);
-                                        // release and wait
-                                        Monitor.Wait(workitem);
-
-                                        if (workitem.status == (int)WorkItem.Status.Compressed)
-                                            TraceOutput(TraceBits.WriteWait,
-                                                           "Write    A-OK     wi({0}) stat({1}) iba({2}) cba({3}) cyc({4})",
-                                                           workitem.index,
-                                                           workitem.status,
-                                                           workitem.inputBytesAvailable,
-                                                           workitem.compressedBytesAvailable,
-                                                           wcycles);
-                                    }
-
-                                    if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
-                                        break;
-
-                                }
-                            }
-                            while (true);
-                        }
-
-                        if (_noMoreInputForThisSegment)
-                            TraceOutput(TraceBits.Write,
-                                           "Write    nomore  nw({0}) nf({1}) break({2})",
-                                           _nextToWrite, _nextToFill, (_nextToWrite == _nextToFill));
-
-                        if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
-                            break;
-
-                    } while (true);
-
-
-                    // Finish:
-                    // After writing a series of buffers, closing each one with
-                    // Flush.Sync, we now write the final one as Flush.Finish, and
-                    // then stop.
-                    byte[] buffer = new byte[128];
-                    ZlibCodec compressor = new ZlibCodec();
-                    int rc = compressor.InitializeDeflate(_compressLevel, false);
-                    compressor.InputBuffer = null;
-                    compressor.NextIn = 0;
-                    compressor.AvailableBytesIn = 0;
-                    compressor.OutputBuffer = buffer;
-                    compressor.NextOut = 0;
-                    compressor.AvailableBytesOut = buffer.Length;
-                    rc = compressor.Deflate(FlushType.Finish);
-
-                    if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
-                        throw new Exception("deflating: " + compressor.Message);
-
-                    if (buffer.Length - compressor.AvailableBytesOut > 0)
-                    {
-                        TraceOutput(TraceBits.WriteBegin,
-                                       "Write    begin    flush bytes({0})",
-                                       buffer.Length - compressor.AvailableBytesOut);
-
-                        _outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
-
-                        TraceOutput(TraceBits.WriteBegin,
-                                       "Write    done     flush");
-                    }
-
-                    compressor.EndDeflate();
-
-                    _Crc32 = c.Crc32Result;
-
-                    // signal that writing is complete:
-                    TraceOutput(TraceBits.Synch, "Synch    _writingDone.Set()           PWM");
-                    _writingDone.Set();
-                }
-                while (true);
-            }
-            catch (System.Exception exc1)
-            {
-                lock(_eLock)
-                {
-                    // expose the exception to the main thread
-                    if (_pendingException!=null)
-                        _pendingException = exc1;
-                }
-            }
-
-            TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS");
-        }
-#endif
-
-
-
-
-        private void _DeflateOne(Object wi)
-        {
-            // compress one buffer
-            WorkItem workitem = (WorkItem) wi;
-            try
-            {
-                int myItem = workitem.index;
-                Ionic.Crc.CRC32 crc = new Ionic.Crc.CRC32();
-
-                // calc CRC on the buffer
-                crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable);
-
-                // deflate it
-                DeflateOneSegment(workitem);
-
-                // update status
-                workitem.crc = crc.Crc32Result;
-                TraceOutput(TraceBits.Compress,
-                            "Compress          wi({0}) ord({1}) len({2})",
-                            workitem.index,
-                            workitem.ordinal,
-                            workitem.compressedBytesAvailable
-                            );
-
-                lock(_latestLock)
-                {
-                    if (workitem.ordinal > _latestCompressed)
-                        _latestCompressed = workitem.ordinal;
-                }
-                lock (_toWrite)
-                {
-                    _toWrite.Enqueue(workitem.index);
-                }
-                _newlyCompressedBlob.Set();
-            }
-            catch (System.Exception exc1)
-            {
-                lock(_eLock)
-                {
-                    // expose the exception to the main thread
-                    if (_pendingException!=null)
-                        _pendingException = exc1;
-                }
-            }
-        }
-
-
-
-
-        private bool DeflateOneSegment(WorkItem workitem)
-        {
-            ZlibCodec compressor = workitem.compressor;
-            int rc= 0;
-            compressor.ResetDeflate();
-            compressor.NextIn = 0;
-
-            compressor.AvailableBytesIn = workitem.inputBytesAvailable;
-
-            // step 1: deflate the buffer
-            compressor.NextOut = 0;
-            compressor.AvailableBytesOut =  workitem.compressed.Length;
-            do
-            {
-                compressor.Deflate(FlushType.None);
-            }
-            while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);
-
-            // step 2: flush (sync)
-            rc = compressor.Deflate(FlushType.Sync);
-
-            workitem.compressedBytesAvailable= (int) compressor.TotalBytesOut;
-            return true;
-        }
-
-
-        [System.Diagnostics.ConditionalAttribute("Trace")]
-        private void TraceOutput(TraceBits bits, string format, params object[] varParams)
-        {
-            if ((bits & _DesiredTrace) != 0)
-            {
-                lock(_outputLock)
-                {
-                    int tid = Thread.CurrentThread.GetHashCode();
-#if !SILVERLIGHT
-                    Console.ForegroundColor = (ConsoleColor) (tid % 8 + 8);
-#endif
-                    Console.Write("{0:000} PDOS ", tid);
-                    Console.WriteLine(format, varParams);
-#if !SILVERLIGHT
-                    Console.ResetColor();
-#endif
-                }
-            }
-        }
-
-
-        // used only when Trace is defined
-        [Flags]
-        enum TraceBits : uint
-        {
-            None         = 0,
-            NotUsed1     = 1,
-            EmitLock     = 2,
-            EmitEnter    = 4,    // enter _EmitPending
-            EmitBegin    = 8,    // begin to write out
-            EmitDone     = 16,   // done writing out
-            EmitSkip     = 32,   // writer skipping a workitem
-            EmitAll      = 58,   // All Emit flags
-            Flush        = 64,
-            Lifecycle    = 128,  // constructor/disposer
-            Session      = 256,  // Close/Reset
-            Synch        = 512,  // thread synchronization
-            Instance     = 1024, // instance settings
-            Compress     = 2048,  // compress task
-            Write        = 4096,    // filling buffers, when caller invokes Write()
-            WriteEnter   = 8192,    // upon entry to Write()
-            WriteTake    = 16384,    // on _toFill.Take()
-            All          = 0xffffffff,
-        }
-
-
-
-        /// <summary>
-        /// Indicates whether the stream supports Seek operations.
-        /// </summary>
-        /// <remarks>
-        /// Always returns false.
-        /// </remarks>
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-
-        /// <summary>
-        /// Indicates whether the stream supports Read operations.
-        /// </summary>
-        /// <remarks>
-        /// Always returns false.
-        /// </remarks>
-        public override bool CanRead
-        {
-            get {return false;}
-        }
-
-        /// <summary>
-        /// Indicates whether the stream supports Write operations.
-        /// </summary>
-        /// <remarks>
-        /// Returns true if the provided stream is writable.
-        /// </remarks>
-        public override bool CanWrite
-        {
-            get { return _outStream.CanWrite; }
-        }
-
-        /// <summary>
-        /// Reading this property always throws a NotSupportedException.
-        /// </summary>
-        public override long Length
-        {
-            get { throw new NotSupportedException(); }
-        }
-
-        /// <summary>
-        /// Returns the current position of the output stream.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     Because the output gets written by a background thread,
-        ///     the value may change asynchronously.  Setting this
-        ///     property always throws a NotSupportedException.
-        ///   </para>
-        /// </remarks>
-        public override long Position
-        {
-            get { return _outStream.Position; }
-            set { throw new NotSupportedException(); }
-        }
-
-        /// <summary>
-        /// This method always throws a NotSupportedException.
-        /// </summary>
-        /// <param name="buffer">
-        ///   The buffer into which data would be read, IF THIS METHOD
-        ///   ACTUALLY DID ANYTHING.
-        /// </param>
-        /// <param name="offset">
-        ///   The offset within that data array at which to insert the
-        ///   data that is read, IF THIS METHOD ACTUALLY DID
-        ///   ANYTHING.
-        /// </param>
-        /// <param name="count">
-        ///   The number of bytes to write, IF THIS METHOD ACTUALLY DID
-        ///   ANYTHING.
-        /// </param>
-        /// <returns>nothing.</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        /// This method always throws a NotSupportedException.
-        /// </summary>
-        /// <param name="offset">
-        ///   The offset to seek to....
-        ///   IF THIS METHOD ACTUALLY DID ANYTHING.
-        /// </param>
-        /// <param name="origin">
-        ///   The reference specifying how to apply the offset....  IF
-        ///   THIS METHOD ACTUALLY DID ANYTHING.
-        /// </param>
-        /// <returns>nothing. It always throws.</returns>
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        /// This method always throws a NotSupportedException.
-        /// </summary>
-        /// <param name="value">
-        ///   The new value for the stream length....  IF
-        ///   THIS METHOD ACTUALLY DID ANYTHING.
-        /// </param>
-        public override void SetLength(long value)
-        {
-            throw new NotSupportedException();
-        }
-
-    }
-
-}
-
-
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/Tree.cs b/EPPlus/Packaging/DotNetZip/Zlib/Tree.cs
deleted file mode 100644
index c411d08..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/Tree.cs
+++ /dev/null
@@ -1,423 +0,0 @@
-// Tree.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.  
-// 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: <2009-October-28 13:29:50>
-//
-// ------------------------------------------------------------------
-//
-// This module defines classes for zlib compression and
-// decompression. This code is derived from the jzlib implementation of
-// zlib. In keeping with the license for jzlib, the copyright to that
-// code is below.
-//
-// ------------------------------------------------------------------
-// 
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 
-// 2. Redistributions in binary form must reproduce the above copyright 
-// notice, this list of conditions and the following disclaimer in 
-// the documentation and/or other materials provided with the distribution.
-// 
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// -----------------------------------------------------------------------
-//
-// This program is based on zlib-1.1.3; credit to authors
-// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-// and contributors of zlib.
-//
-// -----------------------------------------------------------------------
-
-
-using System;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    sealed class Tree
-    {
-        private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
-                
-        // extra bits for each length code
-        internal static readonly int[] ExtraLengthBits = new int[]
-        {
-            0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-            3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
-        };
-                
-        // extra bits for each distance code
-        internal static readonly int[] ExtraDistanceBits = new int[]
-        {
-            0, 0, 0, 0, 1, 1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,
-            7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
-        };
-                
-        // extra bits for each bit length code
-        internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
-                
-        internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-                
-                
-        // The lengths of the bit length codes are sent in order of decreasing
-        // probability, to avoid transmitting the lengths for unused bit
-        // length codes.
-                
-        internal const int Buf_size = 8 * 2;
-                
-        // see definition of array dist_code below
-        //internal const int DIST_CODE_LEN = 512;
-                
-        private static readonly sbyte[] _dist_code = new sbyte[]
-        {
-            0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7, 
-            8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9,
-            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
-            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 
-            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 
-            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 
-            13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
-            13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-            15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-            15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-            15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-            15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-            0,   0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 
-            22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 
-            24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
-            25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
-            26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
-            26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
-            27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
-            27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 
-            28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
-            28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
-            28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
-            28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
-            29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 
-            29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 
-            29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 
-            29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-        };
-                
-        internal static readonly sbyte[] LengthCode = new sbyte[]
-        {
-            0,   1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11,
-            12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
-            16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
-            18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
-            20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-            21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-            22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-            23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-            24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-            24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-            25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-            25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-            26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-            26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-            27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-            27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-        };
-                
-
-        internal static readonly int[] LengthBase = new int[]
-        {
-            0,   1,  2,  3,  4,  5,  6,   7,   8,  10,  12,  14, 16, 20, 24, 28,
-            32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0
-        };
-                
-
-        internal static readonly int[] DistanceBase = new int[]
-        {
-            0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
-            256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-        };
-
-        
-        /// <summary>
-        /// Map from a distance to a distance code.
-        /// </summary>
-        /// <remarks> 
-        /// No side effects. _dist_code[256] and _dist_code[257] are never used.
-        /// </remarks>
-        internal static int DistanceCode(int dist)
-        {
-            return (dist < 256)
-                ? _dist_code[dist]
-                : _dist_code[256 + SharedUtils.URShift(dist, 7)];
-        }
-
-        internal short[] dyn_tree; // the dynamic tree
-        internal int max_code; // largest code with non zero frequency
-        internal StaticTree staticTree; // the corresponding static tree
-                
-        // Compute the optimal bit lengths for a tree and update the total bit length
-        // for the current block.
-        // IN assertion: the fields freq and dad are set, heap[heap_max] and
-        //    above are the tree nodes sorted by increasing frequency.
-        // OUT assertions: the field len is set to the optimal bit length, the
-        //     array bl_count contains the frequencies for each bit length.
-        //     The length opt_len is updated; static_len is also updated if stree is
-        //     not null.
-        internal void  gen_bitlen(DeflateManager s)
-        {
-            short[] tree = dyn_tree;
-            short[] stree = staticTree.treeCodes;
-            int[] extra = staticTree.extraBits;
-            int base_Renamed = staticTree.extraBase;
-            int max_length = staticTree.maxLength;
-            int h; // heap index
-            int n, m; // iterate over the tree elements
-            int bits; // bit length
-            int xbits; // extra bits
-            short f; // frequency
-            int overflow = 0; // number of elements with bit length too large
-                        
-            for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++)
-                s.bl_count[bits] = 0;
-                        
-            // In a first pass, compute the optimal bit lengths (which may
-            // overflow in the case of the bit length tree).
-            tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
-                        
-            for (h = s.heap_max + 1; h < HEAP_SIZE; h++)
-            {
-                n = s.heap[h];
-                bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
-                if (bits > max_length)
-                {
-                    bits = max_length; overflow++;
-                }
-                tree[n * 2 + 1] = (short) bits;
-                // We overwrite tree[n*2+1] which is no longer needed
-                                
-                if (n > max_code)
-                    continue; // not a leaf node
-                                
-                s.bl_count[bits]++;
-                xbits = 0;
-                if (n >= base_Renamed)
-                    xbits = extra[n - base_Renamed];
-                f = tree[n * 2];
-                s.opt_len += f * (bits + xbits);
-                if (stree != null)
-                    s.static_len += f * (stree[n * 2 + 1] + xbits);
-            }
-            if (overflow == 0)
-                return ;
-                        
-            // This happens for example on obj2 and pic of the Calgary corpus
-            // Find the first bit length which could increase:
-            do 
-            {
-                bits = max_length - 1;
-                while (s.bl_count[bits] == 0)
-                    bits--;
-                s.bl_count[bits]--; // move one leaf down the tree
-                s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother
-                s.bl_count[max_length]--;
-                // The brother of the overflow item also moves one step up,
-                // but this does not affect bl_count[max_length]
-                overflow -= 2;
-            }
-            while (overflow > 0);
-                        
-            for (bits = max_length; bits != 0; bits--)
-            {
-                n = s.bl_count[bits];
-                while (n != 0)
-                {
-                    m = s.heap[--h];
-                    if (m > max_code)
-                        continue;
-                    if (tree[m * 2 + 1] != bits)
-                    {
-                        s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]);
-                        tree[m * 2 + 1] = (short) bits;
-                    }
-                    n--;
-                }
-            }
-        }
-                
-        // Construct one Huffman tree and assigns the code bit strings and lengths.
-        // Update the total bit length for the current block.
-        // IN assertion: the field freq is set for all tree elements.
-        // OUT assertions: the fields len and code are set to the optimal bit length
-        //     and corresponding code. The length opt_len is updated; static_len is
-        //     also updated if stree is not null. The field max_code is set.
-        internal void  build_tree(DeflateManager s)
-        {
-            short[] tree  = dyn_tree;
-            short[] stree = staticTree.treeCodes;
-            int elems     = staticTree.elems;
-            int n, m;            // iterate over heap elements
-            int max_code  = -1;  // largest code with non zero frequency
-            int node;            // new node being created
-                        
-            // Construct the initial heap, with least frequent element in
-            // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-            // heap[0] is not used.
-            s.heap_len = 0;
-            s.heap_max = HEAP_SIZE;
-                        
-            for (n = 0; n < elems; n++)
-            {
-                if (tree[n * 2] != 0)
-                {
-                    s.heap[++s.heap_len] = max_code = n;
-                    s.depth[n] = 0;
-                }
-                else
-                {
-                    tree[n * 2 + 1] = 0;
-                }
-            }
-                        
-            // The pkzip format requires that at least one distance code exists,
-            // and that at least one bit should be sent even if there is only one
-            // possible code. So to avoid special checks later on we force at least
-            // two codes of non zero frequency.
-            while (s.heap_len < 2)
-            {
-                node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0);
-                tree[node * 2] = 1;
-                s.depth[node] = 0;
-                s.opt_len--;
-                if (stree != null)
-                    s.static_len -= stree[node * 2 + 1];
-                // node is 0 or 1 so it does not have extra bits
-            }
-            this.max_code = max_code;
-                        
-            // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-            // establish sub-heaps of increasing lengths:
-                        
-            for (n = s.heap_len / 2; n >= 1; n--)
-                s.pqdownheap(tree, n);
-                        
-            // Construct the Huffman tree by repeatedly combining the least two
-            // frequent nodes.
-                        
-            node = elems; // next internal node of the tree
-            do 
-            {
-                // n = node of least frequency
-                n = s.heap[1];
-                s.heap[1] = s.heap[s.heap_len--];
-                s.pqdownheap(tree, 1);
-                m = s.heap[1]; // m = node of next least frequency
-                                
-                s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
-                s.heap[--s.heap_max] = m;
-                                
-                // Create a new node father of n and m
-                tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2]));
-                s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1);
-                tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node;
-                                
-                // and insert the new node in the heap
-                s.heap[1] = node++;
-                s.pqdownheap(tree, 1);
-            }
-            while (s.heap_len >= 2);
-                        
-            s.heap[--s.heap_max] = s.heap[1];
-                        
-            // At this point, the fields freq and dad are set. We can now
-            // generate the bit lengths.
-                        
-            gen_bitlen(s);
-                        
-            // The field len is now set, we can generate the bit codes
-            gen_codes(tree, max_code, s.bl_count);
-        }
-                
-        // Generate the codes for a given tree and bit counts (which need not be
-        // optimal).
-        // IN assertion: the array bl_count contains the bit length statistics for
-        // the given tree and the field len is set for all tree elements.
-        // OUT assertion: the field code is set for all tree elements of non
-        //     zero code length.
-        internal static void  gen_codes(short[] tree, int max_code, short[] bl_count)
-        {
-            short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length
-            short code = 0; // running code value
-            int bits; // bit index
-            int n; // code index
-                        
-            // The distribution counts are first used to generate the code values
-            // without bit reversal.
-            for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++)
-                unchecked {
-                    next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1);
-                }
-                        
-            // Check that the bit counts in bl_count are consistent. The last code
-            // must be all ones.
-            //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-            //        "inconsistent bit counts");
-            //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-                        
-            for (n = 0; n <= max_code; n++)
-            {
-                int len = tree[n * 2 + 1];
-                if (len == 0)
-                    continue;
-                // Now reverse the bits
-                tree[n * 2] =  unchecked((short) (bi_reverse(next_code[len]++, len)));
-            }
-        }
-                
-        // Reverse the first len bits of a code, using straightforward code (a faster
-        // method would use a table)
-        // IN assertion: 1 <= len <= 15
-        internal static int bi_reverse(int code, int len)
-        {
-            int res = 0;
-            do 
-            {
-                res |= code & 1;
-                code >>= 1; //SharedUtils.URShift(code, 1);
-                res <<= 1;
-            }
-            while (--len > 0);
-            return res >> 1;
-        }
-    }
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/Zlib.cs b/EPPlus/Packaging/DotNetZip/Zlib/Zlib.cs
deleted file mode 100644
index 06d8e7d..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/Zlib.cs
+++ /dev/null
@@ -1,546 +0,0 @@
-// Zlib.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation.
-// 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: <2011-August-03 19:52:28>
-//
-// ------------------------------------------------------------------
-//
-// This module defines classes for ZLIB compression and
-// decompression. This code is derived from the jzlib implementation of
-// zlib, but significantly modified.  The object model is not the same,
-// and many of the behaviors are new or different.  Nonetheless, in
-// keeping with the license for jzlib, the copyright to that code is
-// included below.
-//
-// ------------------------------------------------------------------
-//
-// The following notice applies to jzlib:
-//
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the distribution.
-//
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// -----------------------------------------------------------------------
-//
-// jzlib is based on zlib-1.1.3.
-//
-// The following notice applies to zlib:
-//
-// -----------------------------------------------------------------------
-//
-// Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
-//
-//   The ZLIB software is provided 'as-is', without any express or implied
-//   warranty.  In no event will the authors be held liable for any damages
-//   arising from the use of this software.
-//
-//   Permission is granted to anyone to use this software for any purpose,
-//   including commercial applications, and to alter it and redistribute it
-//   freely, subject to the following restrictions:
-//
-//   1. The origin of this software must not be misrepresented; you must not
-//      claim that you wrote the original software. If you use this software
-//      in a product, an acknowledgment in the product documentation would be
-//      appreciated but is not required.
-//   2. Altered source versions must be plainly marked as such, and must not be
-//      misrepresented as being the original software.
-//   3. This notice may not be removed or altered from any source distribution.
-//
-//   Jean-loup Gailly jloup@gzip.org
-//   Mark Adler madler@alumni.caltech.edu
-//
-// -----------------------------------------------------------------------
-
-
-
-using System;
-using Interop=System.Runtime.InteropServices;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-
-    /// <summary>
-    /// Describes how to flush the current deflate operation.
-    /// </summary>
-    /// <remarks>
-    /// The different FlushType values are useful when using a Deflate in a streaming application.
-    /// </remarks>
-    public enum FlushType
-    {
-        /// <summary>No flush at all.</summary>
-        None = 0,
-
-        /// <summary>Closes the current block, but doesn't flush it to
-        /// the output. Used internally only in hypothetical
-        /// scenarios.  This was supposed to be removed by Zlib, but it is
-        /// still in use in some edge cases.
-        /// </summary>
-        Partial,
-
-        /// <summary>
-        /// Use this during compression to specify that all pending output should be
-        /// flushed to the output buffer and the output should be aligned on a byte
-        /// boundary.  You might use this in a streaming communication scenario, so that
-        /// the decompressor can get all input data available so far.  When using this
-        /// with a ZlibCodec, <c>AvailableBytesIn</c> will be zero after the call if
-        /// enough output space has been provided before the call.  Flushing will
-        /// degrade compression and so it should be used only when necessary.
-        /// </summary>
-        Sync,
-
-        /// <summary>
-        /// Use this during compression to specify that all output should be flushed, as
-        /// with <c>FlushType.Sync</c>, but also, the compression state should be reset
-        /// so that decompression can restart from this point if previous compressed
-        /// data has been damaged or if random access is desired.  Using
-        /// <c>FlushType.Full</c> too often can significantly degrade the compression.
-        /// </summary>
-        Full,
-
-        /// <summary>Signals the end of the compression/decompression stream.</summary>
-        Finish,
-    }
-
-
-    /// <summary>
-    /// The compression level to be used when using a DeflateStream or ZlibStream with CompressionMode.Compress.
-    /// </summary>
-    public enum CompressionLevel
-    {
-        /// <summary>
-        /// None means that the data will be simply stored, with no change at all.
-        /// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None
-        /// cannot be opened with the default zip reader. Use a different CompressionLevel.
-        /// </summary>
-        None= 0,
-        /// <summary>
-        /// Same as None.
-        /// </summary>
-        Level0 = 0,
-
-        /// <summary>
-        /// The fastest but least effective compression.
-        /// </summary>
-        BestSpeed = 1,
-
-        /// <summary>
-        /// A synonym for BestSpeed.
-        /// </summary>
-        Level1 = 1,
-
-        /// <summary>
-        /// A little slower, but better, than level 1.
-        /// </summary>
-        Level2 = 2,
-
-        /// <summary>
-        /// A little slower, but better, than level 2.
-        /// </summary>
-        Level3 = 3,
-
-        /// <summary>
-        /// A little slower, but better, than level 3.
-        /// </summary>
-        Level4 = 4,
-
-        /// <summary>
-        /// A little slower than level 4, but with better compression.
-        /// </summary>
-        Level5 = 5,
-
-        /// <summary>
-        /// The default compression level, with a good balance of speed and compression efficiency.
-        /// </summary>
-        Default = 6,
-        /// <summary>
-        /// A synonym for Default.
-        /// </summary>
-        Level6 = 6,
-
-        /// <summary>
-        /// Pretty good compression!
-        /// </summary>
-        Level7 = 7,
-
-        /// <summary>
-        ///  Better compression than Level7!
-        /// </summary>
-        Level8 = 8,
-
-        /// <summary>
-        /// The "best" compression, where best means greatest reduction in size of the input data stream.
-        /// This is also the slowest compression.
-        /// </summary>
-        BestCompression = 9,
-
-        /// <summary>
-        /// A synonym for BestCompression.
-        /// </summary>
-        Level9 = 9,
-    }
-
-    /// <summary>
-    /// Describes options for how the compression algorithm is executed.  Different 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.
-    /// </summary>
-    public enum CompressionStrategy
-    {
-        /// <summary>
-        /// The default strategy is probably the best for normal data.
-        /// </summary>
-        Default = 0,
-
-        /// <summary>
-        /// The <c>Filtered</c> strategy is intended to be used most effectively with data produced by a
-        /// filter or predictor.  By this definition, filtered data consists mostly of small
-        /// values with a somewhat random distribution.  In this case, the compression algorithm
-        /// is tuned to compress them better.  The effect of <c>Filtered</c> is to force more Huffman
-        /// coding and less string matching; it is a half-step between <c>Default</c> and <c>HuffmanOnly</c>.
-        /// </summary>
-        Filtered = 1,
-
-        /// <summary>
-        /// Using <c>HuffmanOnly</c> will force the compressor to do Huffman encoding only, with no
-        /// string matching.
-        /// </summary>
-        HuffmanOnly = 2,
-    }
-
-
-    /// <summary>
-    /// An enum to specify the direction of transcoding - whether to compress or decompress.
-    /// </summary>
-    public enum CompressionMode
-    {
-        /// <summary>
-        /// Used to specify that the stream should compress the data.
-        /// </summary>
-        Compress= 0,
-        /// <summary>
-        /// Used to specify that the stream should decompress the data.
-        /// </summary>
-        Decompress = 1,
-    }
-
-
-    /// <summary>
-    /// A general purpose exception class for exceptions in the Zlib library.
-    /// </summary>
-    [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")]
-    public class ZlibException : System.Exception
-    {
-        /// <summary>
-        /// The ZlibException class captures exception information generated
-        /// by the Zlib library.
-        /// </summary>
-        public ZlibException()
-            : base()
-        {
-        }
-
-        /// <summary>
-        /// This ctor collects a message attached to the exception.
-        /// </summary>
-        /// <param name="s">the message for the exception.</param>
-        public ZlibException(System.String s)
-            : base(s)
-        {
-        }
-    }
-
-
-    internal class SharedUtils
-    {
-        /// <summary>
-        /// Performs an unsigned bitwise right shift with the specified number
-        /// </summary>
-        /// <param name="number">Number to operate on</param>
-        /// <param name="bits">Ammount of bits to shift</param>
-        /// <returns>The resulting number from the shift operation</returns>
-        public static int URShift(int number, int bits)
-        {
-            return (int)((uint)number >> bits);
-        }
-
-#if NOT
-        /// <summary>
-        /// Performs an unsigned bitwise right shift with the specified number
-        /// </summary>
-        /// <param name="number">Number to operate on</param>
-        /// <param name="bits">Ammount of bits to shift</param>
-        /// <returns>The resulting number from the shift operation</returns>
-        public static long URShift(long number, int bits)
-        {
-            return (long) ((UInt64)number >> bits);
-        }
-#endif
-
-        /// <summary>
-        ///   Reads a number of characters from the current source TextReader and writes
-        ///   the data to the target array at the specified index.
-        /// </summary>
-        ///
-        /// <param name="sourceTextReader">The source TextReader to read from</param>
-        /// <param name="target">Contains the array of characteres read from the source TextReader.</param>
-        /// <param name="start">The starting index of the target array.</param>
-        /// <param name="count">The maximum number of characters to read from the source TextReader.</param>
-        ///
-        /// <returns>
-        ///   The number of characters read. The number will be less than or equal to
-        ///   count depending on the data available in the source TextReader. Returns -1
-        ///   if the end of the stream is reached.
-        /// </returns>
-        public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count)
-        {
-            // Returns 0 bytes if not enough space in target
-            if (target.Length == 0) return 0;
-
-            char[] charArray = new char[target.Length];
-            int bytesRead = sourceTextReader.Read(charArray, start, count);
-
-            // Returns -1 if EOF
-            if (bytesRead == 0) return -1;
-
-            for (int index = start; index < start + bytesRead; index++)
-                target[index] = (byte)charArray[index];
-
-            return bytesRead;
-        }
-
-
-        internal static byte[] ToByteArray(System.String sourceString)
-        {
-            return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString);
-        }
-
-
-        internal static char[] ToCharArray(byte[] byteArray)
-        {
-            return System.Text.UTF8Encoding.UTF8.GetChars(byteArray);
-        }
-    }
-
-    internal static class InternalConstants
-    {
-        internal static readonly int MAX_BITS     = 15;
-        internal static readonly int BL_CODES     = 19;
-        internal static readonly int D_CODES      = 30;
-        internal static readonly int LITERALS     = 256;
-        internal static readonly int LENGTH_CODES = 29;
-        internal static readonly int L_CODES      = (LITERALS + 1 + LENGTH_CODES);
-
-        // Bit length codes must not exceed MAX_BL_BITS bits
-        internal static readonly int MAX_BL_BITS  = 7;
-
-        // repeat previous bit length 3-6 times (2 bits of repeat count)
-        internal static readonly int REP_3_6      = 16;
-
-        // repeat a zero length 3-10 times  (3 bits of repeat count)
-        internal static readonly int REPZ_3_10    = 17;
-
-        // repeat a zero length 11-138 times  (7 bits of repeat count)
-        internal static readonly int REPZ_11_138  = 18;
-
-    }
-
-    internal sealed class StaticTree
-    {
-        internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] {
-            12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8,
-            28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8,
-             2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8,
-            18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8,
-            10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8,
-            26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8,
-             6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
-            22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8,
-            14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8,
-            30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8,
-             1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8,
-            17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8,
-             9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8,
-            25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8,
-             5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8,
-            21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8,
-            13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8,
-            29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8,
-            19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
-            51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9,
-            11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9,
-            43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9,
-            27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9,
-            59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9,
-             7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9,
-            39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9,
-            23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9,
-            55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9,
-            15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9,
-            47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9,
-            31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9,
-            63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9,
-             0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7,
-             8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7,
-             4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7,
-             3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8
-        };
-
-        internal static readonly short[] distTreeCodes = new short[] {
-            0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5,
-            2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5,
-            1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5,
-            3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 };
-
-        internal static readonly StaticTree Literals;
-        internal static readonly StaticTree Distances;
-        internal static readonly StaticTree BitLengths;
-
-        internal short[] treeCodes; // static tree or null
-        internal int[] extraBits;   // extra bits for each code or null
-        internal int extraBase;     // base index for extra_bits
-        internal int elems;         // max number of elements in the tree
-        internal int maxLength;     // max bit length for the codes
-
-        private StaticTree(short[] treeCodes, int[] extraBits, int extraBase, int elems, int maxLength)
-        {
-            this.treeCodes = treeCodes;
-            this.extraBits = extraBits;
-            this.extraBase = extraBase;
-            this.elems = elems;
-            this.maxLength = maxLength;
-        }
-        static StaticTree()
-        {
-            Literals = new StaticTree(lengthAndLiteralsTreeCodes, Tree.ExtraLengthBits, InternalConstants.LITERALS + 1, InternalConstants.L_CODES, InternalConstants.MAX_BITS);
-            Distances = new StaticTree(distTreeCodes, Tree.ExtraDistanceBits, 0, InternalConstants.D_CODES, InternalConstants.MAX_BITS);
-            BitLengths = new StaticTree(null, Tree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS);
-        }
-    }
-
-
-
-    /// <summary>
-    /// Computes an Adler-32 checksum.
-    /// </summary>
-    /// <remarks>
-    /// The Adler checksum is similar to a CRC checksum, but faster to compute, though less
-    /// reliable.  It is used in producing RFC1950 compressed streams.  The Adler checksum
-    /// is a required part of the "ZLIB" standard.  Applications will almost never need to
-    /// use this class directly.
-    /// </remarks>
-    ///
-    /// <exclude/>
-    public sealed class Adler
-    {
-        // largest prime smaller than 65536
-        private static readonly uint BASE = 65521;
-        // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
-        private static readonly int NMAX = 5552;
-
-
-#pragma warning disable 3001
-#pragma warning disable 3002
-
-        /// <summary>
-        ///   Calculates the Adler32 checksum.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     This is used within ZLIB.  You probably don't need to use this directly.
-        ///   </para>
-        /// </remarks>
-        /// <example>
-        ///    To compute an Adler32 checksum on a byte array:
-        ///  <code>
-        ///    var adler = Adler.Adler32(0, null, 0, 0);
-        ///    adler = Adler.Adler32(adler, buffer, index, length);
-        ///  </code>
-        /// </example>
-        public static uint Adler32(uint adler, byte[] buf, int index, int len)
-        {
-            if (buf == null)
-                return 1;
-
-            uint s1 = (uint) (adler & 0xffff);
-            uint s2 = (uint) ((adler >> 16) & 0xffff);
-
-            while (len > 0)
-            {
-                int k = len < NMAX ? len : NMAX;
-                len -= k;
-                while (k >= 16)
-                {
-                    //s1 += (buf[index++] & 0xff); s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    s1 += buf[index++]; s2 += s1;
-                    k -= 16;
-                }
-                if (k != 0)
-                {
-                    do
-                    {
-                        s1 += buf[index++];
-                        s2 += s1;
-                    }
-                    while (--k != 0);
-                }
-                s1 %= BASE;
-                s2 %= BASE;
-            }
-            return (uint)((s2 << 16) | s1);
-        }
-#pragma warning restore 3001
-#pragma warning restore 3002
-
-    }
-
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/ZlibBaseStream.cs b/EPPlus/Packaging/DotNetZip/Zlib/ZlibBaseStream.cs
deleted file mode 100644
index 3215e3a..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/ZlibBaseStream.cs
+++ /dev/null
@@ -1,628 +0,0 @@
-// ZlibBaseStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
-// 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-August-06 21:22:38>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZlibBaseStream class, which is an intnernal
-// base class for DeflateStream, ZlibStream and GZipStream.
-//
-// ------------------------------------------------------------------
-
-using OfficeOpenXml.Packaging.Ionic.Crc;
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-
-    internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 }
-
-    internal class ZlibBaseStream : System.IO.Stream
-    {
-        protected internal ZlibCodec _z = null; // deferred init... new ZlibCodec();
-
-        protected internal StreamMode _streamMode = StreamMode.Undefined;
-        protected internal FlushType _flushMode;
-        protected internal ZlibStreamFlavor _flavor;
-        protected internal CompressionMode _compressionMode;
-        protected internal CompressionLevel _level;
-        protected internal bool _leaveOpen;
-        protected internal byte[] _workingBuffer;
-        protected internal int _bufferSize = ZlibConstants.WorkingBufferSizeDefault;
-        protected internal byte[] _buf1 = new byte[1];
-
-        protected internal System.IO.Stream _stream;
-        protected internal CompressionStrategy Strategy = CompressionStrategy.Default;
-
-        // workitem 7159
-        CRC32 crc;
-        protected internal string _GzipFileName;
-        protected internal string _GzipComment;
-        protected internal DateTime _GzipMtime;
-        protected internal int _gzipHeaderByteCount;
-
-        internal int Crc32 { get { if (crc == null) return 0; return crc.Crc32Result; } }
-
-        public ZlibBaseStream(System.IO.Stream stream,
-                              CompressionMode compressionMode,
-                              CompressionLevel level,
-                              ZlibStreamFlavor flavor,
-                              bool leaveOpen)
-            : base()
-        {
-            this._flushMode = FlushType.None;
-            //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
-            this._stream = stream;
-            this._leaveOpen = leaveOpen;
-            this._compressionMode = compressionMode;
-            this._flavor = flavor;
-            this._level = level;
-            // workitem 7159
-            if (flavor == ZlibStreamFlavor.GZIP)
-            {
-                this.crc = new Ionic.Crc.CRC32();
-            }
-        }
-
-
-        protected internal bool _wantCompress
-        {
-            get
-            {
-                return (this._compressionMode == CompressionMode.Compress);
-            }
-        }
-
-        private ZlibCodec z
-        {
-            get
-            {
-                if (_z == null)
-                {
-                    bool wantRfc1950Header = (this._flavor == ZlibStreamFlavor.ZLIB);
-                    _z = new ZlibCodec();
-                    if (this._compressionMode == CompressionMode.Decompress)
-                    {
-                        _z.InitializeInflate(wantRfc1950Header);
-                    }
-                    else
-                    {
-                        _z.Strategy = Strategy;
-                        _z.InitializeDeflate(this._level, wantRfc1950Header);
-                    }
-                }
-                return _z;
-            }
-        }
-
-
-
-        private byte[] workingBuffer
-        {
-            get
-            {
-                if (_workingBuffer == null)
-                    _workingBuffer = new byte[_bufferSize];
-                return _workingBuffer;
-            }
-        }
-
-
-
-        public override void Write(System.Byte[] buffer, int offset, int count)
-        {
-            // workitem 7159
-            // calculate the CRC on the unccompressed data  (before writing)
-            if (crc != null)
-                crc.SlurpBlock(buffer, offset, count);
-
-            if (_streamMode == StreamMode.Undefined)
-                _streamMode = StreamMode.Writer;
-            else if (_streamMode != StreamMode.Writer)
-                throw new ZlibException("Cannot Write after Reading.");
-
-            if (count == 0)
-                return;
-
-            // first reference of z property will initialize the private var _z
-            z.InputBuffer = buffer;
-            _z.NextIn = offset;
-            _z.AvailableBytesIn = count;
-            bool done = false;
-            do
-            {
-                _z.OutputBuffer = workingBuffer;
-                _z.NextOut = 0;
-                _z.AvailableBytesOut = _workingBuffer.Length;
-                int rc = (_wantCompress)
-                    ? _z.Deflate(_flushMode)
-                    : _z.Inflate(_flushMode);
-                if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
-                    throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message);
-
-                //if (_workingBuffer.Length - _z.AvailableBytesOut > 0)
-                _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut);
-
-                done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0;
-
-                // If GZIP and de-compress, we're done when 8 bytes remain.
-                if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress)
-                    done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0);
-
-            }
-            while (!done);
-        }
-
-
-
-        private void finish()
-        {
-            if (_z == null) return;
-
-            if (_streamMode == StreamMode.Writer)
-            {
-                bool done = false;
-                do
-                {
-                    _z.OutputBuffer = workingBuffer;
-                    _z.NextOut = 0;
-                    _z.AvailableBytesOut = _workingBuffer.Length;
-                    int rc = (_wantCompress)
-                        ? _z.Deflate(FlushType.Finish)
-                        : _z.Inflate(FlushType.Finish);
-
-                    if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
-                    {
-                        string verb = (_wantCompress ? "de" : "in") + "flating";
-                        if (_z.Message == null)
-                            throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc));
-                        else
-                            throw new ZlibException(verb + ": " + _z.Message);
-                    }
-
-                    if (_workingBuffer.Length - _z.AvailableBytesOut > 0)
-                    {
-                        _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut);
-                    }
-
-                    done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0;
-                    // If GZIP and de-compress, we're done when 8 bytes remain.
-                    if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress)
-                        done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0);
-
-                }
-                while (!done);
-
-                Flush();
-
-                // workitem 7159
-                if (_flavor == ZlibStreamFlavor.GZIP)
-                {
-                    if (_wantCompress)
-                    {
-                        // Emit the GZIP trailer: CRC32 and  size mod 2^32
-                        int c1 = crc.Crc32Result;
-                        _stream.Write(BitConverter.GetBytes(c1), 0, 4);
-                        int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
-                        _stream.Write(BitConverter.GetBytes(c2), 0, 4);
-                    }
-                    else
-                    {
-                        throw new ZlibException("Writing with decompression is not supported.");
-                    }
-                }
-            }
-            // workitem 7159
-            else if (_streamMode == StreamMode.Reader)
-            {
-                if (_flavor == ZlibStreamFlavor.GZIP)
-                {
-                    if (!_wantCompress)
-                    {
-                        // workitem 8501: handle edge case (decompress empty stream)
-                        if (_z.TotalBytesOut == 0L)
-                            return;
-
-                        // Read and potentially verify the GZIP trailer:
-                        // CRC32 and size mod 2^32
-                        byte[] trailer = new byte[8];
-
-                        // workitems 8679 & 12554
-                        if (_z.AvailableBytesIn < 8)
-                        {
-                            // Make sure we have read to the end of the stream
-                            Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, _z.AvailableBytesIn);
-                            int bytesNeeded = 8 - _z.AvailableBytesIn;
-                            int bytesRead = _stream.Read(trailer,
-                                                         _z.AvailableBytesIn,
-                                                         bytesNeeded);
-                            if (bytesNeeded != bytesRead)
-                            {
-                                throw new ZlibException(String.Format("Missing or incomplete GZIP trailer. Expected 8 bytes, got {0}.",
-                                                                      _z.AvailableBytesIn + bytesRead));
-                            }
-                        }
-                        else
-                        {
-                            Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length);
-                        }
-
-                        Int32 crc32_expected = BitConverter.ToInt32(trailer, 0);
-                        Int32 crc32_actual = crc.Crc32Result;
-                        Int32 isize_expected = BitConverter.ToInt32(trailer, 4);
-                        Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF);
-
-                        if (crc32_actual != crc32_expected)
-                            throw new ZlibException(String.Format("Bad CRC32 in GZIP trailer. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected));
-
-                        if (isize_actual != isize_expected)
-                            throw new ZlibException(String.Format("Bad size in GZIP trailer. (actual({0})!=expected({1}))", isize_actual, isize_expected));
-
-                    }
-                    else
-                    {
-                        throw new ZlibException("Reading with compression is not supported.");
-                    }
-                }
-            }
-        }
-
-
-        private void end()
-        {
-            if (z == null)
-                return;
-            if (_wantCompress)
-            {
-                _z.EndDeflate();
-            }
-            else
-            {
-                _z.EndInflate();
-            }
-            _z = null;
-        }
-
-
-        public override void Close()
-        {
-            if (_stream == null) return;
-            try
-            {
-                finish();
-            }
-            finally
-            {
-                end();
-                if (!_leaveOpen) _stream.Close();
-                _stream = null;
-            }
-        }
-
-        public override void Flush()
-        {
-            _stream.Flush();
-        }
-
-        public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotImplementedException();
-            //_outStream.Seek(offset, origin);
-        }
-        public override void SetLength(System.Int64 value)
-        {
-            _stream.SetLength(value);
-        }
-
-
-#if NOT
-        public int Read()
-        {
-            if (Read(_buf1, 0, 1) == 0)
-                return 0;
-            // calculate CRC after reading
-            if (crc!=null)
-                crc.SlurpBlock(_buf1,0,1);
-            return (_buf1[0] & 0xFF);
-        }
-#endif
-
-        private bool nomoreinput = false;
-
-
-
-        private string ReadZeroTerminatedString()
-        {
-            var list = new System.Collections.Generic.List<byte>();
-            bool done = false;
-            do
-            {
-                // workitem 7740
-                int n = _stream.Read(_buf1, 0, 1);
-                if (n != 1)
-                    throw new ZlibException("Unexpected EOF reading GZIP header.");
-                else
-                {
-                    if (_buf1[0] == 0)
-                        done = true;
-                    else
-                        list.Add(_buf1[0]);
-                }
-            } while (!done);
-            byte[] a = list.ToArray();
-            return GZipStream.iso8859dash1.GetString(a, 0, a.Length);
-        }
-
-
-        private int _ReadAndValidateGzipHeader()
-        {
-            int totalBytesRead = 0;
-            // read the header on the first read
-            byte[] header = new byte[10];
-            int n = _stream.Read(header, 0, header.Length);
-
-            // workitem 8501: handle edge case (decompress empty stream)
-            if (n == 0)
-                return 0;
-
-            if (n != 10)
-                throw new ZlibException("Not a valid GZIP stream.");
-
-            if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8)
-                throw new ZlibException("Bad GZIP header.");
-
-            Int32 timet = BitConverter.ToInt32(header, 4);
-            _GzipMtime = GZipStream._unixEpoch.AddSeconds(timet);
-            totalBytesRead += n;
-            if ((header[3] & 0x04) == 0x04)
-            {
-                // read and discard extra field
-                n = _stream.Read(header, 0, 2); // 2-byte length field
-                totalBytesRead += n;
-
-                Int16 extraLength = (Int16)(header[0] + header[1] * 256);
-                byte[] extra = new byte[extraLength];
-                n = _stream.Read(extra, 0, extra.Length);
-                if (n != extraLength)
-                    throw new ZlibException("Unexpected end-of-file reading GZIP header.");
-                totalBytesRead += n;
-            }
-            if ((header[3] & 0x08) == 0x08)
-                _GzipFileName = ReadZeroTerminatedString();
-            if ((header[3] & 0x10) == 0x010)
-                _GzipComment = ReadZeroTerminatedString();
-            if ((header[3] & 0x02) == 0x02)
-                Read(_buf1, 0, 1); // CRC16, ignore
-
-            return totalBytesRead;
-        }
-
-
-
-        public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count)
-        {
-            // According to MS documentation, any implementation of the IO.Stream.Read function must:
-            // (a) throw an exception if offset & count reference an invalid part of the buffer,
-            //     or if count < 0, or if buffer is null
-            // (b) return 0 only upon EOF, or if count = 0
-            // (c) if not EOF, then return at least 1 byte, up to <count> bytes
-
-            if (_streamMode == StreamMode.Undefined)
-            {
-                if (!this._stream.CanRead) throw new ZlibException("The stream is not readable.");
-                // for the first read, set up some controls.
-                _streamMode = StreamMode.Reader;
-                // (The first reference to _z goes through the private accessor which
-                // may initialize it.)
-                z.AvailableBytesIn = 0;
-                if (_flavor == ZlibStreamFlavor.GZIP)
-                {
-                    _gzipHeaderByteCount = _ReadAndValidateGzipHeader();
-                    // workitem 8501: handle edge case (decompress empty stream)
-                    if (_gzipHeaderByteCount == 0)
-                        return 0;
-                }
-            }
-
-            if (_streamMode != StreamMode.Reader)
-                throw new ZlibException("Cannot Read after Writing.");
-
-            if (count == 0) return 0;
-            if (nomoreinput && _wantCompress) return 0;  // workitem 8557
-            if (buffer == null) throw new ArgumentNullException("buffer");
-            if (count < 0) throw new ArgumentOutOfRangeException("count");
-            if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset");
-            if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count");
-
-            int rc = 0;
-
-            // set up the output of the deflate/inflate codec:
-            _z.OutputBuffer = buffer;
-            _z.NextOut = offset;
-            _z.AvailableBytesOut = count;
-
-            // This is necessary in case _workingBuffer has been resized. (new byte[])
-            // (The first reference to _workingBuffer goes through the private accessor which
-            // may initialize it.)
-            _z.InputBuffer = workingBuffer;
-
-            do
-            {
-                // need data in _workingBuffer in order to deflate/inflate.  Here, we check if we have any.
-                if ((_z.AvailableBytesIn == 0) && (!nomoreinput))
-                {
-                    // No data available, so try to Read data from the captive stream.
-                    _z.NextIn = 0;
-                    _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length);
-                    if (_z.AvailableBytesIn == 0)
-                        nomoreinput = true;
-
-                }
-                // we have data in InputBuffer; now compress or decompress as appropriate
-                rc = (_wantCompress)
-                    ? _z.Deflate(_flushMode)
-                    : _z.Inflate(_flushMode);
-
-                if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR))
-                    return 0;
-
-                if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
-                    throw new ZlibException(String.Format("{0}flating:  rc={1}  msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message));
-
-                if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count))
-                    break; // nothing more to read
-            }
-            //while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK);
-            while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK);
-
-
-            // workitem 8557
-            // is there more room in output?
-            if (_z.AvailableBytesOut > 0)
-            {
-                if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0)
-                {
-                    // deferred
-                }
-
-                // are we completely done reading?
-                if (nomoreinput)
-                {
-                    // and in compression?
-                    if (_wantCompress)
-                    {
-                        // no more input data available; therefore we flush to
-                        // try to complete the read
-                        rc = _z.Deflate(FlushType.Finish);
-
-                        if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
-                            throw new ZlibException(String.Format("Deflating:  rc={0}  msg={1}", rc, _z.Message));
-                    }
-                }
-            }
-
-
-            rc = (count - _z.AvailableBytesOut);
-
-            // calculate CRC after reading
-            if (crc != null)
-                crc.SlurpBlock(buffer, offset, rc);
-
-            return rc;
-        }
-
-
-
-        public override System.Boolean CanRead
-        {
-            get { return this._stream.CanRead; }
-        }
-
-        public override System.Boolean CanSeek
-        {
-            get { return this._stream.CanSeek; }
-        }
-
-        public override System.Boolean CanWrite
-        {
-            get { return this._stream.CanWrite; }
-        }
-
-        public override System.Int64 Length
-        {
-            get { return _stream.Length; }
-        }
-
-        public override long Position
-        {
-            get { throw new NotImplementedException(); }
-            set { throw new NotImplementedException(); }
-        }
-
-        internal enum StreamMode
-        {
-            Writer,
-            Reader,
-            Undefined,
-        }
-
-
-        public static void CompressString(String s, Stream compressor)
-        {
-            byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(s);
-            using (compressor)
-            {
-                compressor.Write(uncompressed, 0, uncompressed.Length);
-            }
-        }
-
-        public static void CompressBuffer(byte[] b, Stream compressor)
-        {
-            // workitem 8460
-            using (compressor)
-            {
-                compressor.Write(b, 0, b.Length);
-            }
-        }
-
-        public static String UncompressString(byte[] compressed, Stream decompressor)
-        {
-            // workitem 8460
-            byte[] working = new byte[1024];
-            var encoding = System.Text.Encoding.UTF8;
-            using (var output = new MemoryStream())
-            {
-                using (decompressor)
-                {
-                    int n;
-                    while ((n = decompressor.Read(working, 0, working.Length)) != 0)
-                    {
-                        output.Write(working, 0, n);
-                    }
-                }
-
-                // reset to allow read from start
-                output.Seek(0, SeekOrigin.Begin);
-                var sr = new StreamReader(output, encoding);
-                return sr.ReadToEnd();
-            }
-        }
-
-        public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor)
-        {
-            // workitem 8460
-            byte[] working = new byte[1024];
-            using (var output = new MemoryStream())
-            {
-                using (decompressor)
-                {
-                    int n;
-                    while ((n = decompressor.Read(working, 0, working.Length)) != 0)
-                    {
-                        output.Write(working, 0, n);
-                    }
-                }
-                return output.ToArray();
-            }
-        }
-
-    }
-
-
-}
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/ZlibCodec.cs b/EPPlus/Packaging/DotNetZip/Zlib/ZlibCodec.cs
deleted file mode 100644
index 8cd6ce4..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/ZlibCodec.cs
+++ /dev/null
@@ -1,717 +0,0 @@
-// ZlibCodec.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.  
-// 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: <2009-November-03 15:40:51>
-//
-// ------------------------------------------------------------------
-//
-// This module defines a Codec for ZLIB compression and
-// decompression. This code extends code that was based the jzlib
-// implementation of zlib, but this code is completely novel.  The codec
-// class is new, and encapsulates some behaviors that are new, and some
-// that were present in other classes in the jzlib code base.  In
-// keeping with the license for jzlib, the copyright to the jzlib code
-// is included below.
-//
-// ------------------------------------------------------------------
-// 
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 
-// 2. Redistributions in binary form must reproduce the above copyright 
-// notice, this list of conditions and the following disclaimer in 
-// the documentation and/or other materials provided with the distribution.
-// 
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// -----------------------------------------------------------------------
-//
-// This program is based on zlib-1.1.3; credit to authors
-// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-// and contributors of zlib.
-//
-// -----------------------------------------------------------------------
-
-
-using System;
-using Interop=System.Runtime.InteropServices;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    /// <summary>
-    /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951).
-    /// </summary>
-    ///
-    /// <remarks>
-    /// This class compresses and decompresses data according to the Deflate algorithm
-    /// and optionally, the ZLIB format, as documented in <see
-    /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950 - ZLIB</see> and <see
-    /// href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE</see>.
-    /// </remarks>
-    [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000D")]
-    [Interop.ComVisible(true)]
-#if !NETCF    
-    [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)]
-#endif
-    sealed public class ZlibCodec
-    {
-        /// <summary>
-        /// The buffer from which data is taken.
-        /// </summary>
-        public byte[] InputBuffer;
-
-        /// <summary>
-        /// An index into the InputBuffer array, indicating where to start reading. 
-        /// </summary>
-        public int NextIn;
-
-        /// <summary>
-        /// The number of bytes available in the InputBuffer, starting at NextIn. 
-        /// </summary>
-        /// <remarks>
-        /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. 
-        /// The class will update this number as calls to Inflate/Deflate are made.
-        /// </remarks>
-        public int AvailableBytesIn;
-
-        /// <summary>
-        /// Total number of bytes read so far, through all calls to Inflate()/Deflate().
-        /// </summary>
-        public long TotalBytesIn;
-
-        /// <summary>
-        /// Buffer to store output data.
-        /// </summary>
-        public byte[] OutputBuffer;
-
-        /// <summary>
-        /// An index into the OutputBuffer array, indicating where to start writing. 
-        /// </summary>
-        public int NextOut;
-
-        /// <summary>
-        /// The number of bytes available in the OutputBuffer, starting at NextOut. 
-        /// </summary>
-        /// <remarks>
-        /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. 
-        /// The class will update this number as calls to Inflate/Deflate are made.
-        /// </remarks>
-        public int AvailableBytesOut;
-
-        /// <summary>
-        /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate().
-        /// </summary>
-        public long TotalBytesOut;
-
-        /// <summary>
-        /// used for diagnostics, when something goes wrong!
-        /// </summary>
-        public System.String Message;
-
-        internal DeflateManager dstate;
-        internal InflateManager istate;
-
-        internal uint _Adler32;
-
-        /// <summary>
-        /// The compression level to use in this codec.  Useful only in compression mode.
-        /// </summary>
-        public CompressionLevel CompressLevel = CompressionLevel.Default;
-
-        /// <summary>
-        /// The number of Window Bits to use.  
-        /// </summary>
-        /// <remarks>
-        /// This gauges the size of the sliding window, and hence the 
-        /// compression effectiveness as well as memory consumption. It's best to just leave this 
-        /// setting alone if you don't know what it is.  The maximum value is 15 bits, which implies
-        /// a 32k window.  
-        /// </remarks>
-        public int WindowBits = ZlibConstants.WindowBitsDefault;
-
-        /// <summary>
-        /// The compression strategy to use.
-        /// </summary>
-        /// <remarks>
-        /// This is only effective in compression.  The theory offered by ZLIB is that different
-        /// strategies could potentially produce significant differences in compression behavior
-        /// for different data sets.  Unfortunately I don't have any good recommendations for how
-        /// to set it differently.  When I tested changing the strategy I got minimally different
-        /// compression performance. It's best to leave this property alone if you don't have a
-        /// good feel for it.  Or, you may want to produce a test harness that runs through the
-        /// different strategy options and evaluates them on different file types. If you do that,
-        /// let me know your results.
-        /// </remarks>
-        public CompressionStrategy Strategy = CompressionStrategy.Default;
-
-
-        /// <summary>
-        /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this.
-        /// </summary>
-        public int Adler32 { get { return (int)_Adler32; } }
-
-
-        /// <summary>
-        /// Create a ZlibCodec.
-        /// </summary>
-        /// <remarks>
-        /// If you use this default constructor, you will later have to explicitly call 
-        /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress 
-        /// or decompress. 
-        /// </remarks>
-        public ZlibCodec() { }
-
-        /// <summary>
-        /// Create a ZlibCodec that either compresses or decompresses.
-        /// </summary>
-        /// <param name="mode">
-        /// Indicates whether the codec should compress (deflate) or decompress (inflate).
-        /// </param>
-        public ZlibCodec(CompressionMode mode)
-        {
-            if (mode == CompressionMode.Compress)
-            {
-                int rc = InitializeDeflate();
-                if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate.");
-            }
-            else if (mode == CompressionMode.Decompress)
-            {
-                int rc = InitializeInflate();
-                if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate.");
-            }
-            else throw new ZlibException("Invalid ZlibStreamFlavor.");
-        }
-
-        /// <summary>
-        /// Initialize the inflation state. 
-        /// </summary>
-        /// <remarks>
-        /// It is not necessary to call this before using the ZlibCodec to inflate data; 
-        /// It is implicitly called when you call the constructor.
-        /// </remarks>
-        /// <returns>Z_OK if everything goes well.</returns>
-        public int InitializeInflate()
-        {
-            return InitializeInflate(this.WindowBits);
-        }
-
-        /// <summary>
-        /// Initialize the inflation state with an explicit flag to
-        /// govern the handling of RFC1950 header bytes.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// By default, the ZLIB header defined in <see
-        /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950</see> is expected.  If
-        /// you want to read a zlib stream you should specify true for
-        /// expectRfc1950Header.  If you have a deflate stream, you will want to specify
-        /// false. It is only necessary to invoke this initializer explicitly if you
-        /// want to specify false.
-        /// </remarks>
-        ///
-        /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte
-        /// pair when reading the stream of data to be inflated.</param>
-        ///
-        /// <returns>Z_OK if everything goes well.</returns>
-        public int InitializeInflate(bool expectRfc1950Header)
-        {
-            return InitializeInflate(this.WindowBits, expectRfc1950Header);
-        }
-
-        /// <summary>
-        /// Initialize the ZlibCodec for inflation, with the specified number of window bits. 
-        /// </summary>
-        /// <param name="windowBits">The number of window bits to use. If you need to ask what that is, 
-        /// then you shouldn't be calling this initializer.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int InitializeInflate(int windowBits)
-        {
-            this.WindowBits = windowBits;            
-            return InitializeInflate(windowBits, true);
-        }
-
-        /// <summary>
-        /// Initialize the inflation state with an explicit flag to govern the handling of
-        /// RFC1950 header bytes. 
-        /// </summary>
-        ///
-        /// <remarks>
-        /// If you want to read a zlib stream you should specify true for
-        /// expectRfc1950Header. In this case, the library will expect to find a ZLIB
-        /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
-        /// 1950</see>, in the compressed stream.  If you will be reading a DEFLATE or
-        /// GZIP stream, which does not have such a header, you will want to specify
-        /// false.
-        /// </remarks>
-        ///
-        /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte pair when reading 
-        /// the stream of data to be inflated.</param>
-        /// <param name="windowBits">The number of window bits to use. If you need to ask what that is, 
-        /// then you shouldn't be calling this initializer.</param>
-        /// <returns>Z_OK if everything goes well.</returns>
-        public int InitializeInflate(int windowBits, bool expectRfc1950Header)
-        {
-            this.WindowBits = windowBits;
-            if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate().");
-            istate = new InflateManager(expectRfc1950Header);
-            return istate.Initialize(this, windowBits);
-        }
-
-        /// <summary>
-        /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer.
-        /// </summary>
-        /// <remarks>
-        /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and 
-        /// AvailableBytesOut  before calling this method.
-        /// </remarks>
-        /// <example>
-        /// <code>
-        /// private void InflateBuffer()
-        /// {
-        ///     int bufferSize = 1024;
-        ///     byte[] buffer = new byte[bufferSize];
-        ///     ZlibCodec decompressor = new ZlibCodec();
-        /// 
-        ///     Console.WriteLine("\n============================================");
-        ///     Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length);
-        ///     MemoryStream ms = new MemoryStream(DecompressedBytes);
-        /// 
-        ///     int rc = decompressor.InitializeInflate();
-        /// 
-        ///     decompressor.InputBuffer = CompressedBytes;
-        ///     decompressor.NextIn = 0;
-        ///     decompressor.AvailableBytesIn = CompressedBytes.Length;
-        /// 
-        ///     decompressor.OutputBuffer = buffer;
-        /// 
-        ///     // pass 1: inflate 
-        ///     do
-        ///     {
-        ///         decompressor.NextOut = 0;
-        ///         decompressor.AvailableBytesOut = buffer.Length;
-        ///         rc = decompressor.Inflate(FlushType.None);
-        /// 
-        ///         if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
-        ///             throw new Exception("inflating: " + decompressor.Message);
-        /// 
-        ///         ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut);
-        ///     }
-        ///     while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
-        /// 
-        ///     // pass 2: finish and flush
-        ///     do
-        ///     {
-        ///         decompressor.NextOut = 0;
-        ///         decompressor.AvailableBytesOut = buffer.Length;
-        ///         rc = decompressor.Inflate(FlushType.Finish);
-        /// 
-        ///         if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
-        ///             throw new Exception("inflating: " + decompressor.Message);
-        /// 
-        ///         if (buffer.Length - decompressor.AvailableBytesOut &gt; 0)
-        ///             ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut);
-        ///     }
-        ///     while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
-        /// 
-        ///     decompressor.EndInflate();
-        /// }
-        ///
-        /// </code>
-        /// </example>
-        /// <param name="flush">The flush to use when inflating.</param>
-        /// <returns>Z_OK if everything goes well.</returns>
-        public int Inflate(FlushType flush)
-        {
-            if (istate == null)
-                throw new ZlibException("No Inflate State!");
-            return istate.Inflate(flush);
-        }
-
-
-        /// <summary>
-        /// Ends an inflation session. 
-        /// </summary>
-        /// <remarks>
-        /// Call this after successively calling Inflate().  This will cause all buffers to be flushed. 
-        /// After calling this you cannot call Inflate() without a intervening call to one of the
-        /// InitializeInflate() overloads.
-        /// </remarks>
-        /// <returns>Z_OK if everything goes well.</returns>
-        public int EndInflate()
-        {
-            if (istate == null)
-                throw new ZlibException("No Inflate State!");
-            int ret = istate.End();
-            istate = null;
-            return ret;
-        }
-
-        /// <summary>
-        /// I don't know what this does!
-        /// </summary>
-        /// <returns>Z_OK if everything goes well.</returns>
-        public int SyncInflate()
-        {
-            if (istate == null)
-                throw new ZlibException("No Inflate State!");
-            return istate.Sync();
-        }
-
-        /// <summary>
-        /// Initialize the ZlibCodec for deflation operation.
-        /// </summary>
-        /// <remarks>
-        /// The codec will use the MAX window bits and the default level of compression.
-        /// </remarks>
-        /// <example>
-        /// <code>
-        ///  int bufferSize = 40000;
-        ///  byte[] CompressedBytes = new byte[bufferSize];
-        ///  byte[] DecompressedBytes = new byte[bufferSize];
-        ///  
-        ///  ZlibCodec compressor = new ZlibCodec();
-        ///  
-        ///  compressor.InitializeDeflate(CompressionLevel.Default);
-        ///  
-        ///  compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress);
-        ///  compressor.NextIn = 0;
-        ///  compressor.AvailableBytesIn = compressor.InputBuffer.Length;
-        ///  
-        ///  compressor.OutputBuffer = CompressedBytes;
-        ///  compressor.NextOut = 0;
-        ///  compressor.AvailableBytesOut = CompressedBytes.Length;
-        ///  
-        ///  while (compressor.TotalBytesIn != TextToCompress.Length &amp;&amp; compressor.TotalBytesOut &lt; bufferSize)
-        ///  {
-        ///    compressor.Deflate(FlushType.None);
-        ///  }
-        ///  
-        ///  while (true)
-        ///  {
-        ///    int rc= compressor.Deflate(FlushType.Finish);
-        ///    if (rc == ZlibConstants.Z_STREAM_END) break;
-        ///  }
-        ///  
-        ///  compressor.EndDeflate();
-        ///   
-        /// </code>
-        /// </example>
-        /// <returns>Z_OK if all goes well. You generally don't need to check the return code.</returns>
-        public int InitializeDeflate()
-        {
-            return _InternalInitializeDeflate(true);
-        }
-
-        /// <summary>
-        /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel.
-        /// </summary>
-        /// <remarks>
-        /// The codec will use the maximum window bits (15) and the specified
-        /// CompressionLevel.  It will emit a ZLIB stream as it compresses.
-        /// </remarks>
-        /// <param name="level">The compression level for the codec.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int InitializeDeflate(CompressionLevel level)
-        {
-            this.CompressLevel = level;
-            return _InternalInitializeDeflate(true);
-        }
-
-
-        /// <summary>
-        /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, 
-        /// and the explicit flag governing whether to emit an RFC1950 header byte pair.
-        /// </summary>
-        /// <remarks>
-        /// The codec will use the maximum window bits (15) and the specified CompressionLevel.
-        /// If you want to generate a zlib stream, you should specify true for
-        /// wantRfc1950Header. In this case, the library will emit a ZLIB
-        /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
-        /// 1950</see>, in the compressed stream.  
-        /// </remarks>
-        /// <param name="level">The compression level for the codec.</param>
-        /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header)
-        {
-            this.CompressLevel = level;
-            return _InternalInitializeDeflate(wantRfc1950Header);
-        }
-
-
-        /// <summary>
-        /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, 
-        /// and the specified number of window bits. 
-        /// </summary>
-        /// <remarks>
-        /// The codec will use the specified number of window bits and the specified CompressionLevel.
-        /// </remarks>
-        /// <param name="level">The compression level for the codec.</param>
-        /// <param name="bits">the number of window bits to use.  If you don't know what this means, don't use this method.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int InitializeDeflate(CompressionLevel level, int bits)
-        {
-            this.CompressLevel = level;
-            this.WindowBits = bits;
-            return _InternalInitializeDeflate(true);
-        }
-
-        /// <summary>
-        /// Initialize the ZlibCodec for deflation operation, using the specified
-        /// CompressionLevel, the specified number of window bits, and the explicit flag
-        /// governing whether to emit an RFC1950 header byte pair.
-        /// </summary>
-        ///
-        /// <param name="level">The compression level for the codec.</param>
-        /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param>
-        /// <param name="bits">the number of window bits to use.  If you don't know what this means, don't use this method.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header)
-        {
-            this.CompressLevel = level;
-            this.WindowBits = bits;
-            return _InternalInitializeDeflate(wantRfc1950Header);
-        }
-
-        private int _InternalInitializeDeflate(bool wantRfc1950Header)
-        {
-            if (istate != null) throw new ZlibException("You may not call InitializeDeflate() after calling InitializeInflate().");
-            dstate = new DeflateManager();
-            dstate.WantRfc1950HeaderBytes = wantRfc1950Header;
-
-            return dstate.Initialize(this, this.CompressLevel, this.WindowBits, this.Strategy);
-        }
-
-        /// <summary>
-        /// Deflate one batch of data.
-        /// </summary>
-        /// <remarks>
-        /// You must have set InputBuffer and OutputBuffer before calling this method.
-        /// </remarks>
-        /// <example>
-        /// <code>
-        /// private void DeflateBuffer(CompressionLevel level)
-        /// {
-        ///     int bufferSize = 1024;
-        ///     byte[] buffer = new byte[bufferSize];
-        ///     ZlibCodec compressor = new ZlibCodec();
-        /// 
-        ///     Console.WriteLine("\n============================================");
-        ///     Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length);
-        ///     MemoryStream ms = new MemoryStream();
-        /// 
-        ///     int rc = compressor.InitializeDeflate(level);
-        /// 
-        ///     compressor.InputBuffer = UncompressedBytes;
-        ///     compressor.NextIn = 0;
-        ///     compressor.AvailableBytesIn = UncompressedBytes.Length;
-        /// 
-        ///     compressor.OutputBuffer = buffer;
-        /// 
-        ///     // pass 1: deflate 
-        ///     do
-        ///     {
-        ///         compressor.NextOut = 0;
-        ///         compressor.AvailableBytesOut = buffer.Length;
-        ///         rc = compressor.Deflate(FlushType.None);
-        /// 
-        ///         if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
-        ///             throw new Exception("deflating: " + compressor.Message);
-        /// 
-        ///         ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut);
-        ///     }
-        ///     while (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
-        /// 
-        ///     // pass 2: finish and flush
-        ///     do
-        ///     {
-        ///         compressor.NextOut = 0;
-        ///         compressor.AvailableBytesOut = buffer.Length;
-        ///         rc = compressor.Deflate(FlushType.Finish);
-        /// 
-        ///         if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
-        ///             throw new Exception("deflating: " + compressor.Message);
-        /// 
-        ///         if (buffer.Length - compressor.AvailableBytesOut &gt; 0)
-        ///             ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
-        ///     }
-        ///     while (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
-        /// 
-        ///     compressor.EndDeflate();
-        /// 
-        ///     ms.Seek(0, SeekOrigin.Begin);
-        ///     CompressedBytes = new byte[compressor.TotalBytesOut];
-        ///     ms.Read(CompressedBytes, 0, CompressedBytes.Length);
-        /// }
-        /// </code>
-        /// </example>
-        /// <param name="flush">whether to flush all data as you deflate. Generally you will want to 
-        /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to 
-        /// flush everything. 
-        /// </param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int Deflate(FlushType flush)
-        {
-            if (dstate == null)
-                throw new ZlibException("No Deflate State!");
-            return dstate.Deflate(flush);
-        }
-
-        /// <summary>
-        /// End a deflation session.
-        /// </summary>
-        /// <remarks>
-        /// Call this after making a series of one or more calls to Deflate(). All buffers are flushed.
-        /// </remarks>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int EndDeflate()
-        {
-            if (dstate == null)
-                throw new ZlibException("No Deflate State!");
-            // TODO: dinoch Tue, 03 Nov 2009  15:39 (test this)
-            //int ret = dstate.End();
-            dstate = null;
-            return ZlibConstants.Z_OK; //ret;
-        }
-
-        /// <summary>
-        /// Reset a codec for another deflation session.
-        /// </summary>
-        /// <remarks>
-        /// Call this to reset the deflation state.  For example if a thread is deflating
-        /// non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first
-        /// block and before the next Deflate(None) of the second block.
-        /// </remarks>
-        /// <returns>Z_OK if all goes well.</returns>
-        public void ResetDeflate()
-        {
-            if (dstate == null)
-                throw new ZlibException("No Deflate State!");
-            dstate.Reset();
-        }
-
-
-        /// <summary>
-        /// Set the CompressionStrategy and CompressionLevel for a deflation session.
-        /// </summary>
-        /// <param name="level">the level of compression to use.</param>
-        /// <param name="strategy">the strategy to use for compression.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy)
-        {
-            if (dstate == null)
-                throw new ZlibException("No Deflate State!");
-            return dstate.SetParams(level, strategy);
-        }
-
-
-        /// <summary>
-        /// Set the dictionary to be used for either Inflation or Deflation.
-        /// </summary>
-        /// <param name="dictionary">The dictionary bytes to use.</param>
-        /// <returns>Z_OK if all goes well.</returns>
-        public int SetDictionary(byte[] dictionary)
-        {
-            if (istate != null)
-                return istate.SetDictionary(dictionary);
-
-            if (dstate != null)
-                return dstate.SetDictionary(dictionary);
-
-            throw new ZlibException("No Inflate or Deflate state!");
-        }
-
-        // Flush as much pending output as possible. All deflate() output goes
-        // through this function so some applications may wish to modify it
-        // to avoid allocating a large strm->next_out buffer and copying into it.
-        // (See also read_buf()).
-        internal void flush_pending()
-        {
-            int len = dstate.pendingCount;
-
-            if (len > AvailableBytesOut)
-                len = AvailableBytesOut;
-            if (len == 0)
-                return;
-
-            if (dstate.pending.Length <= dstate.nextPending ||
-                OutputBuffer.Length <= NextOut ||
-                dstate.pending.Length < (dstate.nextPending + len) ||
-                OutputBuffer.Length < (NextOut + len))
-            {
-                throw new ZlibException(String.Format("Invalid State. (pending.Length={0}, pendingCount={1})",
-                    dstate.pending.Length, dstate.pendingCount));
-            }
-
-            Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len);
-
-            NextOut             += len;
-            dstate.nextPending  += len;
-            TotalBytesOut       += len;
-            AvailableBytesOut   -= len;
-            dstate.pendingCount -= len;
-            if (dstate.pendingCount == 0)
-            {
-                dstate.nextPending = 0;
-            }
-        }
-
-        // Read a new buffer from the current input stream, update the adler32
-        // and total number of bytes read.  All deflate() input goes through
-        // this function so some applications may wish to modify it to avoid
-        // allocating a large strm->next_in buffer and copying from it.
-        // (See also flush_pending()).
-        internal int read_buf(byte[] buf, int start, int size)
-        {
-            int len = AvailableBytesIn;
-
-            if (len > size)
-                len = size;
-            if (len == 0)
-                return 0;
-
-            AvailableBytesIn -= len;
-
-            if (dstate.WantRfc1950HeaderBytes)
-            {
-                _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len);
-            }
-            Array.Copy(InputBuffer, NextIn, buf, start, len);
-            NextIn += len;
-            TotalBytesIn += len;
-            return len;
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/ZlibConstants.cs b/EPPlus/Packaging/DotNetZip/Zlib/ZlibConstants.cs
deleted file mode 100644
index 951f42a..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/ZlibConstants.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-// ZlibConstants.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.  
-// 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: <2009-November-03 18:50:19>
-//
-// ------------------------------------------------------------------
-//
-// This module defines constants used by the zlib class library.  This
-// code is derived from the jzlib implementation of zlib, but
-// significantly modified.  In keeping with the license for jzlib, the
-// copyright to that code is included here.
-//
-// ------------------------------------------------------------------
-// 
-// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 
-// 2. Redistributions in binary form must reproduce the above copyright 
-// notice, this list of conditions and the following disclaimer in 
-// the documentation and/or other materials provided with the distribution.
-// 
-// 3. The names of the authors may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// -----------------------------------------------------------------------
-//
-// This program is based on zlib-1.1.3; credit to authors
-// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-// and contributors of zlib.
-//
-// -----------------------------------------------------------------------
-
-
-using System;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-    /// <summary>
-    /// A bunch of constants used in the Zlib interface.
-    /// </summary>
-    public static class ZlibConstants
-    {
-        /// <summary>
-        /// The maximum number of window bits for the Deflate algorithm.
-        /// </summary>
-        public const int WindowBitsMax = 15; // 32K LZ77 window
-
-        /// <summary>
-        /// The default number of window bits for the Deflate algorithm.
-        /// </summary>
-        public const int WindowBitsDefault = WindowBitsMax;
-
-        /// <summary>
-        /// indicates everything is A-OK
-        /// </summary>
-        public const int Z_OK = 0;
-
-        /// <summary>
-        /// Indicates that the last operation reached the end of the stream.
-        /// </summary>
-        public const int Z_STREAM_END = 1;
-
-        /// <summary>
-        /// The operation ended in need of a dictionary. 
-        /// </summary>
-        public const int Z_NEED_DICT = 2;
-
-        /// <summary>
-        /// There was an error with the stream - not enough data, not open and readable, etc.
-        /// </summary>
-        public const int Z_STREAM_ERROR = -2;
-
-        /// <summary>
-        /// There was an error with the data - not enough data, bad data, etc.
-        /// </summary>
-        public const int Z_DATA_ERROR = -3;
-
-        /// <summary>
-        /// There was an error with the working buffer.
-        /// </summary>
-        public const int Z_BUF_ERROR = -5;
-
-        /// <summary>
-        /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
-        /// </summary>
-#if NETCF        
-        public const int WorkingBufferSizeDefault = 8192;
-#else
-        public const int WorkingBufferSizeDefault = 16384; 
-#endif
-        /// <summary>
-        /// The minimum size of the working buffer used in the ZlibCodec class.  Currently it is 128 bytes.
-        /// </summary>
-        public const int WorkingBufferSizeMin = 1024;
-    }
-
-}
-
diff --git a/EPPlus/Packaging/DotNetZip/Zlib/ZlibStream.cs b/EPPlus/Packaging/DotNetZip/Zlib/ZlibStream.cs
deleted file mode 100644
index 460aee7..0000000
--- a/EPPlus/Packaging/DotNetZip/Zlib/ZlibStream.cs
+++ /dev/null
@@ -1,725 +0,0 @@
-// ZlibStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
-// 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-31 14:53:33>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZlibStream class, which is similar in idea to
-// the System.IO.Compression.DeflateStream and
-// System.IO.Compression.GZipStream classes in the .NET BCL.
-//
-// ------------------------------------------------------------------
-
-using System;
-using System.IO;
-
-namespace OfficeOpenXml.Packaging.Ionic.Zlib
-{
-
-    /// <summary>
-    /// Represents a Zlib stream for compression or decompression.
-    /// </summary>
-    /// <remarks>
-    ///
-    /// <para>
-    /// The ZlibStream is a <see
-    /// href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see
-    /// cref="System.IO.Stream"/>.  It adds ZLIB compression or decompression to any
-    /// stream.
-    /// </para>
-    ///
-    /// <para> Using this stream, applications can compress or decompress data via
-    /// stream <c>Read()</c> and <c>Write()</c> operations.  Either compresssion or
-    /// decompression can occur through either reading or writing. The compression
-    /// format used is ZLIB, which is documented in <see
-    /// href="http://www.ietf.org/rfc/rfc1950.txt">IETF RFC 1950</see>, "ZLIB Compressed
-    /// Data Format Specification version 3.3". This implementation of ZLIB always uses
-    /// DEFLATE as the compression method.  (see <see
-    /// href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE
-    /// Compressed Data Format Specification version 1.3.") </para>
-    ///
-    /// <para>
-    /// The ZLIB format allows for varying compression methods, window sizes, and dictionaries.
-    /// This implementation always uses the DEFLATE compression method, a preset dictionary,
-    /// and 15 window bits by default.
-    /// </para>
-    ///
-    /// <para>
-    /// This class is similar to <see cref="DeflateStream"/>, except that it adds the
-    /// RFC1950 header and trailer bytes to a compressed stream when compressing, or expects
-    /// the RFC1950 header and trailer bytes when decompressing.  It is also similar to the
-    /// <see cref="GZipStream"/>.
-    /// </para>
-    /// </remarks>
-    /// <seealso cref="DeflateStream" />
-    /// <seealso cref="GZipStream" />
-    public class ZlibStream : System.IO.Stream
-    {
-        internal ZlibBaseStream _baseStream;
-        bool _disposed;
-
-        /// <summary>
-        /// Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>.
-        /// </summary>
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Compress</c>, the <c>ZlibStream</c>
-        ///   will use the default compression level. The "captive" stream will be
-        ///   closed when the <c>ZlibStream</c> is closed.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        /// This example uses a <c>ZlibStream</c> to compress a file, and writes the
-        /// compressed data to another file.
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(fileToCompress + ".zlib"))
-        ///     {
-        ///         using (Stream compressor = new ZlibStream(raw, CompressionMode.Compress))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".zlib")
-        ///     Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress)
-        ///         Dim buffer As Byte() = New Byte(4096) {}
-        ///         Dim n As Integer = -1
-        ///         Do While (n &lt;&gt; 0)
-        ///             If (n &gt; 0) Then
-        ///                 compressor.Write(buffer, 0, n)
-        ///             End If
-        ///             n = input.Read(buffer, 0, buffer.Length)
-        ///         Loop
-        ///     End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="stream">The stream which will be read or written.</param>
-        /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
-        public ZlibStream(System.IO.Stream stream, CompressionMode mode)
-            : this(stream, mode, CompressionLevel.Default, false)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c> and
-        ///   the specified <c>CompressionLevel</c>.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored.
-        ///   The "captive" stream will be closed when the <c>ZlibStream</c> is closed.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///   This example uses a <c>ZlibStream</c> to compress data from a file, and writes the
-        ///   compressed data to another file.
-        ///
-        /// <code>
-        /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        /// {
-        ///     using (var raw = System.IO.File.Create(fileToCompress + ".zlib"))
-        ///     {
-        ///         using (Stream compressor = new ZlibStream(raw,
-        ///                                                   CompressionMode.Compress,
-        ///                                                   CompressionLevel.BestCompression))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        /// }
-        /// </code>
-        ///
-        /// <code lang="VB">
-        /// Using input As Stream = File.OpenRead(fileToCompress)
-        ///     Using raw As FileStream = File.Create(fileToCompress &amp; ".zlib")
-        ///         Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
-        ///             Dim buffer As Byte() = New Byte(4096) {}
-        ///             Dim n As Integer = -1
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="stream">The stream to be read or written while deflating or inflating.</param>
-        /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
-        /// <param name="level">A tuning knob to trade speed for effectiveness.</param>
-        public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level)
-            : this(stream, mode, level, false)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>, and
-        ///   explicitly specify whether the captive stream should be left open after
-        ///   Deflation or Inflation.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Compress</c>, the <c>ZlibStream</c> will use
-        ///   the default compression level.
-        /// </para>
-        ///
-        /// <para>
-        ///   This constructor allows the application to request that the captive stream
-        ///   remain open after the deflation or inflation occurs.  By default, after
-        ///   <c>Close()</c> is called on the stream, the captive stream is also
-        ///   closed. In some cases this is not desired, for example if the stream is a
-        ///   <see cref="System.IO.MemoryStream"/> that will be re-read after
-        ///   compression.  Specify true for the <paramref name="leaveOpen"/> parameter to leave the stream
-        ///   open.
-        /// </para>
-        ///
-        /// <para>
-        /// See the other overloads of this constructor for example code.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="stream">The stream which will be read or written. This is called the
-        /// "captive" stream in other places in this documentation.</param>
-        /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
-        /// <param name="leaveOpen">true if the application would like the stream to remain
-        /// open after inflation/deflation.</param>
-        public ZlibStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen)
-            : this(stream, mode, CompressionLevel.Default, leaveOpen)
-        {
-        }
-
-        /// <summary>
-        ///   Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>
-        ///   and the specified <c>CompressionLevel</c>, and explicitly specify
-        ///   whether the stream should be left open after Deflation or Inflation.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   This constructor allows the application to request that the captive
-        ///   stream remain open after the deflation or inflation occurs.  By
-        ///   default, after <c>Close()</c> is called on the stream, the captive
-        ///   stream is also closed. In some cases this is not desired, for example
-        ///   if the stream is a <see cref="System.IO.MemoryStream"/> that will be
-        ///   re-read after compression.  Specify true for the <paramref
-        ///   name="leaveOpen"/> parameter to leave the stream open.
-        /// </para>
-        ///
-        /// <para>
-        ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is
-        ///   ignored.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <example>
-        ///
-        /// This example shows how to use a ZlibStream to compress the data from a file,
-        /// and store the result into another file. The filestream remains open to allow
-        /// additional data to be written to it.
-        ///
-        /// <code>
-        /// using (var output = System.IO.File.Create(fileToCompress + ".zlib"))
-        /// {
-        ///     using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
-        ///     {
-        ///         using (Stream compressor = new ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
-        ///         {
-        ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE];
-        ///             int n;
-        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
-        ///             {
-        ///                 compressor.Write(buffer, 0, n);
-        ///             }
-        ///         }
-        ///     }
-        ///     // can write additional data to the output stream here
-        /// }
-        /// </code>
-        /// <code lang="VB">
-        /// Using output As FileStream = File.Create(fileToCompress &amp; ".zlib")
-        ///     Using input As Stream = File.OpenRead(fileToCompress)
-        ///         Using compressor As Stream = New ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
-        ///             Dim buffer As Byte() = New Byte(4096) {}
-        ///             Dim n As Integer = -1
-        ///             Do While (n &lt;&gt; 0)
-        ///                 If (n &gt; 0) Then
-        ///                     compressor.Write(buffer, 0, n)
-        ///                 End If
-        ///                 n = input.Read(buffer, 0, buffer.Length)
-        ///             Loop
-        ///         End Using
-        ///     End Using
-        ///     ' can write additional data to the output stream here.
-        /// End Using
-        /// </code>
-        /// </example>
-        ///
-        /// <param name="stream">The stream which will be read or written.</param>
-        ///
-        /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
-        ///
-        /// <param name="leaveOpen">
-        /// true if the application would like the stream to remain open after
-        /// inflation/deflation.
-        /// </param>
-        ///
-        /// <param name="level">
-        /// A tuning knob to trade speed for effectiveness. This parameter is
-        /// effective only when mode is <c>CompressionMode.Compress</c>.
-        /// </param>
-        public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
-        {
-            _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen);
-        }
-
-        #region Zlib properties
-
-        /// <summary>
-        /// This property sets the flush behavior on the stream.
-        /// Sorry, though, not sure exactly how to describe all the various settings.
-        /// </summary>
-        virtual public FlushType FlushMode
-        {
-            get { return (this._baseStream._flushMode); }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("ZlibStream");
-                this._baseStream._flushMode = value;
-            }
-        }
-
-        /// <summary>
-        ///   The size of the working buffer for the compression codec.
-        /// </summary>
-        ///
-        /// <remarks>
-        /// <para>
-        ///   The working buffer is used for all stream operations.  The default size is
-        ///   1024 bytes. The minimum size is 128 bytes. You may get better performance
-        ///   with a larger buffer.  Then again, you might not.  You would have to test
-        ///   it.
-        /// </para>
-        ///
-        /// <para>
-        ///   Set this before the first call to <c>Read()</c> or <c>Write()</c> on the
-        ///   stream. If you try to set it afterwards, it will throw.
-        /// </para>
-        /// </remarks>
-        public int BufferSize
-        {
-            get
-            {
-                return this._baseStream._bufferSize;
-            }
-            set
-            {
-                if (_disposed) throw new ObjectDisposedException("ZlibStream");
-                if (this._baseStream._workingBuffer != null)
-                    throw new ZlibException("The working buffer is already set.");
-                if (value < ZlibConstants.WorkingBufferSizeMin)
-                    throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));
-                this._baseStream._bufferSize = value;
-            }
-        }
-
-        /// <summary> Returns the total number of bytes input so far.</summary>
-        virtual public long TotalIn
-        {
-            get { return this._baseStream._z.TotalBytesIn; }
-        }
-
-        /// <summary> Returns the total number of bytes output so far.</summary>
-        virtual public long TotalOut
-        {
-            get { return this._baseStream._z.TotalBytesOut; }
-        }
-
-        #endregion
-
-        #region System.IO.Stream methods
-
-        /// <summary>
-        ///   Dispose the stream.
-        /// </summary>
-        /// <remarks>
-        ///   <para>
-        ///     This may or may not result in a <c>Close()</c> call on the captive
-        ///     stream.  See the constructors that have a <c>leaveOpen</c> parameter
-        ///     for more information.
-        ///   </para>
-        ///   <para>
-        ///     This method may be invoked in two distinct scenarios.  If disposing
-        ///     == true, the method has been called directly or indirectly by a
-        ///     user's code, for example via the public Dispose() method. In this
-        ///     case, both managed and unmanaged resources can be referenced and
-        ///     disposed.  If disposing == false, the method has been called by the
-        ///     runtime from inside the object finalizer and this method should not
-        ///     reference other objects; in that case only unmanaged resources must
-        ///     be referenced or disposed.
-        ///   </para>
-        /// </remarks>
-        /// <param name="disposing">
-        ///   indicates whether the Dispose method was invoked by user code.
-        /// </param>
-        protected override void Dispose(bool disposing)
-        {
-            try
-            {
-                if (!_disposed)
-                {
-                    if (disposing && (this._baseStream != null))
-                        this._baseStream.Close();
-                    _disposed = true;
-                }
-            }
-            finally
-            {
-                base.Dispose(disposing);
-            }
-        }
-
-
-        /// <summary>
-        /// Indicates whether the stream can be read.
-        /// </summary>
-        /// <remarks>
-        /// The return value depends on whether the captive stream supports reading.
-        /// </remarks>
-        public override bool CanRead
-        {
-            get
-            {
-                if (_disposed) throw new ObjectDisposedException("ZlibStream");
-                return _baseStream._stream.CanRead;
-            }
-        }
-
-        /// <summary>
-        /// Indicates whether the stream supports Seek operations.
-        /// </summary>
-        /// <remarks>
-        /// Always returns false.
-        /// </remarks>
-        public override bool CanSeek
-        {
-            get { return false; }
-        }
-
-        /// <summary>
-        /// Indicates whether the stream can be written.
-        /// </summary>
-        /// <remarks>
-        /// The return value depends on whether the captive stream supports writing.
-        /// </remarks>
-        public override bool CanWrite
-        {
-            get
-            {
-                if (_disposed) throw new ObjectDisposedException("ZlibStream");
-                return _baseStream._stream.CanWrite;
-            }
-        }
-
-        /// <summary>
-        /// Flush the stream.
-        /// </summary>
-        public override void Flush()
-        {
-            if (_disposed) throw new ObjectDisposedException("ZlibStream");
-            _baseStream.Flush();
-        }
-
-        /// <summary>
-        /// Reading this property always throws a <see cref="NotSupportedException"/>.
-        /// </summary>
-        public override long Length
-        {
-            get { throw new NotSupportedException(); }
-        }
-
-        /// <summary>
-        ///   The position of the stream pointer.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Setting this property always throws a <see
-        ///   cref="NotSupportedException"/>. Reading will return the total bytes
-        ///   written out, if used in writing, or the total bytes read in, if used in
-        ///   reading.  The count may refer to compressed bytes or uncompressed bytes,
-        ///   depending on how you've used the stream.
-        /// </remarks>
-        public override long Position
-        {
-            get
-            {
-                if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer)
-                    return this._baseStream._z.TotalBytesOut;
-                if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader)
-                    return this._baseStream._z.TotalBytesIn;
-                return 0;
-            }
-
-            set { throw new NotSupportedException(); }
-        }
-
-        /// <summary>
-        /// Read data from the stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   If you wish to use the <c>ZlibStream</c> to compress data while reading,
-        ///   you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>,
-        ///   providing an uncompressed data stream.  Then call <c>Read()</c> on that
-        ///   <c>ZlibStream</c>, and the data read will be compressed.  If you wish to
-        ///   use the <c>ZlibStream</c> to decompress data while reading, you can create
-        ///   a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, providing a
-        ///   readable compressed data stream.  Then call <c>Read()</c> on that
-        ///   <c>ZlibStream</c>, and the data will be decompressed as it is read.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but
-        ///   not both.
-        /// </para>
-        ///
-        /// </remarks>
-        ///
-        /// <param name="buffer">
-        /// The buffer into which the read data should be placed.</param>
-        ///
-        /// <param name="offset">
-        /// the offset within that data array to put the first byte read.</param>
-        ///
-        /// <param name="count">the number of bytes to read.</param>
-        ///
-        /// <returns>the number of bytes read</returns>
-        public override int Read(byte[] buffer, int offset, int count)
-        {
-                if (_disposed) throw new ObjectDisposedException("ZlibStream");
-            return _baseStream.Read(buffer, offset, count);
-        }
-
-        /// <summary>
-        /// Calling this method always throws a <see cref="NotSupportedException"/>.
-        /// </summary>
-        /// <param name="offset">
-        ///   The offset to seek to....
-        ///   IF THIS METHOD ACTUALLY DID ANYTHING.
-        /// </param>
-        /// <param name="origin">
-        ///   The reference specifying how to apply the offset....  IF
-        ///   THIS METHOD ACTUALLY DID ANYTHING.
-        /// </param>
-        ///
-        /// <returns>nothing. This method always throws.</returns>
-        public override long Seek(long offset, System.IO.SeekOrigin origin)
-        {
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        /// Calling this method always throws a <see cref="NotSupportedException"/>.
-        /// </summary>
-        /// <param name="value">
-        ///   The new value for the stream length....  IF
-        ///   THIS METHOD ACTUALLY DID ANYTHING.
-        /// </param>
-        public override void SetLength(long value)
-        {
-            throw new NotSupportedException();
-        }
-
-        /// <summary>
-        /// Write data to the stream.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///
-        /// <para>
-        ///   If you wish to use the <c>ZlibStream</c> to compress data while writing,
-        ///   you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>,
-        ///   and a writable output stream.  Then call <c>Write()</c> on that
-        ///   <c>ZlibStream</c>, providing uncompressed data as input.  The data sent to
-        ///   the output stream will be the compressed form of the data written.  If you
-        ///   wish to use the <c>ZlibStream</c> to decompress data while writing, you
-        ///   can create a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, and a
-        ///   writable output stream.  Then call <c>Write()</c> on that stream,
-        ///   providing previously compressed data. The data sent to the output stream
-        ///   will be the decompressed form of the data written.
-        /// </para>
-        ///
-        /// <para>
-        ///   A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both.
-        /// </para>
-        /// </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) throw new ObjectDisposedException("ZlibStream");
-            _baseStream.Write(buffer, offset, count);
-        }
-        #endregion
-
-
-        /// <summary>
-        ///   Compress a string into a byte array using ZLIB.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Uncompress it with <see cref="ZlibStream.UncompressString(byte[])"/>.
-        /// </remarks>
-        ///
-        /// <seealso cref="ZlibStream.UncompressString(byte[])"/>
-        /// <seealso cref="ZlibStream.CompressBuffer(byte[])"/>
-        /// <seealso cref="GZipStream.CompressString(string)"/>
-        ///
-        /// <param name="s">
-        ///   A string to compress.  The string will first be encoded
-        ///   using UTF8, then compressed.
-        /// </param>
-        ///
-        /// <returns>The string in compressed form</returns>
-        public static byte[] CompressString(String s)
-        {
-            using (var ms = new MemoryStream())
-            {
-                Stream compressor =
-                    new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression);
-                ZlibBaseStream.CompressString(s, compressor);
-                return ms.ToArray();
-            }
-        }
-
-
-        /// <summary>
-        ///   Compress a byte array into a new byte array using ZLIB.
-        /// </summary>
-        ///
-        /// <remarks>
-        ///   Uncompress it with <see cref="ZlibStream.UncompressBuffer(byte[])"/>.
-        /// </remarks>
-        ///
-        /// <seealso cref="ZlibStream.CompressString(string)"/>
-        /// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/>
-        ///
-        /// <param name="b">
-        /// A buffer to compress.
-        /// </param>
-        ///
-        /// <returns>The data in compressed form</returns>
-        public static byte[] CompressBuffer(byte[] b)
-        {
-            using (var ms = new MemoryStream())
-            {
-                Stream compressor =
-                    new ZlibStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression );
-
-                ZlibBaseStream.CompressBuffer(b, compressor);
-                return ms.ToArray();
-            }
-        }
-
-
-        /// <summary>
-        ///   Uncompress a ZLIB-compressed byte array into a single string.
-        /// </summary>
-        ///
-        /// <seealso cref="ZlibStream.CompressString(String)"/>
-        /// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/>
-        ///
-        /// <param name="compressed">
-        ///   A buffer containing ZLIB-compressed data.
-        /// </param>
-        ///
-        /// <returns>The uncompressed string</returns>
-        public static String UncompressString(byte[] compressed)
-        {
-            using (var input = new MemoryStream(compressed))
-            {
-                Stream decompressor =
-                    new ZlibStream(input, CompressionMode.Decompress);
-
-                return ZlibBaseStream.UncompressString(compressed, decompressor);
-            }
-        }
-
-
-        /// <summary>
-        ///   Uncompress a ZLIB-compressed byte array into a byte array.
-        /// </summary>
-        ///
-        /// <seealso cref="ZlibStream.CompressBuffer(byte[])"/>
-        /// <seealso cref="ZlibStream.UncompressString(byte[])"/>
-        ///
-        /// <param name="compressed">
-        ///   A buffer containing ZLIB-compressed data.
-        /// </param>
-        ///
-        /// <returns>The data in uncompressed form</returns>
-        public static byte[] UncompressBuffer(byte[] compressed)
-        {
-            using (var input = new MemoryStream(compressed))
-            {
-                Stream decompressor =
-                    new ZlibStream( input, CompressionMode.Decompress );
-
-                return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
-            }
-        }
-
-    }
-
-
-}
\ No newline at end of file
diff --git a/EPPlus/Packaging/ZipPackage.cs b/EPPlus/Packaging/ZipPackage.cs
index 9c6c8b4..c47d5ea 100644
--- a/EPPlus/Packaging/ZipPackage.cs
+++ b/EPPlus/Packaging/ZipPackage.cs
@@ -34,10 +34,9 @@
 using System.Linq;
 using System.Text;
 using System.IO;
+using System.IO.Compression;
 using System.Xml;
 using OfficeOpenXml.Utils;
-using OfficeOpenXml.Packaging.Ionic.Zip;
-using Ionic.Zip;
 namespace OfficeOpenXml.Packaging
 {
     /// <summary>
@@ -93,82 +92,75 @@
             }
             else
             {
-                var rels = new Dictionary<string, string>();
-                stream.Seek(0, SeekOrigin.Begin);                
-                using (ZipInputStream zip = new ZipInputStream(stream))
+                var rels = new Dictionary<string, ZipArchiveEntry>();
+                stream.Seek(0, SeekOrigin.Begin);
+                using var zip = new ZipArchive(stream);
+                foreach (var e in zip.Entries)
                 {
-                    var e = zip.GetNextEntry();
-                    while (e != null)
+                    if (e.Length > 0)
                     {
-                        if (e.UncompressedSize > 0)
+                        if (e.FullName .Equals("[content_types].xml", StringComparison.InvariantCultureIgnoreCase))
                         {
-                            var b = new byte[e.UncompressedSize];
-                            var size = zip.Read(b, 0, (int)e.UncompressedSize);
-                            if (e.FileName.Equals("[content_types].xml", StringComparison.InvariantCultureIgnoreCase))
-                            {
-                                AddContentTypes(Encoding.UTF8.GetString(b));
-                                hasContentTypeXml = true;
-                            }
-                            else if (e.FileName.Equals("_rels/.rels", StringComparison.InvariantCultureIgnoreCase)) 
-                            {
-                                ReadRelation(Encoding.UTF8.GetString(b), "");
-                            }
-                            else
-                            {
-                                if (e.FileName.EndsWith(".rels", StringComparison.InvariantCultureIgnoreCase))
-                                {
-                                    rels.Add(GetUriKey(e.FileName), Encoding.UTF8.GetString(b));
-                                }
-                                else
-                                {
-                                    var part = new ZipPackagePart(this, e);
-                                    part.Stream = new MemoryStream();
-                                    part.Stream.Write(b, 0, b.Length);
-                                    Parts.Add(GetUriKey(e.FileName), part);
-                                }
-                            }
+                            using var inputStream = e.Open();
+                            AddContentTypes(inputStream);
+                            hasContentTypeXml = true;
+                        }
+                        else if (e.FullName .Equals("_rels/.rels", StringComparison.InvariantCultureIgnoreCase)) 
+                        {
+                            using var inputStream = e.Open();
+                            ReadRelation(inputStream, "");
                         }
                         else
                         {
+                            if (e.FullName.EndsWith(".rels", StringComparison.InvariantCultureIgnoreCase))
+                            {
+                                rels.Add(GetUriKey(e.FullName), e);
+                            }
+                            else
+                            {
+                                using var inputStream = e.Open();
+                                var part = new ZipPackagePart(this, e);
+                                part.Stream = new MemoryStream();
+                                inputStream.CopyTo(part.Stream);
+                                Parts.Add(GetUriKey(e.FullName), part);
+                            }
                         }
-                        e = zip.GetNextEntry();
                     }
-
-                    foreach (var p in Parts)
+                }
+                foreach (var p in Parts)
+                {
+                    string name = Path.GetFileName(p.Key);
+                    string extension = Path.GetExtension(p.Key);
+                    string relFile = string.Format("{0}_rels/{1}.rels", p.Key.Substring(0, p.Key.Length - name.Length), name);
+                    if (rels.TryGetValue(relFile, out var zipArchiveEntry))
                     {
-                        string name = Path.GetFileName(p.Key);
-                        string extension = Path.GetExtension(p.Key);
-                        string relFile = string.Format("{0}_rels/{1}.rels", p.Key.Substring(0, p.Key.Length - name.Length), name);
-                        if (rels.ContainsKey(relFile))
-                        {
-                            p.Value.ReadRelation(rels[relFile], p.Value.Uri.OriginalString);
-                        }
-                        if (_contentTypes.ContainsKey(p.Key))
-                        {
-                            p.Value.ContentType = _contentTypes[p.Key].Name;
-                        }
-                        else if (extension.Length > 1 && _contentTypes.ContainsKey(extension.Substring(1)))
-                        {
-                            p.Value.ContentType = _contentTypes[extension.Substring(1)].Name;
-                        }
+                        using var inputStream = zipArchiveEntry.Open();
+                        p.Value.ReadRelation(inputStream, p.Value.Uri.OriginalString);
                     }
-                    if (!hasContentTypeXml)
+                    if (_contentTypes.TryGetValue(p.Key, out var type))
                     {
-                        throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
+                        p.Value.ContentType = type.Name;
                     }
-                    if (!hasContentTypeXml)
+                    else if (extension.Length > 1 && _contentTypes.ContainsKey(extension.Substring(1)))
                     {
-                        throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
+                        p.Value.ContentType = _contentTypes[extension.Substring(1)].Name;
                     }
-                    zip.Close();
+                }
+                if (!hasContentTypeXml)
+                {
+                    throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
+                }
+                if (!hasContentTypeXml)
+                {
+                    throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
                 }
             }
         }
 
-        private void AddContentTypes(string xml)
+        private void AddContentTypes(Stream inputStream)
         {
             var doc = new XmlDocument();
-            XmlHelper.LoadXmlSafe(doc, xml, Encoding.UTF8);
+            XmlHelper.LoadXmlSafe(doc, inputStream);
 
             foreach (XmlElement c in doc.DocumentElement.ChildNodes)
             {
@@ -260,21 +252,21 @@
         }
         internal void Save(Stream stream)
         {
-            var enc = Encoding.UTF8;
-            ZipOutputStream os = new ZipOutputStream(stream, true);
-            os.CompressionLevel = (OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel)_compression;            
+            using var zipArchive = new ZipArchive(stream, ZipArchiveMode.Create);
             /**** ContentType****/
-            var entry = os.PutNextEntry("[Content_Types].xml");
-            byte[] b = enc.GetBytes(GetContentTypeXml());
-            os.Write(b, 0, b.Length);
+            var contentTypesEntry = zipArchive.CreateEntry("[Content_Types].xml");
+            using (var contentTypesWriter = new StreamWriter(contentTypesEntry.Open()))
+            {
+                contentTypesWriter.Write(GetContentTypeXml());
+            }
             /**** Top Rels ****/
-            _rels.WriteZip(os, "_rels\\.rels");
+            _rels.WriteZip(zipArchive, "_rels\\.rels");
             ZipPackagePart ssPart=null;
             foreach(var part in Parts.Values)
             {
                 if (part.ContentType != ExcelPackage.contentTypeSharedString)
                 {
-                    part.WriteZip(os);
+                    part.WriteZip(zipArchive);
                 }
                 else
                 {
@@ -284,12 +276,8 @@
             //Shared strings must be saved after all worksheets. The ss dictionary is populated when that workheets are saved (to get the best performance).
             if (ssPart != null)
             {
-                ssPart.WriteZip(os);
+                ssPart.WriteZip(zipArchive);
             }
-            os.Flush();
-            os.Close();
-            os.Dispose();  
-            
             //return ms;
         }
 
diff --git a/EPPlus/Packaging/ZipPackagePart.cs b/EPPlus/Packaging/ZipPackagePart.cs
index 5d45c35..06ca810 100644
--- a/EPPlus/Packaging/ZipPackagePart.cs
+++ b/EPPlus/Packaging/ZipPackagePart.cs
@@ -29,24 +29,20 @@
  * Jan Källman		Added		25-Oct-2012
  *******************************************************************************/
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 using System.IO;
-using OfficeOpenXml.Packaging.Ionic.Zip;
+using System.IO.Compression;
 
 namespace OfficeOpenXml.Packaging
 {
     internal class ZipPackagePart : ZipPackageRelationshipBase, IDisposable
     {
-        internal delegate void SaveHandlerDelegate(ZipOutputStream stream, CompressionLevel compressionLevel, string fileName);
+        internal delegate void SaveHandlerDelegate(StreamWriter streamWriter);
 
-        internal ZipPackagePart(ZipPackage package, ZipEntry entry)
+        internal ZipPackagePart(ZipPackage package, ZipArchiveEntry entry)
         {
             Package = package;
-            Entry = entry;
             SaveHandler = null;
-            Uri = new Uri(package.GetUriKey(entry.FileName), UriKind.Relative);
+            Uri = new Uri(package.GetUriKey(entry.FullName), UriKind.Relative);
         }
         internal ZipPackagePart(ZipPackage package, Uri partUri, string contentType, CompressionLevel compressionLevel)
         {
@@ -58,7 +54,6 @@
             CompressionLevel = compressionLevel;
         }
         internal ZipPackage Package { get; set; }
-        internal ZipEntry Entry { get; set; }
         internal CompressionLevel CompressionLevel;
         MemoryStream _stream = null;
         internal MemoryStream Stream
@@ -121,18 +116,12 @@
             }
         }
         public Uri Uri { get; private set; }
-        public Stream GetZipStream()
-        {
-            MemoryStream ms = new MemoryStream();
-            ZipOutputStream os = new ZipOutputStream(ms);
-            return os;
-        }
         internal SaveHandlerDelegate SaveHandler
         {
             get;
             set;
         }
-        internal void WriteZip(ZipOutputStream os)
+        internal void WriteZip(ZipArchive zipArchive)
         {
             byte[] b;
             if (SaveHandler == null)
@@ -142,20 +131,22 @@
                 {
                     return;
                 }
-                os.CompressionLevel = (OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel)CompressionLevel;
-                os.PutNextEntry(Uri.OriginalString);
-                os.Write(b, 0, b.Length);
+                var zipEntry = zipArchive.CreateEntry(Uri.OriginalString);
+                using var os = zipEntry.Open();
+                os.Write(b);
             }
             else
             {
-                SaveHandler(os, (CompressionLevel)CompressionLevel, Uri.OriginalString);
+                var zipEntry = zipArchive.CreateEntry(Uri.OriginalString);
+                using var streamWriter = new StreamWriter(zipEntry.Open());
+                SaveHandler(streamWriter);
             }
 
             if (_rels.Count > 0)
             {
                 string f = Uri.OriginalString;
                 var name = Path.GetFileName(f);
-                _rels.WriteZip(os, (string.Format("{0}_rels/{1}.rels", f.Substring(0, f.Length - name.Length), name)));
+                _rels.WriteZip(zipArchive, $"{f.Substring(0, f.Length - name.Length)}_rels/{name}.rels");
             }
             b = null;
         }
diff --git a/EPPlus/Packaging/ZipPackageRelationship.cs b/EPPlus/Packaging/ZipPackageRelationship.cs
index 2c04a28..7bb7a50 100644
--- a/EPPlus/Packaging/ZipPackageRelationship.cs
+++ b/EPPlus/Packaging/ZipPackageRelationship.cs
@@ -29,9 +29,6 @@
  * Jan Källman		Added		25-Oct-2012
  *******************************************************************************/
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 
 namespace OfficeOpenXml.Packaging
 {
diff --git a/EPPlus/Packaging/ZipPackageRelationshipBase.cs b/EPPlus/Packaging/ZipPackageRelationshipBase.cs
index 60b6948..b0bd124 100644
--- a/EPPlus/Packaging/ZipPackageRelationshipBase.cs
+++ b/EPPlus/Packaging/ZipPackageRelationshipBase.cs
@@ -29,21 +29,15 @@
  * Jan Källman		Added		25-Oct-2012
  *******************************************************************************/
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Ionic.Zip;
 using System.IO;
 using System.Xml;
-using OfficeOpenXml.Packaging.Ionic.Zlib;
-using System.Web;
+
 namespace OfficeOpenXml.Packaging
 {
     public abstract class ZipPackageRelationshipBase
     {
         protected ZipPackageRelationshipCollection _rels = new ZipPackageRelationshipCollection();
-        protected internal 
-        int maxRId = 1;
+        protected internal int maxRId = 1;
         internal void DeleteRelationship(string id)
         {
             _rels.Remove(id);
@@ -89,10 +83,10 @@
         {
             return _rels[id];
         }
-        internal void ReadRelation(string xml, string source)
+        internal void ReadRelation(Stream inputStream, string source)
         {
             var doc = new XmlDocument();
-            XmlHelper.LoadXmlSafe(doc, xml, Encoding.UTF8);
+            XmlHelper.LoadXmlSafe(doc, inputStream);
 
             foreach (XmlElement c in doc.DocumentElement.ChildNodes)
             {
diff --git a/EPPlus/Packaging/ZipPackageRelationshipCollection.cs b/EPPlus/Packaging/ZipPackageRelationshipCollection.cs
index df1ce86..0820322 100644
--- a/EPPlus/Packaging/ZipPackageRelationshipCollection.cs
+++ b/EPPlus/Packaging/ZipPackageRelationshipCollection.cs
@@ -30,12 +30,9 @@
  *******************************************************************************/
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Ionic.Zip;
 using System.IO;
+using System.IO.Compression;
 using System.Security;
-using OfficeOpenXml.Packaging.Ionic.Zip;
 
 namespace OfficeOpenXml.Packaging
 {
@@ -84,18 +81,17 @@
             return ret;
         }
 
-        internal void WriteZip(ZipOutputStream os, string fileName)
+        internal void WriteZip(ZipArchive zipArchive, string filename)
         {
-            StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
+            var entry = zipArchive.CreateEntry(filename);
+            using var writer = new StreamWriter(entry.Open());
+                
+            writer.Write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
             foreach (var rel in _rels.Values)
             {
-                xml.AppendFormat("<Relationship Id=\"{0}\" Type=\"{1}\" Target=\"{2}\"{3}/>", SecurityElement.Escape(rel.Id), rel.RelationshipType, SecurityElement.Escape(rel.TargetUri.OriginalString), rel.TargetMode == TargetMode.External ? " TargetMode=\"External\"" : "");
+                writer.Write("<Relationship Id=\"{0}\" Type=\"{1}\" Target=\"{2}\"{3}/>", SecurityElement.Escape(rel.Id), rel.RelationshipType, SecurityElement.Escape(rel.TargetUri.OriginalString), rel.TargetMode == TargetMode.External ? " TargetMode=\"External\"" : "");
             }
-            xml.Append("</Relationships>");
-
-            os.PutNextEntry(fileName);
-            byte[] b = Encoding.UTF8.GetBytes(xml.ToString());
-            os.Write(b, 0, b.Length);
+            writer.Write("</Relationships>");
         }
 
         public int Count