MetaData Root (20 bytes + UTF-8 Version String + quad align padding) StreamHeaders (8 bytes + null terminated name string + quad align padding) Streams #~ (always present - holds metadata tables) #Strings (always present - holds identifier strings) #US (Userstring heap) #Blob (signature blobs) #GUID (guids for assemblies or Modules)
		internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
			: this (md, 0, 0, name, ret_param, pars)
		{
		}
		internal GenericParameter (MethodDef owner, MetaData metadata,
				short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
		{
		}
		internal sealed override uint Size(MetaData md) 
		{
			return (uint) (4 +
					md.CodedIndexSize(CIx.TypeOrMethodDef) + 
					md.StringsIndexSize ());
		}
		internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
				bool entryPoint, MetaData md) {
			if (!metaData) flags = NoMetaData;
			if (entryPoint) md.SetEntryPoint(this);
			this.nameIx = nameIx;
			hashIx = md.AddToBlobHeap(hashBytes);
			tabIx = MDTable.File;
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			md.AddToTable(MDTable.File,this);
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			if (done) return;
			ntIx = md.AddToBlobHeap(nt.ToBlob());
			done = true;
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			if (done) return;
			md.AddData(data);
			done = true;
		}
		internal override uint GetSigIx(MetaData md)
		{
			MemoryStream sig = new MemoryStream();
			TypeSig(sig);
			return md.AddToBlobHeap(sig.ToArray());
		}
		internal sealed override uint Size(MetaData md) 
		{
			return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
		}
		internal sealed override uint Size(MetaData md) 
		{
			return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
		}
		internal sealed override uint Size(MetaData md) 
		{
			return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			if (done) return;
			if (pinvokeImpl != null) {
				md.AddToTable(MDTable.ImplMap,pinvokeImpl);
				pinvokeImpl.BuildTables(md);
			}
			if (entryPoint) md.SetEntryPoint(this);
			uint locToken = 0;
			if (locals != null) {
				localSig = new LocalSig(locals);
				md.AddToTable(MDTable.StandAloneSig,localSig);
				localSig.BuildTables(md);
				locToken = localSig.Token();
			}
			if (code != null) {
				code.CheckCode(locToken,initLocals,maxStack);
				textOffset = md.AddCode(code);
			}
			nameIx = md.AddToStringsHeap(name);
			sigIx = GetSigIx(md);
			parIx = md.TableIndex(MDTable.Param);
			if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
				md.AddToTable(MDTable.Param, ret_param);
				ret_param.BuildTables(md);
			}
			for (int i=0; i < numPars; i++) {
				md.AddToTable(MDTable.Param,parList[i]);
				parList[i].BuildTables(md);
			}
			if (varArgSigList != null) {
				foreach (MethodRef varArgSig in varArgSigList) {
					md.AddToTable(MDTable.MemberRef,varArgSig);
					varArgSig.BuildTables(md);
				}
			}
			// Console.WriteLine("method has " + numPars + " parameters");
			done = true;
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			if (done) return;
			valIx = cValue.GetBlobIndex(md);
			done = true;
		}
		internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, 
				Param ret_param, Param [] pars) 
			: base (name)
		{
			methFlags = (ushort)mAttrSet;
			implFlags = (ushort)iAttrSet;
			this.ret_param = ret_param;
			metaData = md;
			parList = pars;
			if (parList != null) 
				numPars = parList.Length;
			tabIx = MDTable.Method;
		}
		internal sealed override uint Size(MetaData md) 
		{
			return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
		}
		internal override MetaDataElement GetTypeSpec(MetaData md) 
		{
			TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
			if (tS == null) {
				tS = new TypeSpec(this,md);
				md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
				md.AddToTable(MDTable.TypeSpec,tS);
			}
			return tS;
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			if (done) return;

			BinaryWriter bw = new BinaryWriter (new MemoryStream ());
			md.AddToTable (MDTable.DeclSecurity, this);
			MemoryStream str = (MemoryStream)bw.BaseStream;
			WriteSig (bw);
			permissionIx = md.AddToBlobHeap(str.ToArray());

			done = true;
		}
		internal AssemblyRef(MetaData md, string name) : base(name,md) 
		{
			tabIx = MDTable.AssemblyRef;
		}
		internal sealed override uint Size(MetaData md) 
		{
			return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
		}
		internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
			: base("System",eType.GetName(),md) {
				elemType = eType;
				parent = paren;
			}
		internal sealed override uint Size(MetaData md) 
		{
			return 4 + md.TableIndexSize(MDTable.Field);
		}
		internal override sealed MetaDataElement GetTypeSpec(MetaData md) 
		{
			if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
			return typeSpec;
		}
		internal sealed override uint Size(MetaData md) 
		{
			return 4 + md.StringsIndexSize() + md.BlobIndexSize();
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			md.AddToTable(MDTable.CustomAttribute, this);
			if (byteVal == null) {
				valIx = 0;
				return;
			}

			BinaryWriter bw = new BinaryWriter(new MemoryStream());
			bw.Write(byteVal);
			MemoryStream str = (MemoryStream)bw.BaseStream;
			valIx = md.AddToBlobHeap(str.ToArray());
		}
		internal sealed override uint Size(MetaData md) 
		{
			return 2+ md.CodedIndexSize(CIx.MemberForwarded) + 
				md.StringsIndexSize() +  md.TableIndexSize(MDTable.ModuleRef);
		}
		internal MSCorLib(MetaData md) : base(md,"mscorlib") 
		{
			if (!PEFile.IsMSCorlib)
				md.AddToTable(MDTable.AssemblyRef,this);
			systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
			systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
			systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
			systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
			systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
			systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
			systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
			systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
			systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
			systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
			systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
			systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
			systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
			systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
			systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
			systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
			systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
			systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
		}
		private GenericParameter (MetaDataElement owner, MetaData metadata,
				short index, string name, GenericParamAttributes attr, bool nadda) {
			this.owner = owner;
			this.metadata = metadata;
			this.index = index;
			tabIx = MDTable.GenericParam;
			this.name = name;
			this.attr = attr;
		}
		internal sealed override uint Size(MetaData md) 
		{
			return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
		}
		internal sealed override void BuildTables(MetaData md) 
		{
			if (done) return;
			nameIx = md.AddToStringsHeap(name);
			done = true;
		}
		internal abstract uint GetSigIx(MetaData md);