private StructureValueCollection SerializePage(ResourcePage page, ThirdGenCacheFileReference[] externalFiles)
 {
     var result = new StructureValueCollection();
     result.SetInteger("salt", page.Salt);
     result.SetInteger("flags", page.Flags);
     result.SetInteger("compression codec index",
         (page.CompressionMethod != ResourcePageCompression.None) ? 0 : 0xFFFFFFFF);
     result.SetInteger("shared cache file index",
         (page.FilePath != null) ? (uint) FindExternalFile(externalFiles, page.FilePath) : 0xFFFFFFFF);
     result.SetInteger("unknown 1", (uint) page.Unknown1);
     result.SetInteger("compressed block offset", (uint) page.Offset);
     result.SetInteger("compressed block size", (uint) page.CompressedSize);
     result.SetInteger("uncompressed block size", (uint) page.UncompressedSize);
     result.SetInteger("checksum", page.Checksum);
     result.SetRaw("hash 1", page.Hash1);
     result.SetRaw("hash 2", page.Hash2);
     result.SetRaw("hash 3", page.Hash3);
     result.SetInteger("unknown 2", (uint) page.Unknown2);
     result.SetInteger("unknown 3", (uint) page.Unknown3);
     return result;
 }
 private int FindExternalFile(ThirdGenCacheFileReference[] externalFiles, string path)
 {
     for (int i = 0; i < externalFiles.Length; i++)
     {
         if (externalFiles[i].Path.Equals(path, StringComparison.InvariantCultureIgnoreCase))
             return i;
     }
     throw new InvalidOperationException("Invalid shared map path \"" + path + "\"");
 }
 private ResourcePage LoadPage(StructureValueCollection values, int index, ThirdGenCacheFileReference[] externalFiles)
 {
     var result = new ResourcePage();
     result.Index = index;
     result.Salt = (ushort) values.GetInteger("salt");
     result.Flags = (byte) values.GetInteger("flags");
     result.CompressionMethod = ((int) values.GetInteger("compression codec index") != -1)
         ? ResourcePageCompression.Deflate
         : ResourcePageCompression.None; // FIXME: hax/laziness
     var externalFile = (int) values.GetInteger("shared cache file index");
     result.FilePath = (externalFile != -1) ? externalFiles[externalFile].Path : null;
     result.Unknown1 = (int) values.GetIntegerOrDefault("unknown 1", 0);
     result.Offset = (int) values.GetInteger("compressed block offset");
     result.CompressedSize = (int) values.GetInteger("compressed block size");
     result.UncompressedSize = (int) values.GetInteger("uncompressed block size");
     result.Checksum = values.GetInteger("checksum");
     result.Hash1 = values.GetRaw("hash 1");
     result.Hash2 = values.GetRaw("hash 2");
     result.Hash3 = values.GetRaw("hash 3");
     result.Unknown2 = (int) values.GetIntegerOrDefault("unknown 2", 0);
     result.Unknown3 = (int) values.GetIntegerOrDefault("unknown 3", 0);
     return result;
 }