/// <summary>
        /// UnZip files from zip archive in a stream.
        /// </summary>
        /// <param name="zipStream">Zip archive stream.</param>
        /// <returns>Each file in the archive.</returns>
        public static IEnumerable <UncompressedFile> UnZip(Stream zipStream)
        {
            BinaryReader  binaryReader  = new BinaryReader(zipStream);
            LimitedStream limitedStream = new LimitedStream(zipStream, 0);

            while (true)
            {
                uint signature = binaryReader.ReadUInt32();

                if (signature == 0x02014b50)
                {
                    break;
                }

                if (signature != 0x04034b50)
                {
                    throw new ApplicationException("Zip file is broken or corrupt");
                }

                binaryReader.ReadBytes(2);
                ushort flags = binaryReader.ReadUInt16();

                if ((flags & (1 << 3)) != 0)
                {
                    throw new ApplicationException("Unsupported Zip file format (compressed size not available in header");
                }

                ushort method = binaryReader.ReadUInt16();
                binaryReader.ReadBytes(8);
                uint compressedSize = binaryReader.ReadUInt32();
                binaryReader.ReadBytes(4);
                ushort fileNameLength   = binaryReader.ReadUInt16();
                ushort extraFieldLength = binaryReader.ReadUInt16();

                string filename = Encoding.ASCII.GetString(binaryReader.ReadBytes(fileNameLength)).Replace('/', Path.DirectorySeparatorChar);
                binaryReader.ReadBytes(extraFieldLength);

                limitedStream.Limit = compressedSize;

                switch (method)
                {
                case 0:
                    // No compression
                    yield return(new UncompressedFile(filename, limitedStream));

                    break;

                case 8:
                    // Deflate
                    DeflateStream deflateStream = new DeflateStream(limitedStream, CompressionMode.Decompress, true);
                    yield return(new UncompressedFile(filename, deflateStream));

                    break;

                default:
                    // Ignore...
                    break;
                }

                limitedStream.SeekToEnd();
            }

            limitedStream.Close();
            binaryReader.Close();
        }