/// <summary>
		/// Perform the initial read on an entry which may include 
		/// reading encryption headers and setting up inflation.
		/// </summary>
		/// <param name="destination">The destination to fill with data read.</param>
		/// <param name="offset">The offset to start reading at.</param>
		/// <param name="count">The maximum number of bytes to read.</param>
		/// <returns>The actual number of bytes read.</returns>
		private int InitialRead(byte[] destination, int offset, int count)
		{
			if (!CanDecompressEntry)
			{
				throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version + ")");
			}

			// Handle encryption if required.
			if (entry.IsCrypted)
			{
#if NETCF_1_0
				throw new ZipException("Encryption not supported for Compact Framework 1.0");
#else
				if (password == null)
				{
					throw new ZipException("No password set.");
				}

				// Generate and set crypto transform...
				PkzipClassicManaged managed = new PkzipClassicManaged();
				byte[] key = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(password));

				inputBuffer.CryptoTransform = managed.CreateDecryptor(key, null);

				byte[] cryptbuffer = new byte[ZipConstants.CryptoHeaderSize];
				inputBuffer.ReadClearTextBuffer(cryptbuffer, 0, ZipConstants.CryptoHeaderSize);

				if (cryptbuffer[ZipConstants.CryptoHeaderSize - 1] != entry.CryptoCheckValue)
				{
					throw new ZipException("Invalid password");
				}

				if (csize >= ZipConstants.CryptoHeaderSize)
				{
					csize -= ZipConstants.CryptoHeaderSize;
				}
				else if ((entry.Flags & (int) GeneralBitFlags.Descriptor) == 0)
				{
					throw new ZipException(string.Format("Entry compressed size {0} too small for encryption", csize));
				}
#endif
			}
			else
			{
#if !NETCF_1_0
				inputBuffer.CryptoTransform = null;
#endif
			}

			if ((method == (int) CompressionMethod.Deflated) && (inputBuffer.Available > 0))
			{
				inputBuffer.SetInflaterInput(inf);
			}

			internalReader = BodyRead;
			return BodyRead(destination, offset, count);
		}
		private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry)
		{
			CryptoStream result = null;

			if ((entry.Version < ZipConstants.VersionStrongEncryption)
			    || (entry.Flags & (int) GeneralBitFlags.StrongEncryption) == 0)
			{
				PkzipClassicManaged classicManaged = new PkzipClassicManaged();

				OnKeysRequired(entry.Name);
				if (HaveKeys == false)
				{
					throw new ZipException("No password available for encrypted stream");
				}

				result = new CryptoStream(baseStream, classicManaged.CreateDecryptor(key, null), CryptoStreamMode.Read);
				CheckClassicPassword(result, entry);
			}
			else
			{
				throw new ZipException("Decryption method not supported");
			}

			return result;
		}
		private Stream CreateAndInitEncryptionStream(Stream baseStream, ZipEntry entry)
		{
			CryptoStream result = null;
			if ((entry.Version < ZipConstants.VersionStrongEncryption)
			    || (entry.Flags & (int) GeneralBitFlags.StrongEncryption) == 0)
			{
				PkzipClassicManaged classicManaged = new PkzipClassicManaged();

				OnKeysRequired(entry.Name);
				if (HaveKeys == false)
				{
					throw new ZipException("No password available for encrypted stream");
				}

				// Closing a CryptoStream will close the base stream as well so wrap it in an UncompressedStream
				// which doesnt do this.
				result = new CryptoStream(new UncompressedStream(baseStream),
				                          classicManaged.CreateEncryptor(key, null), CryptoStreamMode.Write);

				if ((entry.Crc < 0) || (entry.Flags & 8) != 0)
				{
					WriteEncryptionHeader(result, entry.DosTime << 16);
				}
				else
				{
					WriteEncryptionHeader(result, entry.Crc);
				}
			}
			return result;
		}
		/// <summary>
		/// Initializes encryption keys based on given password
		/// </summary>
		/// <param name="password">The password.</param>
		protected void InitializePassword(string password)
		{
#if NETCF_1_0
			keys = new uint[] {
				0x12345678,
				0x23456789,
				0x34567890
			};
			
			byte[] rawPassword = ZipConstants.ConvertToArray(password);
			
			for (int i = 0; i < rawPassword.Length; ++i) {
				UpdateKeys((byte)rawPassword[i]);
			}

#else
			PkzipClassicManaged pkManaged = new PkzipClassicManaged();
			byte[] key = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(password));
			cryptoTransform_ = pkManaged.CreateEncryptor(key, null);
#endif
		}