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
