/// <summary>Adds one or more files to the list of files to be packed</summary>
        /// <param name="packagePath">Path to the package that assets are read from</param>
        /// <param name="packageFiles">Enumerable list with the paths of the files to add</param>
        public static void Build(string packagePath, IEnumerable <PackageFile> packageFiles)
        {
            List <PackageFileHeader> packageFileHeaders = setupPackageFileHeaders(packageFiles);

            using (
                FileStream package = new FileStream(
                    packagePath, FileMode.Create, FileAccess.Write, FileShare.None
                    )
                ) {
                BinaryWriter packageWriter = new BinaryWriter(package);
                packageWriter.Write(packageFileHeaders.Count);

                // Write the preliminary headers to the package (we don't know some informations,
                // like the compressed file sizes, yet). The headers will be written a second
                // time after the data offsets and compressed file sizes have been filled in.
                foreach (PackageFileHeader packageFileHeader in packageFileHeaders)
                {
                    packageFileHeader.Write(packageWriter);
                }

                // Compress all files and write them into the package, filling the missing fields
                // in the package file headers in the process.
                int index = 0;
                foreach (PackageFile packageFile in packageFiles)
                {
                    using (
                        FileStream asset = new FileStream(
                            packageFile.Path, FileMode.Open, FileAccess.Read, FileShare.Read
                            )
                        ) {
                        PackageFileHeader header = packageFileHeaders[index];
                        header.DataOffset         = package.Position;
                        header.CompressedLength   = compress(package, asset);
                        packageFileHeaders[index] = header;
                    }

                    ++index;
                }

                // Second run writing the package file headers, this time we know all the
                // informations. This relies on the headers not changing in size, so any
                // strings contained in the headers must not be modified.
                package.Position = 4;
                foreach (PackageFileHeader packageFileHeader in packageFileHeaders)
                {
                    packageFileHeader.Write(packageWriter);
                }
            }
        }
        public void Build()
        {
            List<PackageFileHeader> packageFileHeaders = new List<PackageFileHeader>(packageFiles.Count);

            using (FileStream package = new FileStream(packagePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
            {
                // Create a binary writer using ASCII in little-endian format
                BinaryWriter writer = new BinaryWriter(package);
                // The Package Header Section
                writer.Write(PACKAGE_ID, 0, 4);   // The Package ID
                writer.Write((int)0);             // File Count
                writer.Write((long)0);            // Offset to Package File Headers
                writer.Write((int)0);             // CRC

                // Compress and write the file data
                foreach (PackageFile packageFile in packageFiles)
                {
                    using (FileStream file = new FileStream(packageFile.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        FileInfo fileInfo = new FileInfo(packageFile.Path);
                        string relativePath = packageFile.Path.Substring(packageFile.Path.LastIndexOf("..\\Data\\"));
                        switch (fileInfo.Extension)
                        {
                            case ".pak":
                                // Check the file for the package file header ID
                                byte[] packageID = new byte[4];
                                file.Read(packageID, 0, 4);
                                file.Position = 0;
                                for (int i = 0; i < packageID.Length; ++i)
                                {
                                    if (packageID[i] != PACKAGE_ID[i])
                                        goto default;
                                }
                                // Skip packaged files
                                break;
                            case ".xml":
                                PackageFileHeader packageFileHeader = new PackageFileHeader(relativePath, package.Position, fileInfo.Length, true);

                                // Encrypt the file
                                MemoryStream encryptedFile = Encrypt(file, "mtT_;oV4)0Gw", "89ZB!]ekT(0d", "SHA1", 2, "3BgLd7#q{@@ZoR1E", KeySize.AES128);

                                // The size of the encrypted file can increase due to padding
                                packageFileHeader.UncompressedSize = encryptedFile.Length;

                                // Compress and write to package
                                //packageFileHeader.CompressedSize = Compress(package, encryptedFile);

                                package.Write(encryptedFile.ToArray(), 0, (int)encryptedFile.Length);
                                encryptedFile.Close();
                                packageFileHeaders.Add(packageFileHeader);
                                break;
                            default:
                                packageFileHeader = new PackageFileHeader(relativePath, package.Position, fileInfo.Length);

                                // Compress and write to package
                                //packageFileHeader.CompressedSize = Compress(package, file);

                                byte[] buffer = new byte[file.Length];
                                file.Read(buffer, 0, (int)file.Length);
                                package.Write(buffer, 0, (int)file.Length);
                                packageFileHeaders.Add(packageFileHeader);
                                break;
                        }
                    }
                }

                // Save the position of the first file header for the File Header section
                long offsetToHeaders = package.Position;

                // Write Headers
                foreach (PackageFileHeader header in packageFileHeaders)
                {
                    header.Write(writer);
                }
                writer.Flush();

                // Write the position of the first file header
                package.Position = PACKAGE_HEADER_FILE_COUNT_POSITION;
                writer.Write(packageFileHeaders.Count);
                writer.Write(offsetToHeaders);
                package.Flush();
            }
        }