private static Metadata readMetadataTable(FileStream metadataStream, int offset)
 {
     MetadataTableInfo info = readMetadataTableInfo(metadataStream, offset);
     List<Tuple<int, byte[]>> table = new List<Tuple<int, byte[]>>();
     int offs_acc = info.tableOffset.value;
     for(int i=0; i<info.numEntries; i++)
     {
         table.Add(readMetadataEntry(metadataStream, offs_acc));
         offs_acc += metadataStream.ReadInt(offs_acc) + 4;
         offs_acc = HexTools.align(offs_acc); //word align
     }
     Metadata ret = new Metadata();
     ret.data = table;
     ret.info = info;
     return ret;
 }
        private static MetadataTableInfo readMetadataTableInfo(FileStream metadataStream, int offset)
        {
            MetadataTableInfo info = new MetadataTableInfo();

            info.identifier = metadataStream.ReadASCII(offset, IDENTIFIER_LENGTH);
            info.tableOffset = new Pointer(metadataStream.ReadData(offset + IDENTIFIER_LENGTH, 4));
            info.numEntries = metadataStream.ReadInt(offset + 4 + IDENTIFIER_LENGTH);
            info.totalLength = metadataStream.ReadInt(offset + 8 + IDENTIFIER_LENGTH);

            return info;
        }
        /*public byte[] getAt(int offset, int length)
        {
            //Returns [offset, offset+length)

        }
        public byte[] getDereferenceOf(int offset, int length)
        {
            //Returns [*offset, *offset+length)

        }*/
        private static Tuple<int, byte[]> readMetadataEntry(FileStream metadataStream, int offset)
        {
            //Returns [*(offset+4), *(offset+4)+*offset)
            return Tuple.Create(metadataStream.ReadInt(offset),
                metadataStream.ReadData(offset + 4, metadataStream.ReadInt(offset)));
        }