// This file was generated by Code Generator.
// 2003/08/17 20:11:24

using System;
using System.Text;

namespace Girl.PEAnalyzer
{
	public enum MetadataTables
	{
		Module = 0x00,
		TypeRef = 0x01,
		TypeDef = 0x02,
		Field = 0x04,
		MethodDef = 0x06,
		Param = 0x08,
		InterfaceImpl = 0x09,
		MemberRef = 0x0A,
		Constant = 0x0B,
		CustomAttribute = 0x0C,
		FieldMarshal = 0x0D,
		DeclSecurity = 0x0E,
		ClassLayout = 0x0F,
		FieldLayout = 0x10,
		StandAloneSig = 0x11,
		EventMap = 0x12,
		Event = 0x14,
		PropertyMap = 0x15,
		Property = 0x17,
		MethodSemantics = 0x18,
		MethodImpl = 0x19,
		ModuleRef = 0x1A,
		TypeSpec = 0x1B,
		ImplMap = 0x1C,
		FieldRVA = 0x1D,
		Assembly = 0x20,
		AssemblyProcessor = 0x21,
		AssemblyOS = 0x22,
		AssemblyRef = 0x23,
		AssemblyRefProcessor = 0x24,
		AssemblyRefOS = 0x25,
		File = 0x26,
		ExportedType = 0x27,
		ManifestResource = 0x28,
		NestedClass = 0x29,
		NotUsed = 0x3f
	}

	public class MetadataTableCreator
	{
		public static TableBase Create(MetadataTables tbl)
		{
			switch (tbl)
			{
				case MetadataTables.Assembly:
					return new AssemblyTable();
				case MetadataTables.AssemblyOS:
					return new AssemblyOSTable();
				case MetadataTables.AssemblyProcessor:
					return new AssemblyProcessorTable();
				case MetadataTables.AssemblyRef:
					return new AssemblyRefTable();
				case MetadataTables.AssemblyRefOS:
					return new AssemblyRefOSTable();
				case MetadataTables.AssemblyRefProcessor:
					return new AssemblyRefProcessorTable();
				case MetadataTables.ClassLayout:
					return new ClassLayoutTable();
				case MetadataTables.Constant:
					return new ConstantTable();
				case MetadataTables.CustomAttribute:
					return new CustomAttributeTable();
				case MetadataTables.DeclSecurity:
					return new DeclSecurityTable();
				case MetadataTables.EventMap:
					return new EventMapTable();
				case MetadataTables.Event:
					return new EventTable();
				case MetadataTables.ExportedType:
					return new ExportedTypeTable();
				case MetadataTables.Field:
					return new FieldTable();
				case MetadataTables.FieldLayout:
					return new FieldLayoutTable();
				case MetadataTables.FieldMarshal:
					return new FieldMarshalTable();
				case MetadataTables.FieldRVA:
					return new FieldRVATable();
				case MetadataTables.File:
					return new FileTable();
				case MetadataTables.ImplMap:
					return new ImplMapTable();
				case MetadataTables.InterfaceImpl:
					return new InterfaceImplTable();
				case MetadataTables.ManifestResource:
					return new ManifestResourceTable();
				case MetadataTables.MemberRef:
					return new MemberRefTable();
				case MetadataTables.MethodDef:
					return new MethodDefTable();
				case MetadataTables.MethodImpl:
					return new MethodImplTable();
				case MetadataTables.MethodSemantics:
					return new MethodSemanticsTable();
				case MetadataTables.Module:
					return new ModuleTable();
				case MetadataTables.ModuleRef:
					return new ModuleRefTable();
				case MetadataTables.NestedClass:
					return new NestedClassTable();
				case MetadataTables.Param:
					return new ParamTable();
				case MetadataTables.Property:
					return new PropertyTable();
				case MetadataTables.PropertyMap:
					return new PropertyMapTable();
				case MetadataTables.StandAloneSig:
					return new StandAloneSigTable();
				case MetadataTables.TypeDef:
					return new TypeDefTable();
				case MetadataTables.TypeRef:
					return new TypeRefTable();
				case MetadataTables.TypeSpec:
					return new TypeSpecTable();
			}
			return null;
		}
	}

	/// <summary>
	/// The Assembly table is defined using the .assembly directive
	/// (see Section 6.2); its columns are obtained from the
	/// respective .hash algorithm, .ver, .publickey, and .culture
	/// (see clause 6.2.1 For an example see Section 6.2.
	/// </summary>
	public class AssemblyTable : TableBase
	{
		/// <summary>
		/// a 4 byte constant of type AssemblyHashAlgorithm, clause
		/// 22.1.1
		/// </summary>
		public int HashAlgId;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short MajorVersion;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short MinorVersion;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short BuildNumber;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short RevisionNumber;

		/// <summary>
		/// a 4 byte bitmask of type AssemblyFlags, clause 22.1.2
		/// </summary>
		public int Flags;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int PublicKey;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Culture;

		public AssemblyTable()
		{
			title = "Assembly";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			HashAlgId = ReadInt32();
			MajorVersion = ReadInt16();
			MinorVersion = ReadInt16();
			BuildNumber = ReadInt16();
			RevisionNumber = ReadInt16();
			Flags = ReadInt32();
			PublicKey = ReadBlobIndex();
			Name = ReadStringsIndex();
			Culture = ReadStringsIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(HashAlgId, "HashAlgId: a 4 byte constant of type AssemblyHashAlgorithm, clause 22.1.1"));
			sb.Append(GetInfo(MajorVersion, "MajorVersion: 2 byte constants"));
			sb.Append(GetInfo(MinorVersion, "MinorVersion: 2 byte constants"));
			sb.Append(GetInfo(BuildNumber, "BuildNumber: 2 byte constants"));
			sb.Append(GetInfo(RevisionNumber, "RevisionNumber: 2 byte constants"));
			sb.Append(GetInfo(Flags, "Flags: a 4 byte bitmask of type AssemblyFlags, clause 22.1.2"));
			sb.Append(GetBlobIndexInfo(PublicKey, "PublicKey: index into Blob heap"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetStringsIndexInfo(Culture, "Culture: index into String heap"));
		}
	}

	/// <summary>
	/// This record should not be emitted into any PE file. If
	/// present in a PE file, it should be treated as if all its
	/// fields were zero. It should be ignored by the CLI.
	/// </summary>
	public class AssemblyOSTable : TableBase
	{
		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int OSPlatformID;

		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int OSMajorVersion;

		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int OSMinorVersion;

		public AssemblyOSTable()
		{
			title = "AssemblyOS";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			OSPlatformID = ReadInt32();
			OSMajorVersion = ReadInt32();
			OSMinorVersion = ReadInt32();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(OSPlatformID, "OSPlatformID: a 4 byte constant"));
			sb.Append(GetInfo(OSMajorVersion, "OSMajorVersion: a 4 byte constant"));
			sb.Append(GetInfo(OSMinorVersion, "OSMinorVersion: a 4 byte constant"));
		}
	}

	/// <summary>
	/// This record should not be emitted into any PE file. If
	/// present in a PE file, it should be treated as if its field
	/// were zero. It should be ignored by the CLI.
	/// </summary>
	public class AssemblyProcessorTable : TableBase
	{
		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int Processor;

		public AssemblyProcessorTable()
		{
			title = "AssemblyProcessor";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Processor = ReadInt32();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Processor, "Processor: a 4 byte constant"));
		}
	}

	/// <summary>
	/// The table is defined by the .assembly extern directive (see
	/// Section 6.3). Its columns are filled using directives
	/// similar to those of the Assembly table except for the
	/// PublicKeyOrToken column which is defined using the
	/// .publickeytoken directive. For an example see Section 6.3.
	/// </summary>
	public class AssemblyRefTable : TableBase
	{
		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short MajorVersion;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short MinorVersion;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short BuildNumber;

		/// <summary>
		/// 2 byte constants
		/// </summary>
		public short RevisionNumber;

		/// <summary>
		/// a 4 byte bitmask of type AssemblyFlags, clause 22.1.2
		/// </summary>
		public int Flags;

		/// <summary>
		/// index into Blob heap -- the public key or token that
		/// identifies the author of this Assembly
		/// </summary>
		public int PublicKeyOrToken;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Culture;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int HashValue;

		public AssemblyRefTable()
		{
			title = "AssemblyRef";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			MajorVersion = ReadInt16();
			MinorVersion = ReadInt16();
			BuildNumber = ReadInt16();
			RevisionNumber = ReadInt16();
			Flags = ReadInt32();
			PublicKeyOrToken = ReadBlobIndex();
			Name = ReadStringsIndex();
			Culture = ReadStringsIndex();
			HashValue = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(MajorVersion, "MajorVersion: 2 byte constants"));
			sb.Append(GetInfo(MinorVersion, "MinorVersion: 2 byte constants"));
			sb.Append(GetInfo(BuildNumber, "BuildNumber: 2 byte constants"));
			sb.Append(GetInfo(RevisionNumber, "RevisionNumber: 2 byte constants"));
			sb.Append(GetInfo(Flags, "Flags: a 4 byte bitmask of type AssemblyFlags, clause 22.1.2"));
			sb.Append(GetBlobIndexInfo(PublicKeyOrToken, "PublicKeyOrToken: index into Blob heap -- the public key or token that identifies the author of this Assembly"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetStringsIndexInfo(Culture, "Culture: index into String heap"));
			sb.Append(GetBlobIndexInfo(HashValue, "HashValue: index into Blob heap"));
		}
	}

	/// <summary>
	/// These records should not be emitted into any PE file. If
	/// present in a PE file, they should be treated as-if their
	/// fields were zero. They should be ignored by the CLI.
	/// </summary>
	public class AssemblyRefOSTable : TableBase
	{
		/// <summary>
		/// 4 byte constant
		/// </summary>
		public int OSPlatformId;

		/// <summary>
		/// 4 byte constant
		/// </summary>
		public int OSMajorVersion;

		/// <summary>
		/// 4 byte constant
		/// </summary>
		public int OSMinorVersion;

		/// <summary>
		/// index into the AssemblyRef table
		/// </summary>
		public int AssemblyRef;

		public AssemblyRefOSTable()
		{
			title = "AssemblyRefOS";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			OSPlatformId = ReadInt32();
			OSMajorVersion = ReadInt32();
			OSMinorVersion = ReadInt32();
			AssemblyRef = ReadIndex(MetadataTables.AssemblyRef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(OSPlatformId, "OSPlatformId: 4 byte constant"));
			sb.Append(GetInfo(OSMajorVersion, "OSMajorVersion: 4 byte constant"));
			sb.Append(GetInfo(OSMinorVersion, "OSMinorVersion: 4 byte constant"));
			sb.Append(GetInfo(AssemblyRef, MetadataTables.AssemblyRef, "AssemblyRef: index into the AssemblyRef table"));
		}
	}

	/// <summary>
	/// These records should not be emitted into any PE file. If
	/// present in a PE file, they should be treated as-if their
	/// fields were zero. They should be ignored by the CLI.
	/// </summary>
	public class AssemblyRefProcessorTable : TableBase
	{
		/// <summary>
		/// 4 byte constant
		/// </summary>
		public int Processor;

		/// <summary>
		/// index into the AssemblyRef table
		/// </summary>
		public int AssemblyRef;

		public AssemblyRefProcessorTable()
		{
			title = "AssemblyRefProcessor";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Processor = ReadInt32();
			AssemblyRef = ReadIndex(MetadataTables.AssemblyRef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Processor, "Processor: 4 byte constant"));
			sb.Append(GetInfo(AssemblyRef, MetadataTables.AssemblyRef, "AssemblyRef: index into the AssemblyRef table"));
		}
	}

	/// <summary>
	/// The ClassLayout table is used to define how the fields of a
	/// class or value type shall be laid out by the CLI (normally,
	/// the CLI is free to reorder and/or insert gaps between the
	/// fields defined for a class or value type).
	/// The rows of the ClassLayout table are defined by placing
	/// .pack and .size directives on the body of a parent type
	/// declaration (see Section 9.2). For an example see Section
	/// 9.7.
	/// </summary>
	public class ClassLayoutTable : TableBase
	{
		/// <summary>
		/// a 2 byte constant
		/// </summary>
		public short PackingSize;

		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int ClassSize;

		/// <summary>
		/// index into TypeDef table
		/// </summary>
		public int Parent;

		public ClassLayoutTable()
		{
			title = "ClassLayout";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			PackingSize = ReadInt16();
			ClassSize = ReadInt32();
			Parent = ReadIndex(MetadataTables.TypeDef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(PackingSize, "PackingSize: a 2 byte constant"));
			sb.Append(GetInfo(ClassSize, "ClassSize: a 4 byte constant"));
			sb.Append(GetInfo(Parent, MetadataTables.TypeDef, "Parent: index into TypeDef table"));
		}
	}

	/// <summary>
	/// The Constant table is used to store compile-time, constant
	/// values for fields, parameters and properties.
	/// Note that Constant information does not directly influence
	/// runtime behavior, although it is visible via Reflection (and
	/// hence may be used to implement functionality such as that
	/// provided by System.Enum.ToString). Compilers inspect this
	/// information, at compile time, when importing metadata; but
	/// the value of the constant itself, if used, becomes embedded
	/// into the CIL stream the compiler emits. There are no CIL
	/// instructions to access the Constant table at runtime.
	/// A row in the Constant table for a parent is created whenever
	/// a compile-time value is specified for that parent, for an
	/// example see Section 15.2.
	/// </summary>
	public class ConstantTable : TableBase
	{
		/// <summary>
		/// a 1 byte constant, followed by a 1-byte padding zero
		/// </summary>
		public byte Type;

		/// <summary>
		/// index into the Param or Field or Property table; more
		/// precisely, a HasConstant coded index
		/// </summary>
		public int Parent;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int Value;

		public ConstantTable()
		{
			title = "Constant";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Type = ReadByte();
			Parent = ReadIndex(CodedIndices.HasConstant);
			Value = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Type, "Type: a 1 byte constant, followed by a 1-byte padding zero"));
			sb.Append(GetInfo(Parent, CodedIndices.HasConstant, "Parent: index into the Param or Field or Property table; more precisely, a HasConstant coded index"));
			sb.Append(GetBlobIndexInfo(Value, "Value: index into Blob heap"));
		}
	}

	/// <summary>
	/// The CustomAttribute table stores data that can be used to
	/// instantiate a Custom Attribute (more precisely, an object of
	/// the specified Custom Attribute class) at runtime. The column
	/// called Type is slightly misleading -- it actually indexes a
	/// constructor method -- the owner of that constructor method
	/// is the Type of the Custom Attribute.
	/// A row in the CustomAttribute table for a parent is created
	/// by the .custom attribute, which gives the value of the Type
	/// column and optionally that of the Value column (see Chapter
	/// 20)
	/// </summary>
	public class CustomAttributeTable : TableBase
	{
		/// <summary>
		/// index into any metadata table, except the CustomAttribute
		/// table itself; more precisely, a HasCustomAttribute coded
		/// index
		/// </summary>
		public int Parent;

		/// <summary>
		/// index into the MethodDef or MethodRef table; more precisely,
		/// a CustomAttributeType coded index
		/// </summary>
		public int Type;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int Value;

		public CustomAttributeTable()
		{
			title = "CustomAttribute";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Parent = ReadIndex(CodedIndices.HasCustomAttribute);
			Type = ReadIndex(CodedIndices.CustomAttributeType);
			Value = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Parent, CodedIndices.HasCustomAttribute, "Parent: index into any metadata table, except the CustomAttribute table itself; more precisely, a HasCustomAttribute coded index"));
			sb.Append(GetInfo(Type, CodedIndices.CustomAttributeType, "Type: index into the MethodDef or MethodRef table; more precisely, a CustomAttributeType coded index"));
			sb.Append(GetBlobIndexInfo(Value, "Value: index into Blob heap"));
		}
	}

	/// <summary>
	/// The rows of the DeclSecurity table are filled by attaching a
	/// .permission or .permissionset directive that specifies the
	/// Action and PermissionSet on a parent assembly (see Section
	/// 6.6) or parent type or method (see Section 9.2).
	/// </summary>
	public class DeclSecurityTable : TableBase
	{
		/// <summary>
		/// 2 byte value
		/// </summary>
		public short Action;

		/// <summary>
		/// index into the TypeDef, MethodDef or Assembly table
		/// </summary>
		public int Parent;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int PermissionSet;

		public DeclSecurityTable()
		{
			title = "DeclSecurity";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Action = ReadInt16();
			Parent = ReadIndex(MetadataTables.MethodDef);
			PermissionSet = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Action, "Action: 2 byte value"));
			sb.Append(GetInfo(Parent, MetadataTables.MethodDef, "Parent: index into the TypeDef, MethodDef or Assembly table"));
			sb.Append(GetBlobIndexInfo(PermissionSet, "PermissionSet: index into Blob heap"));
		}
	}

	/// <summary>
	/// Note that EventMap info does not directly influence runtime
	/// behavior; what counts is the info stored for each method
	/// that the event comprises.
	/// </summary>
	public class EventMapTable : TableBase
	{
		/// <summary>
		/// index into the TypeDef table
		/// </summary>
		public int Parent;

		/// <summary>
		/// index into Event table
		/// </summary>
		public int EventList;

		public EventMapTable()
		{
			title = "EventMap";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Parent = ReadIndex(MetadataTables.TypeDef);
			EventList = ReadIndex(MetadataTables.Event);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Parent, MetadataTables.TypeDef, "Parent: index into the TypeDef table"));
			sb.Append(GetInfo(EventList, MetadataTables.Event, "EventList: index into Event table"));
		}
	}

	/// <summary>
	/// Events are treated within metadata much like Properties -- a
	/// way to associate a collection of methods defined on given
	/// class. There are two required methods -- add_ and remove_,
	/// plus optional raise_ and others. All of the methods gathered
	/// together as an Event shall be defined on the class.
	/// Note that Event information does not directly influence
	/// runtime behavior; what counts is the information stored for
	/// each method that the event comprises.
	/// The EventMap and Event tables result from putting the .event
	/// directive on a class (see Chapter 17).
	/// </summary>
	public class EventTable : TableBase
	{
		/// <summary>
		/// a 2 byte bitmask of type EventAttribute, clause 22.1.4
		/// </summary>
		public short EventFlags;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into TypeDef, TypeRef or TypeSpec tables; more
		/// precisely, a TypeDefOrRef coded index
		/// </summary>
		public int EventType;

		public EventTable()
		{
			title = "Event";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			EventFlags = ReadInt16();
			Name = ReadStringsIndex();
			EventType = ReadIndex(CodedIndices.TypeDefOrRef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(EventFlags, "EventFlags: a 2 byte bitmask of type EventAttribute, clause 22.1.4"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetInfo(EventType, CodedIndices.TypeDefOrRef, "EventType: index into TypeDef, TypeRef or TypeSpec tables; more precisely, a TypeDefOrRef coded index"));
		}
	}

	/// <summary>
	/// The ExportedType table holds a row for each type, defined
	/// within other modules of this Assembly, that is exported out
	/// of this Assembly. In essence, it stores TypeDef row numbers
	/// of all types that are marked public in other modules that
	/// this Assembly comprises.
	/// The rows in the ExportedType table are the result of the
	/// .class extern directive (see Section 6.7).
	/// </summary>
	public class ExportedTypeTable : TableBase
	{
		/// <summary>
		/// a 4 byte bitmask of type TypeAttributes, clause 22.1.14
		/// </summary>
		public int Flags;

		/// <summary>
		/// 4 byte index into a TypeDef table of another module in this
		/// Assembly
		/// </summary>
		public int TypeDefId;

		/// <summary>
		/// index into the String heap
		/// </summary>
		public int TypeName;

		/// <summary>
		/// index into the String heap
		/// </summary>
		public int TypeNamespace;

		/// <summary>
		/// This can be an index (more precisely, an Implementation
		/// coded index) into one of 2 tables.
		/// </summary>
		public int Implementation;

		public ExportedTypeTable()
		{
			title = "ExportedType";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt32();
			TypeDefId = ReadIndex(MetadataTables.TypeDef);
			TypeName = ReadStringsIndex();
			TypeNamespace = ReadStringsIndex();
			Implementation = ReadIndex(CodedIndices.Implementation);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Flags, "Flags: a 4 byte bitmask of type TypeAttributes, clause 22.1.14"));
			sb.Append(GetInfo(TypeDefId, MetadataTables.TypeDef, "TypeDefId: 4 byte index into a TypeDef table of another module in this Assembly"));
			sb.Append(GetStringsIndexInfo(TypeName, "TypeName: index into the String heap"));
			sb.Append(GetStringsIndexInfo(TypeNamespace, "TypeNamespace: index into the String heap"));
			sb.Append(GetInfo(Implementation, CodedIndices.Implementation, "Implementation: This can be an index (more precisely, an Implementation coded index) into one of 2 tables."));
		}
	}

	/// <summary>
	/// Each row in the Field table results from a toplevel .field
	/// directive (see Section 5.10), or a .field directive inside a
	/// Type (see Section 9.2). For an example see Section 13.5.
	/// </summary>
	public class FieldTable : TableBase
	{
		/// <summary>
		/// a 2 byte bitmask of type FieldAttributes, clause 22.1.5
		/// </summary>
		public short Flags;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int Signature;

		public FieldTable()
		{
			title = "Field";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt16();
			Name = ReadStringsIndex();
			Signature = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Flags, "Flags: a 2 byte bitmask of type FieldAttributes, clause 22.1.5"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetBlobIndexInfo(Signature, "Signature: index into Blob heap"));
		}
	}

	/// <summary>
	/// A row in the FieldLayout table is created if the .field
	/// directive for the parent field has specified a field offset
	/// (see Section 9.7).
	/// </summary>
	public class FieldLayoutTable : TableBase
	{
		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int Offset;

		/// <summary>
		/// index into the Field table
		/// </summary>
		public int Field;

		public FieldLayoutTable()
		{
			title = "FieldLayout";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Offset = ReadInt32();
			Field = ReadIndex(MetadataTables.Field);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Offset, "Offset: a 4 byte constant"));
			sb.Append(GetInfo(Field, MetadataTables.Field, "Field: index into the Field table"));
		}
	}

	/// <summary>
	/// A row in the FieldMarshal table is created if the .field
	/// directive for the parent field has specified a .marshall
	/// attribute (see Section 15.1).
	/// </summary>
	public class FieldMarshalTable : TableBase
	{
		/// <summary>
		/// index into Field or Param table; more precisely, a
		/// HasFieldMarshal coded index
		/// </summary>
		public int Parent;

		/// <summary>
		/// index into the Blob heap
		/// </summary>
		public int NativeType;

		public FieldMarshalTable()
		{
			title = "FieldMarshal";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Parent = ReadIndex(CodedIndices.HasFieldMarshal);
			NativeType = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Parent, CodedIndices.HasFieldMarshal, "Parent: index into Field or Param table; more precisely, a HasFieldMarshal coded index"));
			sb.Append(GetBlobIndexInfo(NativeType, "NativeType: index into the Blob heap"));
		}
	}

	/// <summary>
	/// A row in the FieldRVA table is created for each static
	/// parent field that has specified the optional data label (see
	/// Chapter 15). The RVA column is the relative virtual address
	/// of the data in the PE file (see Section 15.3).
	/// </summary>
	public class FieldRVATable : TableBase
	{
		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int RVA;

		/// <summary>
		/// index into Field table
		/// </summary>
		public int Field;

		public FieldRVATable()
		{
			title = "FieldRVA";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			RVA = ReadInt32();
			Field = ReadIndex(MetadataTables.Field);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(RVA, "RVA: a 4 byte constant"));
			sb.Append(GetInfo(Field, MetadataTables.Field, "Field: index into Field table"));
		}
	}

	/// <summary>
	/// The rows of the File table result from .file directives in
	/// an Assembly (see clause 6.2.3)
	/// </summary>
	public class FileTable : TableBase
	{
		/// <summary>
		/// a 4 byte bitmask of type FileAttributes, clause 22.1.6
		/// </summary>
		public int Flags;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int HashValue;

		public FileTable()
		{
			title = "File";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt32();
			Name = ReadStringsIndex();
			HashValue = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Flags, "Flags: a 4 byte bitmask of type FileAttributes, clause 22.1.6"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetBlobIndexInfo(HashValue, "HashValue: index into Blob heap"));
		}
	}

	/// <summary>
	/// A row is entered in the ImplMap table for each parent Method
	/// (see Section 14.5) that is defined with a .pinvokeimpl
	/// interoperation attribute specifying the MappingFlags,
	/// ImportName and ImportScope. For an example see Section 14.5.
	/// </summary>
	public class ImplMapTable : TableBase
	{
		/// <summary>
		/// a 2 byte bitmask of type PInvokeAttributes, clause 22.1.7
		/// </summary>
		public short MappingFlags;

		/// <summary>
		/// index into the Field or MethodDef table; more precisely, a
		/// MemberForwarded coded index
		/// </summary>
		public int MemberForwarded;

		/// <summary>
		/// index into the String heap
		/// </summary>
		public int ImportName;

		/// <summary>
		/// index into the ModuleRef table
		/// </summary>
		public int ImportScope;

		public ImplMapTable()
		{
			title = "ImplMap";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			MappingFlags = ReadInt16();
			MemberForwarded = ReadIndex(CodedIndices.MemberForwarded);
			ImportName = ReadStringsIndex();
			ImportScope = ReadIndex(MetadataTables.ModuleRef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(MappingFlags, "MappingFlags: a 2 byte bitmask of type PInvokeAttributes, clause 22.1.7"));
			sb.Append(GetInfo(MemberForwarded, CodedIndices.MemberForwarded, "MemberForwarded: index into the Field or MethodDef table; more precisely, a MemberForwarded coded index"));
			sb.Append(GetStringsIndexInfo(ImportName, "ImportName: index into the String heap"));
			sb.Append(GetInfo(ImportScope, MetadataTables.ModuleRef, "ImportScope: index into the ModuleRef table"));
		}
	}

	/// <summary>
	/// The InterfaceImpl table records which interfaces a Type
	/// implements. Conceptually, each row in the InterfaceImpl
	/// table says that Class implements Interface.
	/// </summary>
	public class InterfaceImplTable : TableBase
	{
		/// <summary>
		/// index into the TypeDef table
		/// </summary>
		public int Class;

		/// <summary>
		/// index into the TypeDef, TypeRef or TypeSpec table; more
		/// precisely, a TypeDefOrRef coded index
		/// </summary>
		public int Interface;

		public InterfaceImplTable()
		{
			title = "InterfaceImpl";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Class = ReadIndex(MetadataTables.TypeDef);
			Interface = ReadIndex(CodedIndices.TypeDefOrRef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Class, MetadataTables.TypeDef, "Class: index into the TypeDef table"));
			sb.Append(GetInfo(Interface, CodedIndices.TypeDefOrRef, "Interface: index into the TypeDef, TypeRef or TypeSpec table; more precisely, a TypeDefOrRef coded index"));
		}
	}

	/// <summary>
	/// The Offset specifies the byte offset within the referenced
	/// file at which this resource record begins. The
	/// Implementation specifies which file holds this resource. The
	/// rows in the table result from .mresource directives on the
	/// Assembly (see clause 6.2.2).
	/// </summary>
	public class ManifestResourceTable : TableBase
	{
		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int Offset;

		/// <summary>
		/// a 4 byte bitmask of type ManifestResourceAttributes, clause
		/// 22.1.8
		/// </summary>
		public int Flags;

		/// <summary>
		/// index into the String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into File table, or AssemblyRef table, or null; more
		/// precisely, an Implementation coded index
		/// </summary>
		public int Implementation;

		public ManifestResourceTable()
		{
			title = "ManifestResource";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Offset = ReadInt32();
			Flags = ReadInt32();
			Name = ReadStringsIndex();
			Implementation = ReadIndex(CodedIndices.Implementation);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Offset, "Offset: a 4 byte constant"));
			sb.Append(GetInfo(Flags, "Flags: a 4 byte bitmask of type ManifestResourceAttributes, clause 22.1.8"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into the String heap"));
			sb.Append(GetInfo(Implementation, CodedIndices.Implementation, "Implementation: index into File table, or AssemblyRef table, or null; more precisely, an Implementation coded index"));
		}
	}

	/// <summary>
	/// An entry is made into the MemberRef table whenever a
	/// reference is made, in the CIL code, to a method or field
	/// which is defined in another module or assembly. (Also, an
	/// entry is made for a call to a method with a VARARG
	/// signature, even when it is defined in the same module as the
	/// callsite)
	/// </summary>
	public class MemberRefTable : TableBase
	{
		/// <summary>
		/// index into the TypeRef, ModuleRef, MethodDef, TypeSpec or
		/// TypeDef tables; more precisely, a MemberRefParent coded
		/// index
		/// </summary>
		public int Class;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int Signature;

		public MemberRefTable()
		{
			title = "MemberRef";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Class = ReadIndex(CodedIndices.MemberRefParent);
			Name = ReadStringsIndex();
			Signature = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Class, CodedIndices.MemberRefParent, "Class: index into the TypeRef, ModuleRef, MethodDef, TypeSpec or TypeDef tables; more precisely, a MemberRefParent coded index"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetBlobIndexInfo(Signature, "Signature: index into Blob heap"));
		}
	}

	/// <summary>
	/// The rows in the MethodDef table result from .method
	/// directives (see Chapter 14). The RVA column is computed when
	/// the image for the PE file is emitted and points to the
	/// COR_ILMETHOD structure for the body of the method (see
	/// Chapter 24.4)
	/// </summary>
	public class MethodDefTable : TableBase
	{
		/// <summary>
		/// a 4 byte constant
		/// </summary>
		public int RVA;

		/// <summary>
		/// a 2 byte bitmask of type MethodImplAttributes, clause 22.1.9
		/// </summary>
		public short ImplFlags;

		/// <summary>
		/// a 2 byte bitmask of type MethodAttribute, clause 22.1.9
		/// </summary>
		public short Flags;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int Signature;

		/// <summary>
		/// index into Param table
		/// </summary>
		public int ParamList;

		public MethodDefTable()
		{
			title = "MethodDef";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			RVA = ReadInt32();
			ImplFlags = ReadInt16();
			Flags = ReadInt16();
			Name = ReadStringsIndex();
			Signature = ReadBlobIndex();
			ParamList = ReadIndex(MetadataTables.Param);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(RVA, "RVA: a 4 byte constant"));
			sb.Append(GetInfo(ImplFlags, "ImplFlags: a 2 byte bitmask of type MethodImplAttributes, clause 22.1.9"));
			sb.Append(GetInfo(Flags, "Flags: a 2 byte bitmask of type MethodAttribute, clause 22.1.9"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetBlobIndexInfo(Signature, "Signature: index into Blob heap"));
			sb.Append(GetInfo(ParamList, MetadataTables.Param, "ParamList: index into Param table"));
		}
	}

	/// <summary>
	/// ilasm uses the .override directive to specify the rows of
	/// the MethodImpl table (see clause 9.3.2).
	/// </summary>
	public class MethodImplTable : TableBase
	{
		/// <summary>
		/// index into TypeDef table
		/// </summary>
		public int Class;

		/// <summary>
		/// index into MethodDef or MemberRef table; more precisely, a
		/// MethodDefOrRef coded index
		/// </summary>
		public int MethodBody;

		/// <summary>
		/// index into MethodDef or MemberRef table; more precisely, a
		/// MethodDefOrRef coded index
		/// </summary>
		public int MethodDeclaration;

		public MethodImplTable()
		{
			title = "MethodImpl";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Class = ReadIndex(MetadataTables.TypeDef);
			MethodBody = ReadIndex(CodedIndices.MethodDefOrRef);
			MethodDeclaration = ReadIndex(MetadataTables.MethodDef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Class, MetadataTables.TypeDef, "Class: index into TypeDef table"));
			sb.Append(GetInfo(MethodBody, CodedIndices.MethodDefOrRef, "MethodBody: index into MethodDef or MemberRef table; more precisely, a MethodDefOrRef coded index"));
			sb.Append(GetInfo(MethodDeclaration, MetadataTables.MethodDef, "MethodDeclaration: index into MethodDef or MemberRef table; more precisely, a\nMethodDefOrRef coded index"));
		}
	}

	/// <summary>
	/// The rows of the MethodSemantics table are filled by
	/// .property (see Chapter 16) and .event directives (see
	/// Chapter 17). See clause 21.13 for more information.
	/// </summary>
	public class MethodSemanticsTable : TableBase
	{
		/// <summary>
		/// a 2 byte bitmask of type MethodSemanticsAttributes, clause
		/// 22.1.11
		/// </summary>
		public short Semantics;

		/// <summary>
		/// index into the MethodDef table
		/// </summary>
		public int Method;

		/// <summary>
		/// index into the Event or Property table; more precisely, a
		/// HasSemantics coded index
		/// </summary>
		public int Association;

		public MethodSemanticsTable()
		{
			title = "MethodSemantics";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Semantics = ReadInt16();
			Method = ReadIndex(MetadataTables.MethodDef);
			Association = ReadIndex(CodedIndices.HasSemantics);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Semantics, "Semantics: a 2 byte bitmask of type MethodSemanticsAttributes, clause 22.1.11"));
			sb.Append(GetInfo(Method, MetadataTables.MethodDef, "Method: index into the MethodDef table"));
			sb.Append(GetInfo(Association, CodedIndices.HasSemantics, "Association: index into the Event or Property table; more precisely, a HasSemantics coded index"));
		}
	}

	/// <summary>
	/// The Generation, EncId and EncBaseId columns can be written
	/// as zero, and can be ignored by conforming implementations of
	/// the CLI. The rows in the Module table result from .module
	/// directives in the Assembly (see Section 6.4).
	/// </summary>
	public class ModuleTable : TableBase
	{
		/// <summary>
		/// 2 byte value, reserved, shall be zero
		/// </summary>
		public short Generation;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into Guid heap; simply a Guid used to distinguish
		/// between two versions of the same module
		/// </summary>
		public int Mvid;

		/// <summary>
		/// index into Guid heap, reserved, shall be zero
		/// </summary>
		public int EncId;

		/// <summary>
		/// index into Guid heap, reserved, shall be zero
		/// </summary>
		public int EncBaseId;

		public ModuleTable()
		{
			title = "Module";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Generation = ReadInt16();
			Name = ReadStringsIndex();
			Mvid = ReadGUIDIndex();
			EncId = ReadGUIDIndex();
			EncBaseId = ReadGUIDIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Generation, "Generation: 2 byte value, reserved, shall be zero"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetGUIDIndexInfo(Mvid, "Mvid: index into Guid heap; simply a Guid used to distinguish between two versions of the same module"));
			sb.Append(GetGUIDIndexInfo(EncId, "EncId: index into Guid heap, reserved, shall be zero"));
			sb.Append(GetGUIDIndexInfo(EncBaseId, "EncBaseId: index into Guid heap, reserved, shall be zero"));
		}
	}

	/// <summary>
	/// The rows in the ModuleRef table result from .module extern
	/// directives in the Assembly (see Section 6.5).
	/// </summary>
	public class ModuleRefTable : TableBase
	{
		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		public ModuleRefTable()
		{
			title = "ModuleRef";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Name = ReadStringsIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
		}
	}

	/// <summary>
	/// The NestedClass table records which Type definitions are
	/// nested within which other Type definition. In a typical
	/// high-level language, including ilasm, the nested class is
	/// defined as lexically 'inside' the text of its enclosing
	/// Type.
	/// </summary>
	public class NestedClassTable : TableBase
	{
		/// <summary>
		/// index into the TypeDef table
		/// </summary>
		public int NestedClass;

		/// <summary>
		/// index into the TypeDef table
		/// </summary>
		public int EnclosingClass;

		public NestedClassTable()
		{
			title = "NestedClass";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			NestedClass = ReadIndex(MetadataTables.TypeDef);
			EnclosingClass = ReadIndex(MetadataTables.TypeDef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(NestedClass, MetadataTables.TypeDef, "NestedClass: index into the TypeDef table"));
			sb.Append(GetInfo(EnclosingClass, MetadataTables.TypeDef, "EnclosingClass: index into the TypeDef table"));
		}
	}

	/// <summary>
	/// The rows in the Param table result from the parameters in a
	/// method declaration (see Section 14.4), or from a .param
	/// attribute attached to a method (see clause 14.4.1).
	/// </summary>
	public class ParamTable : TableBase
	{
		/// <summary>
		/// a 2 byte bitmask of type ParamAttributes, clause 22.1.12
		/// </summary>
		public short Flags;

		/// <summary>
		/// a 2 byte constant
		/// </summary>
		public short Sequence;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		public ParamTable()
		{
			title = "Param";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt16();
			Sequence = ReadInt16();
			Name = ReadStringsIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Flags, "Flags: a 2 byte bitmask of type ParamAttributes, clause 22.1.12"));
			sb.Append(GetInfo(Sequence, "Sequence: a 2 byte constant"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
		}
	}

	/// <summary>
	/// Properties within metadata are best viewed as a means to
	/// gather together collections of methods defined on a class,
	/// give them a name, and not much else. The methods are
	/// typically get_ and set_ methods, already defined on the
	/// class, and inserted like any other methods into the
	/// MethodDef table.
	/// </summary>
	public class PropertyTable : TableBase
	{
		/// <summary>
		/// a 2 byte bitmask of type PropertyAttributes, clause 22.1.13
		/// </summary>
		public short Flags;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into Blob heap
		/// </summary>
		public int Type;

		public PropertyTable()
		{
			title = "Property";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt16();
			Name = ReadStringsIndex();
			Type = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Flags, "Flags: a 2 byte bitmask of type PropertyAttributes, clause 22.1.13"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetBlobIndexInfo(Type, "Type: index into Blob heap"));
		}
	}

	/// <summary>
	/// The PropertyMap and Property tables result from putting the
	/// .property directive on a class (see Chapter 16).
	/// </summary>
	public class PropertyMapTable : TableBase
	{
		/// <summary>
		/// index into the TypeDef table
		/// </summary>
		public int Parent;

		/// <summary>
		/// index into Property table
		/// </summary>
		public int PropertyList;

		public PropertyMapTable()
		{
			title = "PropertyMap";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Parent = ReadIndex(MetadataTables.TypeDef);
			PropertyList = ReadIndex(MetadataTables.Property);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Parent, MetadataTables.TypeDef, "Parent: index into the TypeDef table"));
			sb.Append(GetInfo(PropertyList, MetadataTables.Property, "PropertyList: index into Property table"));
		}
	}

	/// <summary>
	/// Signatures are stored in the metadata Blob heap. In most
	/// cases, they are indexed by a column in some table --
	/// Field.Signature, Method.Signature, MemberRef.Signature, etc.
	/// However, there are two cases that require a metadata token
	/// for a signature that is not indexed by any metadata table.
	/// The StandAloneSig table fulfils this need. It has just one
	/// column, that points to a Signature in the Blob heap.
	/// </summary>
	public class StandAloneSigTable : TableBase
	{
		/// <summary>
		/// index into the Blob heap
		/// </summary>
		public int Signature;

		public StandAloneSigTable()
		{
			title = "StandAloneSig";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Signature = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetBlobIndexInfo(Signature, "Signature: index into the Blob heap"));
		}
	}

	public class TypeDefTable : TableBase
	{
		/// <summary>
		/// a 4 byte bitmask of type TypeAttributes, clause 22.1.14
		/// </summary>
		public int Flags;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Namespace;

		/// <summary>
		/// index into TypeDef, TypeRef or TypeSpec table; more
		/// precisely, a TypeDefOrRef coded index
		/// </summary>
		public int Extends;

		/// <summary>
		/// index into Field table; it marks the first of a continguous
		/// run of Fields owned by this Type
		/// </summary>
		public int FieldList;

		/// <summary>
		/// index into MethodDef table
		/// </summary>
		public int MethodList;

		public TypeDefTable()
		{
			title = "TypeDef";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Flags = ReadInt32();
			Name = ReadStringsIndex();
			Namespace = ReadStringsIndex();
			Extends = ReadIndex(CodedIndices.TypeDefOrRef);
			FieldList = ReadIndex(MetadataTables.Field);
			MethodList = ReadIndex(MetadataTables.MethodDef);
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(Flags, "Flags: a 4 byte bitmask of type TypeAttributes, clause 22.1.14"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetStringsIndexInfo(Namespace, "Namespace: index into String heap"));
			sb.Append(GetInfo(Extends, CodedIndices.TypeDefOrRef, "Extends: index into TypeDef, TypeRef or TypeSpec table; more precisely, a TypeDefOrRef coded index"));
			sb.Append(GetInfo(FieldList, MetadataTables.Field, "FieldList: index into Field table; it marks the first of a continguous run of Fields owned by this Type"));
			sb.Append(GetInfo(MethodList, MetadataTables.MethodDef, "MethodList: index into MethodDef table"));
		}
	}

	public class TypeRefTable : TableBase
	{
		/// <summary>
		/// index into Module, ModuleRef, AssemblyRef or TypeRef tables,
		/// or null; more precisely, a ResolutionScope coded index
		/// </summary>
		public int ResolutionScope;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Name;

		/// <summary>
		/// index into String heap
		/// </summary>
		public int Namespace;

		public TypeRefTable()
		{
			title = "TypeRef";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			ResolutionScope = ReadIndex(CodedIndices.ResolutionScope);
			Name = ReadStringsIndex();
			Namespace = ReadStringsIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetInfo(ResolutionScope, CodedIndices.ResolutionScope, "ResolutionScope: index into Module, ModuleRef, AssemblyRef or TypeRef tables, or null; more precisely, a ResolutionScope coded index"));
			sb.Append(GetStringsIndexInfo(Name, "Name: index into String heap"));
			sb.Append(GetStringsIndexInfo(Namespace, "Namespace: index into String heap"));
		}
	}

	/// <summary>
	/// The TypeSpec table has just one column, which indexes the
	/// specification of a Type, stored in the Blob heap. This
	/// provides a metadata token for that Type (rather than simply
	/// an index into the Blob heap) -- this is required, typically,
	/// for array operations ・creating, or calling methods on the
	/// array class.
	/// </summary>
	public class TypeSpecTable : TableBase
	{
		/// <summary>
		/// index into the Blob heap, where the blob is formatted as
		/// specified in clause 22.2.14
		/// </summary>
		public int Signature;

		public TypeSpecTable()
		{
			title = "TypeSpec";
		}

		public override void ReadData(byte[] data, int offset)
		{
			base.ReadData(data, offset);

			Signature = ReadBlobIndex();
		}

		public override void GetInfos(StringBuilder sb)
		{
			base.GetInfos(sb);

			sb.Append(GetBlobIndexInfo(Signature, "Signature: index into the Blob heap, where the blob is formatted as specified in clause 22.2.14"));
		}
	}
}
