context: using System;
  using System.IO;
  
  namespace ICSharpCode.SharpZipLib.Zip
  {
  	/// <summary>
  	/// Defines known values for the <see cref="HostSystemID"/> property.
  	/// </summary>
  	public enum HostSystemID
  	{
  		/// <summary>
  		/// Host system = MSDOS
  		/// </summary>
  		Msdos = 0,
  		/// <summary>
  		/// Host system = Amiga
  		/// </summary>
  		Amiga = 1,
  		/// <summary>
  		/// Host system = Open VMS
  		/// </summary>
  		OpenVms = 2,
  		/// <summary>
  		/// Host system = Unix
  		/// </summary>
  		Unix = 3,
  		/// <summary>
  		/// Host system = VMCms
  		/// </summary>
  		VMCms = 4,
  		/// <summary>
  		/// Host system = Atari ST
  		/// </summary>
  		AtariST = 5,
  		/// <summary>
  		/// Host system = OS2
  		/// </summary>
  		OS2 = 6,
  		/// <summary>
  		/// Host system = Macintosh
  		/// </summary>
  		Macintosh = 7,
  		/// <summary>
  		/// Host system = ZSystem
  		/// </summary>
  		ZSystem = 8,
  		/// <summary>
  		/// Host system = Cpm
  		/// </summary>
  		Cpm = 9,
  		/// <summary>
  		/// Host system = Windows NT
  		/// </summary>
  		WindowsNT = 10,
  		/// <summary>
  		/// Host system = MVS
  		/// </summary>
  		MVS = 11,
  		/// <summary>
  		/// Host system = VSE
  		/// </summary>
  		Vse = 12,
  		/// <summary>
  		/// Host system = Acorn RISC
  		/// </summary>
  		AcornRisc = 13,
  		/// <summary>
  		/// Host system = VFAT
  		/// </summary>
  		Vfat = 14,
  		/// <summary>
  		/// Host system = Alternate MVS
  		/// </summary>
  		AlternateMvs = 15,
  		/// <summary>
  		/// Host system = BEOS
  		/// </summary>
  		BeOS = 16,
  		/// <summary>
  		/// Host system = Tandem
  		/// </summary>
  		Tandem = 17,
  		/// <summary>
  		/// Host system = OS400
  		/// </summary>
  		OS400 = 18,
  		/// <summary>
  		/// Host system = OSX
  		/// </summary>
  		OSX = 19,
  		/// <summary>
  		/// Host system = WinZIP AES
  		/// </summary>
  		WinZipAES = 99,
  	}
  
  	/// <summary>
  	/// This class represents an entry in a zip archive.  This can be a file
  	/// or a directory
  	/// ZipFile and ZipInputStream will give you instances of this class as 
  	/// information about the members in an archive.  ZipOutputStream
  	/// uses an instance of this class when creating an entry in a Zip file.
  	/// <br/>
  	/// <br/>Author of the original java version : Jochen Hoenicke
  	/// </summary>
  	public class ZipEntry
  	{
  		[Flags]
  		enum Known : byte
  		{
  			None = 0,
  			Size = 0x01,
  			CompressedSize = 0x02,
  			Crc = 0x04,
  			Time = 0x08,
  			ExternalAttributes = 0x10,
  		}
  
  		#region Constructors
  		/// <summary>
  		/// Creates a zip entry with the given name.
  		/// </summary>
  		/// <param name="name">
  		/// The name for this entry. Can include directory components.
  		/// The convention for names is 'unix' style paths with relative names only.
  		/// There are with no device names and path elements are separated by '/' characters.
  		/// </param>
  		/// <exception cref="ArgumentNullException">
  		/// The name passed is null
  		/// </exception>
  		public ZipEntry(string name)
  			: this(name, 0, ZipConstants.VersionMadeBy, CompressionMethod.Deflated)
  		{
  		}
  
  		/// <summary>
  		/// Creates a zip entry with the given name and version required to extract
  		/// </summary>
  		/// <param name="name">
  		/// The name for this entry. Can include directory components.
  		/// The convention for names is 'unix'  style paths with no device names and 
  		/// path elements separated by '/' characters.  This is not enforced see <see cref="CleanName(string)">CleanName</see>
  		/// on how to ensure names are valid if this is desired.
  		/// </param>
  		/// <param name="versionRequiredToExtract">
  		/// The minimum 'feature version' required this entry
  		/// </param>
  		/// <exception cref="ArgumentNullException">
  		/// The name passed is null
  		/// </exception>
  		internal ZipEntry(string name, int versionRequiredToExtract)
  			: this(name, versionRequiredToExtract, ZipConstants.VersionMadeBy,
  			CompressionMethod.Deflated)
  		{
  		}
  
  		/// <summary>
  		/// Initializes an entry with the given name and made by information
  		/// </summary>
  		/// <param name="name">Name for this entry</param>
  		/// <param name="madeByInfo">Version and HostSystem Information</param>
  		/// <param name="versionRequiredToExtract">Minimum required zip feature version required to extract this entry</param>
  		/// <param name="method">Compression method for this entry.</param>
  		/// <exception cref="ArgumentNullException">
  		/// The name passed is null
  		/// </exception>
  		/// <exception cref="ArgumentOutOfRangeException">
  		/// versionRequiredToExtract should be 0 (auto-calculate) or > 10
  		/// </exception>
  		/// <remarks>
  		/// This constructor is used by the ZipFile class when reading from the central header
  		/// It is not generally useful, use the constructor specifying the name only.
  		/// </remarks>
  		internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo,
  			CompressionMethod method)
  		{
  			if (name == null) {
  				throw new ArgumentNullException(nameof(name));
  			}
  
  			if (name.Length > 0xffff) {
  				throw new ArgumentException("Name is too long", nameof(name));
  			}
  
  			if ((versionRequiredToExtract != 0) && (versionRequiredToExtract < 10)) {
  				throw new ArgumentOutOfRangeException(nameof(versionRequiredToExtract));
  			}
  
  			this.DateTime = DateTime.Now;
  			this.name = CleanName(name);
  			this.versionMadeBy = (ushort)madeByInfo;
  			this.versionToExtract = (ushort)versionRequiredToExtract;
  			this.method = method;
  
  			IsUnicodeText = ZipStrings.UseUnicode;
  		}
  
  		/// <summary>
  		/// Creates a deep copy of the given zip entry.
  		/// </summary>
  		/// <param name="entry">
  		/// The entry to copy.
  		/// </param>
  		[Obsolete("Use Clone instead")]
  		public ZipEntry(ZipEntry entry)
  		{
  			if (entry == null) {
  				throw new ArgumentNullException(nameof(entry));
  			}
  
  			known = entry.known;
  			name = entry.name;
  			size = entry.size;
  			compressedSize = entry.compressedSize;
  			crc = entry.crc;
  			dosTime = entry.dosTime;
  			method = entry.method;
  			comment = entry.comment;
  			versionToExtract = entry.versionToExtract;
  			versionMadeBy = entry.versionMadeBy;
  			externalFileAttributes = entry.externalFileAttributes;
  			flags = entry.flags;
  
  			zipFileIndex = entry.zipFileIndex;
  			offset = entry.offset;
  
  			forceZip64_ = entry.forceZip64_;
  
  			if (entry.extra != null) {
  				extra = new byte[entry.extra.Length];
  				Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length);
  			}
  		}
  
  		#endregion
  
  		/// <summary>
  		/// Get a value indicating wether the entry has a CRC value available.
  		/// </summary>
  		public bool HasCrc {
  			get {
  				return (known & Known.Crc) != 0;
  			}
  		}
  
  		/// <summary>
  		/// Get/Set flag indicating if entry is encrypted.
  		/// A simple helper routine to aid interpretation of <see cref="Flags">flags</see>
  		/// </summary>
  		/// <remarks>This is an assistant that interprets the <see cref="Flags">flags</see> property.</remarks>
  		public bool IsCrypted {
  			get {
  				return (flags & 1) != 0;
  			}
  			set {
  
gt: 				if (value) {