* PEAPI.cs (InterfaceImpl.SortKey): New.
[mono.git] / mcs / class / PEAPI / PEAPI.cs
index ad5f3486ee0ae685a1df1c3d0fed5732e11810f9..575f0c299b2ff239299d13b5aa99eccb1416144f 100644 (file)
-using System;\r
-using System.IO;\r
-using System.Collections;\r
-using System.Text;\r
-\r
-namespace PEAPI \r
-{\r
-  public class Hex {\r
-    readonly static char[] hexDigit = {'0','1','2','3','4','5','6','7',\r
-                                        '8','9','A','B','C','D','E','F'};\r
-    readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};\r
-    readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00, \r
-                                          0x0000000000FF0000, 0x00000000FF000000,\r
-                                          0x000000FF00000000, 0x0000FF0000000000,\r
-                                          0x00FF000000000000, 0xFF00000000000000 };\r
-    readonly static uint nibble0Mask = 0x0000000F;\r
-    readonly static uint nibble1Mask = 0x000000F0;\r
-\r
-    public static String Byte(int b) {\r
-      char[] str = new char[2];\r
-      uint num = (uint)b;\r
-      uint b1 = num & nibble0Mask;\r
-      uint b2 = (num & nibble1Mask) >> 4;\r
-      str[0] = hexDigit[b2];\r
-      str[1] = hexDigit[b1];\r
-      return new String(str);\r
-    }\r
-\r
-    public static String Short(int b) {\r
-      char[] str = new char[4];\r
-      uint num1 = (uint)b & iByteMask[0];\r
-      uint num2 = ((uint)b & iByteMask[1]) >> 8;\r
-      uint b1 = num1 & nibble0Mask;\r
-      uint b2 = (num1 & nibble1Mask) >> 4;\r
-      uint b3 = num2 & nibble0Mask;\r
-      uint b4 = (num2 & nibble1Mask) >> 4;\r
-      str[0] = hexDigit[b4];\r
-      str[1] = hexDigit[b3];\r
-      str[2] = hexDigit[b2];\r
-      str[3] = hexDigit[b1];\r
-      return new String(str);\r
-    }\r
-\r
-    public static String Int(int val) {\r
-      char[] str = new char[8];\r
-      uint num = (uint)val;\r
-      int strIx = 7;\r
-      for (int i=0; i < iByteMask.Length; i++) {\r
-        uint b = num & iByteMask[i];\r
-        b >>= (i*8);\r
-        uint b1 = b & nibble0Mask;\r
-        uint b2 = (b & nibble1Mask) >> 4;\r
-        str[strIx--] = hexDigit[b1];\r
-        str[strIx--] = hexDigit[b2];\r
-      }\r
-      return new String(str);\r
-    }\r
\r
-    public static String Int(uint num) {\r
-      char[] str = new char[8];\r
-      int strIx = 7;\r
-      for (int i=0; i < iByteMask.Length; i++) {\r
-        uint b = num & iByteMask[i];\r
-        b >>= (i*8);\r
-        uint b1 = b & nibble0Mask;\r
-        uint b2 = (b & nibble1Mask) >> 4;\r
-        str[strIx--] = hexDigit[b1];\r
-        str[strIx--] = hexDigit[b2];\r
-      }\r
-      return new String(str);\r
-    }\r
-\r
-    public static String Long(long lnum) {\r
-      ulong num = (ulong)lnum;\r
-      char[] str = new char[16];\r
-      int strIx = 15;\r
-      for (int i=0; i < lByteMask.Length; i++) {\r
-        ulong b = num & lByteMask[i];\r
-        b >>= (i*8);\r
-        ulong b1 = b & nibble0Mask;\r
-        ulong b2 = (b & nibble1Mask) >> 4;\r
-        str[strIx--] = hexDigit[b1];\r
-        str[strIx--] = hexDigit[b2];\r
-      }\r
-      return new String(str);\r
-    }\r
-  }\r
-\r
-  public class NotYetImplementedException : System.Exception \r
-  {\r
-     public NotYetImplementedException(string msg) : base(msg + " Not Yet Implemented") { }\r
-  }\r
-\r
-  public class TypeSignatureException : System.Exception {\r
-    public TypeSignatureException(string msg) : base(msg) { }\r
-  }\r
-\r
-    public class GenericTypeSpec : Type {\r
-\r
-            private int index;\r
-\r
-            public GenericTypeSpec (int index) : base (0x13) {\r
-                    this.index = index;\r
-                    tabIx = MDTable.TypeSpec;\r
-            }\r
-\r
-            internal sealed override void TypeSig(MemoryStream str) {\r
-                    str.WriteByte(typeIndex);\r
-                    MetaData.CompressNum ((uint) index, str);\r
-            }\r
-            }\r
-\r
-\r
-  public class GenericTypeInst : Type {\r
-\r
-          private Type gen_type;\r
-          private Type[] gen_param;\r
-\r
-          public GenericTypeInst (Type gen_type, Type[] gen_param) : base (0x15)\r
-          {\r
-                  typeIndex = 0x15;\r
-                  this.gen_type = gen_type;\r
-                  this.gen_param = gen_param;\r
-                  tabIx = MDTable.TypeSpec;\r
-  }\r
-\r
-          internal sealed override void TypeSig(MemoryStream str) {\r
-                  str.WriteByte(typeIndex);\r
-                  gen_type.TypeSig (str);\r
-                  MetaData.CompressNum ((uint) gen_param.Length, str);\r
-                  foreach (Type param in gen_param)\r
-                          param.TypeSig (str);\r
-            }\r
-  }\r
-\r
-       /// <summary>\r
-       /// The IL Array type\r
-       /// </summary>\r
-       public abstract class Array : Type\r
-       {\r
-\r
-    protected Type elemType;\r
-                protected MetaData metaData;\r
-                protected string cnameSpace, cname;\r
-\r
-    internal Array(Type eType, byte TypeId) : base(TypeId) {\r
-      elemType = eType;\r
-                       tabIx = MDTable.TypeSpec;\r
-    }\r
-\r
-    internal Array(Class eClass, MetaData md, string nameSpace, string name,\r
-                    byte TypeId) : base(TypeId) {\r
-            elemType = eClass;\r
-            tabIx = MDTable.TypeSpec;\r
-            metaData = md;\r
-            cnameSpace = nameSpace;\r
-            cname = name;\r
-    }\r
-\r
-      public Method AddMethod(string name, Type retType, Type[] pars) {\r
-\r
-              if (metaData == null || cnameSpace == null || cname == null)\r
-                      throw new Exception ("Methods cannot be added to arrays not created with the Class.GetArray* methods.");\r
-              Method meth = new MethodRef (GetTypeSpec (metaData), name, retType, pars, false, null);\r
-              metaData.AddToTable(MDTable.MemberRef,meth);\r
-\r
-              return meth;\r
-      }\r
\r
-       }\r
-\r
-  /**************************************************************************/  \r
-  \r
-  /// <summary>\r
-  /// Single dimensional array with zero lower bound\r
-  /// </summary>\r
-  public class ZeroBasedArray : Array {\r
-\r
-    /// <summary>\r
-    /// Create a new array  -   elementType[]\r
-    /// </summary>\r
-    /// <param name="elementType">the type of the array elements</param>\r
-    public ZeroBasedArray(Type elementType) : base (elementType,0x1D) { }\r
-\r
-    public ZeroBasedArray(Class elementClass, MetaData md,\r
-                    string nameSpace, string name) : base (elementClass, md, nameSpace, name, 0x1D) { }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-      elemType.TypeSig(str); \r
-    }\r
-\r
-  }\r
-\r
-\r
-  /**************************************************************************/           \r
-\r
-  /// <summary>\r
-  /// Multi dimensional array with explicit bounds\r
-  /// </summary>\r
-  public class BoundArray : Array {\r
-    int[] lowerBounds;\r
-    int[] sizes;\r
-    uint numDims;\r
-\r
-    /// <summary>\r
-    /// Create a new multi dimensional array type \r
-    /// eg. elemType[1..5,3..10,5,,] would be \r
-    /// new BoundArray(elemType,5,[1,3,0],[5,10,4])\r
-    /// </summary>\r
-    /// <param name="elementType">the type of the elements</param>\r
-    /// <param name="dimensions">the number of dimensions</param>\r
-    /// <param name="loBounds">lower bounds of dimensions</param>\r
-    /// <param name="upBounds">upper bounds of dimensions</param>\r
-    public BoundArray(Type elementType, uint dimensions, int[] loBounds, \r
-      int[] upBounds) : base (elementType,0x14) {\r
-      numDims = dimensions;\r
-      lowerBounds = loBounds;\r
-      sizes = new int[loBounds.Length];\r
-      for (int i=0; i < loBounds.Length; i++) {\r
-        sizes[i] = upBounds[i] - loBounds[i] + 1;\r
-      }\r
-    }\r
-\r
-    internal BoundArray(Class elementClass, MetaData md, string nameSpace, string name,\r
-                    uint dimensions, int[] loBounds,\r
-                    int[] upBounds) : base (elementClass,md, nameSpace, name, 0x14) {\r
-      numDims = dimensions;\r
-      lowerBounds = loBounds;\r
-      sizes = new int[loBounds.Length];\r
-      for (int i=0; i < loBounds.Length; i++) {\r
-        sizes[i] = upBounds[i] - loBounds[i] + 1;\r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new multi dimensional array type \r
-    /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])\r
-    /// </summary>\r
-    /// <param name="elementType">the type of the elements</param>\r
-    /// <param name="dimensions">the number of dimensions</param>\r
-    /// <param name="size">the sizes of the dimensions</param>\r
-    public BoundArray(Type elementType, uint dimensions, int[] size) \r
-                                                  : base (elementType,0x14) {\r
-      numDims = dimensions;\r
-      sizes = size;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new multi dimensional array type \r
-    /// eg. elemType[,,] would be new BoundArray(elemType,3)\r
-    /// </summary>\r
-    /// <param name="elementType">the type of the elements</param>\r
-    /// <param name="dimensions">the number of dimensions</param>\r
-    public BoundArray(Type elementType, uint dimensions)\r
-                                                  : base (elementType,0x14) {\r
-      numDims = dimensions;\r
-    }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-      elemType.TypeSig(str);\r
-      MetaData.CompressNum(numDims,str);\r
-      if ((sizes != null) && (sizes.Length > 0)) {\r
-        MetaData.CompressNum((uint)sizes.Length,str);\r
-        for (int i=0; i < sizes.Length; i++) {\r
-          MetaData.CompressNum((uint)sizes[i],str);\r
-        }\r
-      } else str.WriteByte(0);\r
-      if ((lowerBounds != null) && (lowerBounds.Length > 0)) {\r
-        MetaData.CompressNum((uint)lowerBounds.Length,str);\r
-        for (int i=0; i < lowerBounds.Length; i++) {\r
-          MetaData.CompressNum((uint)lowerBounds[i],str);\r
-        }\r
-      } else str.WriteByte(0);\r
-    }\r
-  \r
-  }\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// Descriptor for THIS assembly (.assembly)\r
-  /// </summary>\r
-  public class Assembly : ResolutionScope \r
-  {\r
-    ushort majorVer, minorVer, buildNo, revisionNo;\r
-    uint flags;\r
-    HashAlgorithm hashAlgId = HashAlgorithm.None;\r
-    uint keyIx = 0, cultIx = 0;\r
-    \r
-    internal Assembly(string name, MetaData md) : base(name,md) {\r
-      tabIx = MDTable.Assembly;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add details about THIS assembly\r
-    /// </summary>\r
-    /// <param name="majVer">Major Version</param>\r
-    /// <param name="minVer">Minor Version</param>\r
-    /// <param name="bldNo">Build Number</param>\r
-    /// <param name="revNo">Revision Number</param>\r
-    /// <param name="key">Hash Key</param>\r
-    /// <param name="hash">Hash Algorithm</param>\r
-    /// <param name="cult">Culture</param>\r
-    public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo, \r
-                              byte[] key, HashAlgorithm hash, string cult) {\r
-      majorVer = (ushort)majVer;\r
-      minorVer = (ushort)minVer;\r
-      buildNo = (ushort)bldNo;\r
-      revisionNo = (ushort)revNo;\r
-      hashAlgId = hash;\r
-      keyIx = metaData.AddToBlobHeap(key);\r
-      cultIx = metaData.AddToStringsHeap(cult);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an attribute to THIS assembly\r
-    /// </summary>\r
-    /// <param name="aa">assembly attribute</param>\r
-    public void AddAssemblyAttr(AssemAttr aa) {\r
-      flags |= (uint)aa;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-//      Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));\r
-      output.Write((uint)hashAlgId);\r
-      output.Write(majorVer);\r
-      output.Write(minorVer);\r
-      output.Write(buildNo);\r
-      output.Write(revisionNo);\r
-      output.Write(flags);\r
-      output.BlobIndex(keyIx);\r
-      output.StringsIndex(nameIx);\r
-      output.StringsIndex(cultIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 14; \r
-        case (CIx.HasDeclSecurity) : return 2; \r
-      }\r
-      return 0;\r
-    }\r
-\r
-  }    \r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// A reference to an external assembly (.assembly extern)\r
-       /// </summary>\r
-       public class AssemblyRef : ResolutionScope\r
-       {\r
-    private ushort major, minor, build, revision;\r
-    uint flags, keyIx, hashIx, cultIx;\r
-    bool hasVersion = false, isKeyToken = false;\r
-    byte[] keyBytes;\r
-    string culture;\r
-\r
-    internal AssemblyRef(MetaData md, string name) : base(name,md) {\r
-      tabIx = MDTable.AssemblyRef;\r
-               }\r
-\r
-    /// <summary>\r
-    /// Add version information about this external assembly\r
-    /// </summary>\r
-    /// <param name="majVer">Major Version</param>\r
-    /// <param name="minVer">Minor Version</param>\r
-    /// <param name="bldNo">Build Number</param>\r
-    /// <param name="revNo">Revision Number</param>\r
-    public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo) {\r
-      major = (ushort)majVer;\r
-      minor = (ushort)minVer;\r
-      build = (ushort)bldNo;\r
-      revision = (ushort)revNo;\r
-      hasVersion = true;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the hash value for this external assembly\r
-    /// </summary>\r
-    /// <param name="hash">bytes of the hash value</param>\r
-    public void AddHash(byte[] hash) {\r
-      hashIx = metaData.AddToBlobHeap(hash); \r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the culture for this external assembly\r
-    /// </summary>\r
-    /// <param name="cult">the culture string</param>\r
-    public void AddCulture(string cult) {\r
-      cultIx = metaData.AddToStringsHeap(cult);\r
-      culture = cult;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the full public key for this external assembly\r
-    /// </summary>\r
-    /// <param name="key">bytes of the public key</param>\r
-    public void AddKey(byte[] key) {\r
-      flags |= 0x0001;   // full public key\r
-      keyBytes = key;\r
-      keyIx = metaData.AddToBlobHeap(key); \r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the public key token (low 8 bytes of the public key)\r
-    /// </summary>\r
-    /// <param name="key">low 8 bytes of public key</param>\r
-    public void AddKeyToken(byte[] key) {\r
-      keyIx = metaData.AddToBlobHeap(key); \r
-      keyBytes = key;\r
-      isKeyToken = true;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a class to this external assembly\r
-    /// </summary>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns></returns>\r
-    public virtual ClassRef AddClass(string nsName, string name) {\r
-      ClassRef aClass = new ClassRef(nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeRef,aClass);\r
-      aClass.SetParent(this);\r
-      return aClass;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a value class to this external assembly\r
-    /// </summary>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns></returns>\r
-    public virtual ClassRef AddValueClass(string nsName, string name) {\r
-      ClassRef aClass = new ClassRef(nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeRef,aClass);\r
-      aClass.SetParent(this);\r
-      aClass.MakeValueClass();\r
-      return aClass;\r
-    }\r
-\r
-    internal string TypeName() {\r
-      string result = name;\r
-      if (hasVersion) \r
-        result = result + ", Version=" + major + "." + minor + "." + \r
-                  build + "." + revision;\r
-      if (keyBytes != null) {\r
-        string tokenStr = "=";\r
-        if (isKeyToken) tokenStr = "Token=";\r
-        result = result + ", PublicKey" + tokenStr;\r
-        for (int i=0; i < keyBytes.Length; i++) {\r
-          result = result + Hex.Byte(keyBytes[i]);\r
-        }\r
-      }\r
-      if (culture != null) \r
-        result = result + ", Culture=" + culture;\r
-      return result;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(major);\r
-      output.Write(minor);\r
-      output.Write(build);\r
-      output.Write(revision);\r
-      output.Write(flags);\r
-      output.BlobIndex(keyIx);\r
-      output.StringsIndex(nameIx);\r
-      output.StringsIndex(cultIx);\r
-      output.BlobIndex(hashIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.ResolutionScope) : return 2; \r
-        case (CIx.HasCustomAttr) : return 15; \r
-        case (CIx.Implementation) : return 1; \r
-      }\r
-      return 0;\r
-    }\r
\r
-       }\r
-  /**************************************************************************/  \r
-\r
-  /// <summary>\r
-  /// flags for the assembly (.corflags)\r
-  /// </summary>\r
-  public enum CorFlags {CF_IL_ONLY, CF_32_BITREQUIRED, CF_STRONGNAMESIGNED, \r
-                        CF_TRACKDEBUGDATA}\r
-\r
-  /// <summary>\r
-  /// subsystem for the assembly (.subsystem)\r
-  /// </summary>\r
-  public enum SubSystem { Native = 1, Windows_GUI = 2, \r
-    Windows_CUI = 3, OS2_CUI = 5, POSIX_CUI = 7, Native_Windows = 8, \r
-    Windows_CE_GUI = 9}\r
\r
-  /// <summary>\r
-  /// Hash algorithms for the assembly\r
-  /// </summary>\r
-  public enum HashAlgorithm { None, SHA1 }\r
-\r
-  /// <summary>\r
-  /// Attributes for this assembly\r
-  /// </summary>\r
-  public enum AssemAttr { EnableJITCompileTracking = 0x8000, \r
-                          DisableJITCompileOptimizer = 0x4000}\r
-\r
-  /// <summary>\r
-  /// Method call conventions\r
-  /// </summary>\r
-  public enum CallConv { Default, Cdecl, Stdcall, Thiscall, \r
-    Fastcall, Vararg, Instance = 0x20, InstanceExplicit = 0x60 }\r
-\r
-  /// <summary>\r
-  /// Type custom modifier\r
-  /// </summary>\r
-  public enum CustomModifier { modreq = 0x1F, modopt };\r
-\r
-  /// <summary>\r
-  /// Attibutes for a class\r
-  /// </summary>\r
-  public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate, \r
-    NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem, \r
-    SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20, \r
-    Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100, \r
-    PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800, \r
-    Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,\r
-    AutoClass = 0x20000, BeforeFieldInit = 0x100000 }\r
-\r
-  /// <summary>\r
-  /// Attributes for a field\r
-  /// </summary>\r
-  public enum FieldAttr {Default, Private, FamAndAssem, Assembly, \r
-    Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16, \r
-    Initonly = 0x20, Literal = 0x40, Notserialized = 0x80, \r
-    SpecialName = 0x200, RTSpecialName = 0x400 }\r
-  \r
-  /// <summary>\r
-  /// Attributes for a method\r
-  /// </summary>\r
-  public enum MethAttr { Default, Private, FamAndAssem, Assembly,\r
-    Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16, \r
-    Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040, \r
-    PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080, \r
-    NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,\r
-    RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800, \r
-    RequireSecObject = 0x8000}\r
-\r
-  /// <summary>\r
-  /// Attributes for .pinvokeimpl method declarations\r
-  /// </summary>\r
-  public enum PInvokeAttr { ansi = 2, unicode = 4, autochar = 6, \r
-    platformapi = 0x100, cdecl = 0x200, stdcall = 0x300, thiscall = 0x400,\r
-    fastcall = 0x500 }\r
-\r
-  /// <summary>\r
-  /// Implementation attributes for a method\r
-  /// </summary>\r
-  public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,\r
-    ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000, \r
-    Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, Optil = 0x0002}\r
-\r
-  /// <summary>\r
-  /// Modes for a parameter\r
-  /// </summary>\r
-  public enum ParamAttr { Default, In, Out, Opt = 4 }\r
-\r
-  /// <summary>\r
-  /// CIL instructions\r
-  /// </summary>\r
-  public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,\r
-    ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3, \r
-    ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3, \r
-    ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop, \r
-    ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4, \r
-    ldind_u4, ldind_i8, ldind_i,  ldind_r4, ldind_r8, ldind_ref, stind_ref, \r
-    stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,\r
-    div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not, \r
-    conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8, \r
-    conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,\r
-    conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un, \r
-    conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un, \r
-    ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2, \r
-    ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8, \r
-    ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,\r
-    stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2, \r
-    conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3, \r
-    conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf, \r
-    add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally, \r
-    stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un, \r
-    localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_, \r
-    cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D}\r
-\r
-  /// <summary>\r
-  /// CIL instructions requiring an integer parameter\r
-  /// </summary>\r
-  public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s, \r
-                     stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,\r
-                     ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }\r
-\r
-  /// <summary>\r
-  /// CIL instructions requiring a field parameter\r
-  /// </summary>\r
-  public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,\r
-                       stsfld, ldtoken = 0xD0 }\r
-\r
-  /// <summary>\r
-  /// CIL instructions requiring a method parameter\r
-  /// </summary>\r
-  public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73, \r
-                        ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }\r
-\r
-  /// <summary>\r
-  /// CIL instructions requiring a type parameter\r
-  /// </summary>\r
-  public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst, \r
-                      unbox = 0x79, stobj = 0x81, box = 0x8C, newarr, \r
-                      ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6, \r
-                      ldtoken = 0xD0, initobj = 0xFE15, sizeOf = 0xFE1C,\r
-                      ldelem = 0xA3, stelem = 0xA4 }\r
-\r
-  /// <summary>\r
-  /// CIL branch instructions\r
-  /// </summary>\r
-  public enum BranchOp {br = 0x2B, brfalse, brtrue, beq, bge, bgt, ble, blt,\r
-    bne_un, bge_un, bgt_un, ble_un, blt_un, leave = 0xDE }\r
-\r
-  /// <summary>\r
-  /// Index for all the tables in the meta data\r
-  /// </summary>\r
-  public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,\r
-    Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute, \r
-    FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig, \r
-    EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics, \r
-    MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20, \r
-    AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor, \r
-    AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,\r
-    GenericParam, MethodSpec, GenericParamConstraint  }\r
-\r
-  public enum SafeArrayType { int16 = 2, int32, float32, float64,\r
-    currency, date, bstr, dispatch, error, boolean, variant, unknown,\r
-    Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }\r
-\r
-  internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,\r
-    HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef, \r
-    MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,\r
-    TypeOrMethodDef, MaxCIx }\r
-\r
-  internal enum MapType { eventMap, propertyMap, nestedClass }\r
-\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// The assembly for mscorlib.  \r
-       /// </summary>\r
-       public sealed class MSCorLib : AssemblyRef\r
-       {\r
-    private static readonly int valueTypeIx = 18;\r
-    private readonly string systemName = "System";\r
-    private ClassRef[] systemClasses = new ClassRef[valueTypeIx+2];\r
-    private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];\r
-    private TypeSpec[] specialTypeSpecs = new TypeSpec[valueTypeIx];\r
-    private static int[] specialNames = {\r
-      PrimitiveType.Void.GetName().GetHashCode(),\r
-      PrimitiveType.Boolean.GetName().GetHashCode(),\r
-      PrimitiveType.Char.GetName().GetHashCode(),\r
-      PrimitiveType.Int8.GetName().GetHashCode(),\r
-      PrimitiveType.UInt8.GetName().GetHashCode(),\r
-      PrimitiveType.Int16.GetName().GetHashCode(),\r
-      PrimitiveType.UInt16.GetName().GetHashCode(),\r
-      PrimitiveType.Int32.GetName().GetHashCode(),\r
-      PrimitiveType.UInt32.GetName().GetHashCode(),\r
-      PrimitiveType.Int64.GetName().GetHashCode(),\r
-      PrimitiveType.UInt64.GetName().GetHashCode(),\r
-      PrimitiveType.Float32.GetName().GetHashCode(),\r
-      PrimitiveType.Float64.GetName().GetHashCode(),\r
-      PrimitiveType.String.GetName().GetHashCode(),\r
-      PrimitiveType.TypedRef.GetName().GetHashCode(),\r
-      PrimitiveType.IntPtr.GetName().GetHashCode(),\r
-      PrimitiveType.UIntPtr.GetName().GetHashCode(),\r
-      PrimitiveType.Object.GetName().GetHashCode(),\r
-      "ValueType".GetHashCode(),\r
-      "Enum".GetHashCode()\r
-    };\r
-\r
-    internal MSCorLib(MetaData md) : base(md,"mscorlib") {\r
-      md.AddToTable(MDTable.AssemblyRef,this);\r
-      systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;\r
-      systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;\r
-      systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;\r
-      systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;\r
-      systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;\r
-      systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;\r
-      systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;\r
-      systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;\r
-      systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;\r
-      systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;\r
-      systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;\r
-      systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;\r
-      systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;\r
-      systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;\r
-      systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;\r
-      systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;\r
-      systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;\r
-      systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a class to the mscorlib assembly\r
-    /// </summary>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns></returns>\r
-    public override ClassRef AddClass(string nsName, string name) {\r
-      ClassRef aClass = GetSpecialClass(nsName,name);\r
-      if (aClass == null) {\r
-        aClass = new ClassRef(nsName,name,metaData);\r
-        metaData.AddToTable(MDTable.TypeRef,aClass);\r
-        aClass.SetParent(this);\r
-      }\r
-      return aClass;\r
-    }\r
-\r
-    private ClassRef GetSpecialClass(string nsName,string name) {\r
-      if (nsName.CompareTo(systemName) != 0) return null;\r
-      int hash = name.GetHashCode();\r
-      for (int i=0; i < specialNames.Length; i++) {\r
-        if (hash == specialNames[i]) {\r
-          if (systemClasses[i] == null) {\r
-            if (i < valueTypeIx) {\r
-              systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);\r
-              if ((systemTypes[i] != PrimitiveType.Object) &&\r
-                (systemTypes[i] != PrimitiveType.String)) {\r
-                systemClasses[i].MakeValueClass();\r
-              }\r
-            } else {\r
-              systemClasses[i] = new ClassRef(nsName,name,metaData);\r
-              systemClasses[i].SetParent(this);\r
-              systemClasses[i].MakeValueClass();\r
-            }\r
-            metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);\r
-          }\r
-          return systemClasses[i];\r
-        }\r
-      }\r
-      return null;\r
-    }\r
-\r
-    internal ClassRef GetSpecialSystemClass(PrimitiveType pType) {\r
-      int ix = pType.GetSystemTypeIx();\r
-      if (systemClasses[ix] == null) {\r
-        systemClasses[ix] = new SystemClass(pType,this,metaData);\r
-        metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);\r
-      }\r
-      return systemClasses[ix];\r
-    }\r
-        \r
-    private ClassRef GetValueClass(string name, int hash) {\r
-      int ix = valueTypeIx;\r
-      if (hash != specialNames[valueTypeIx]) ix++;\r
-      if (systemClasses[ix] == null) {\r
-        systemClasses[ix] = new ClassRef(systemName,name,metaData);\r
-        systemClasses[ix].SetParent(this);\r
-        systemClasses[ix].MakeValueClass();\r
-        metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);\r
-      }\r
-      return systemClasses[ix];\r
-    }\r
-\r
-    internal ClassRef ValueType() {\r
-      if (systemClasses[valueTypeIx] == null) {\r
-        ClassRef valType = new ClassRef("System","ValueType",metaData);\r
-        valType.SetParent(this);\r
-        valType.MakeValueClass();\r
-        metaData.AddToTable(MDTable.TypeRef,valType);\r
-        systemClasses[valueTypeIx] = valType;\r
-      }\r
-      return systemClasses[valueTypeIx];\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a value class to this external assembly\r
-    /// </summary>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns></returns>\r
-    public override ClassRef AddValueClass(string nsName, string name) {\r
-      if (nsName.CompareTo(systemName) == 0) {\r
-        int hash = name.GetHashCode();\r
-        if ((hash == specialNames[valueTypeIx]) ||\r
-            (hash == specialNames[valueTypeIx+1])) {\r
-          return GetValueClass(name,hash);\r
-        }\r
-      }\r
-      ClassRef aClass = new ClassRef(nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeRef,aClass);\r
-      aClass.SetParent(this);\r
-      aClass.MakeValueClass();\r
-      return aClass;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Signature for calli instruction\r
-       /// </summary>\r
-       public class CalliSig : Signature\r
-       {\r
-    private static readonly byte Sentinel = 0x41;\r
-    CallConv callConv;\r
-    Type returnType;\r
-    Type[] parameters, optParams;\r
-               uint numPars = 0, numOptPars = 0;\r
-\r
-    /// <summary>\r
-    /// Create a signature for a calli instruction\r
-    /// </summary>\r
-    /// <param name="cconv">calling conventions</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">parameter types</param>\r
-    public CalliSig(CallConv cconv, Type retType, Type[] pars) {\r
-                       tabIx = MDTable.StandAloneSig;\r
-      callConv = cconv;\r
-      returnType = retType;\r
-      parameters = pars;\r
-                       if (pars != null) numPars = (uint)pars.Length;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the optional parameters to a vararg method\r
-    /// This method sets the vararg calling convention\r
-    /// </summary>\r
-    /// <param name="optPars">the optional pars for the vararg call</param>\r
-    public void AddVarArgs(Type[] optPars) {\r
-      optParams = optPars;\r
-      if (optPars != null) numOptPars = (uint)optPars.Length;\r
-      callConv |= CallConv.Vararg;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add extra calling conventions to this callsite signature\r
-    /// </summary>\r
-    /// <param name="cconv"></param>\r
-    public void AddCallingConv(CallConv cconv) {\r
-      callConv |= cconv;\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      MemoryStream sig = new MemoryStream();\r
-      sig.WriteByte((byte)callConv);\r
-      MetaData.CompressNum(numPars+numOptPars,sig);\r
-      returnType.TypeSig(sig);\r
-      for (int i=0; i < numPars; i++) {\r
-        parameters[i].TypeSig(sig);\r
-      }\r
-      sigIx = md.AddToBlobHeap(sig.ToArray());\r
-      if (numOptPars > 0) {\r
-        sig.WriteByte(Sentinel);\r
-        for (int i=0; i < numOptPars; i++) {\r
-          optParams[i].TypeSig(sig);\r
-        }\r
-      }\r
-      done = true;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// The IL instructions for a method\r
-  /// </summary>\r
-  public class CILInstructions \r
-  {\r
-\r
-    private static readonly uint ExHeaderSize = 4;\r
-    private static readonly uint FatExClauseSize = 24;\r
-    private static readonly uint SmlExClauseSize = 12;\r
-    private static readonly sbyte maxByteVal = 127;\r
-    private static readonly sbyte minByteVal = -128;\r
-    private static readonly byte maxUByteVal = 255;\r
-    private static readonly int smallSize = 64;\r
-    private static readonly ushort TinyFormat = 0x2;\r
-    private static readonly ushort FatFormat = 0x3003;\r
-    private static readonly ushort MoreSects = 0x8;\r
-    private static readonly ushort InitLocals = 0x10;\r
-    private static readonly uint FatSize = 12;\r
-    private static readonly uint FatWords = FatSize/4;\r
-    private static readonly byte FatExceptTable = 0x41;\r
-    private static readonly byte SmlExceptTable = 0x01; \r
-\r
-    private MetaData metaData;\r
-    private ArrayList exceptions, blockStack;\r
-    //private bool codeChecked = false;\r
-    private static readonly int INITSIZE = 5;\r
-    private CILInstruction[] buffer = new CILInstruction[INITSIZE];\r
-    private int tide = 0;\r
-    private uint offset = 0;\r
-    private ushort headerFlags = 0;\r
-    private short maxStack;\r
-    private uint paddingNeeded = 0;\r
-    private byte exceptHeader = 0;\r
-    uint localSigIx = 0;\r
-    uint codeSize = 0, exceptSize = 0;\r
-    bool tinyFormat, fatExceptionFormat = false;\r
-\r
-    internal CILInstructions(MetaData md) {\r
-      metaData = md;\r
-    }\r
-\r
-    private void AddToBuffer(CILInstruction inst) {\r
-      if (tide >= buffer.Length) {\r
-        CILInstruction[] tmp = buffer;\r
-        buffer = new CILInstruction[tmp.Length * 2];\r
-        for (int i=0; i < tide; i++) {\r
-          buffer[i] = tmp[i];\r
-        }\r
-      }\r
-                       //Console.WriteLine("Adding instruction at offset " + offset + " with size " + inst.size);\r
-                       inst.offset = offset;\r
-      offset += inst.size;\r
-      buffer[tide++] = inst;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a simple IL instruction\r
-    /// </summary>\r
-    /// <param name="inst">the IL instruction</param>\r
-    public void Inst(Op inst) {\r
-      AddToBuffer(new Instr((int)inst));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an IL instruction with an integer parameter\r
-    /// </summary>\r
-    /// <param name="inst">the IL instruction</param>\r
-    /// <param name="val">the integer parameter value</param>\r
-    public void IntInst(IntOp inst, int val) {\r
-      int instr = (int)inst;\r
-      if ((inst == IntOp.ldc_i4_s) || (inst == IntOp.ldc_i4)) \r
-        AddToBuffer(new IntInstr(instr,val,(inst == IntOp.ldc_i4_s)));\r
-      else\r
-        AddToBuffer(new UIntInstr(instr,val,((inst < IntOp.ldc_i4_s) ||\r
-                                              (inst == IntOp.unaligned))));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the load long instruction\r
-    /// </summary>\r
-    /// <param name="cVal">the long value</param>\r
-    public void ldc_i8(long cVal) {\r
-      AddToBuffer(new LongInstr(0x21,cVal));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the load float32 instruction\r
-    /// </summary>\r
-    /// <param name="cVal">the float value</param>\r
-    public void ldc_r4(float cVal) {\r
-      AddToBuffer(new FloatInstr(0x22,cVal));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the load float64 instruction\r
-    /// </summary>\r
-    /// <param name="cVal">the float value</param>\r
-    public void ldc_r8(double cVal) {\r
-      AddToBuffer(new DoubleInstr(0x23,cVal));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the load string instruction\r
-    /// </summary>\r
-    /// <param name="str">the string value</param>\r
-    public void ldstr(string str) {\r
-      AddToBuffer(new StringInstr(0x72,str));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the calli instruction\r
-    /// </summary>\r
-    /// <param name="sig">the signature for the calli</param>\r
-    public void calli(CalliSig sig) {\r
-      AddToBuffer(new SigInstr(0x29,sig));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a label to the CIL instructions\r
-    /// </summary>\r
-    /// <param name="lab">the label to be added</param>\r
-    public void CodeLabel(CILLabel lab) {\r
-      AddToBuffer(new LabelInstr(lab));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an instruction with a field parameter\r
-    /// </summary>\r
-    /// <param name="inst">the CIL instruction</param>\r
-    /// <param name="f">the field parameter</param>\r
-    public void FieldInst(FieldOp inst, Field f) {\r
-      AddToBuffer(new FieldInstr((int)inst,f));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an instruction with a method parameter\r
-    /// </summary>\r
-    /// <param name="inst">the CIL instruction</param>\r
-    /// <param name="m">the method parameter</param>\r
-    public void MethInst(MethodOp inst, Method m) {\r
-      AddToBuffer(new MethInstr((int)inst,m));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an instruction with a type parameter\r
-    /// </summary>\r
-    /// <param name="inst">the CIL instruction</param>\r
-    /// <param name="t">the type argument for the CIL instruction</param>\r
-    public void TypeInst(TypeOp inst, Type aType) {\r
-      AddToBuffer(new TypeInstr((int)inst,aType,metaData));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a branch instruction\r
-    /// </summary>\r
-    /// <param name="inst">the branch instruction</param>\r
-    /// <param name="lab">the label that is the target of the branch</param>\r
-    public void Branch(BranchOp inst,  CILLabel lab) {\r
-      AddToBuffer(new BranchInstr((int)inst,lab));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a switch instruction\r
-    /// </summary>\r
-    /// <param name="labs">the target labels for the switch</param>\r
-    public void Switch(CILLabel[] labs) {\r
-      AddToBuffer(new SwitchInstr(0x45,labs));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a byte to the CIL instructions (.emitbyte)\r
-    /// </summary>\r
-    /// <param name="bVal"></param>\r
-    public void emitbyte(byte bVal) { \r
-      AddToBuffer(new CILByte(bVal));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an instruction which puts an integer on TOS.  This method\r
-    /// selects the correct instruction based on the value of the integer.\r
-    /// </summary>\r
-    /// <param name="i">the integer value</param>\r
-    public void PushInt(int i) {\r
-      if (i == -1) {\r
-        AddToBuffer(new Instr((int)Op.ldc_i4_m1));\r
-      } else if ((i >= 0) && (i <= 8)) {\r
-        Op op = (Op)(Op.ldc_i4_0 + i);\r
-        AddToBuffer(new Instr((int)op));\r
-      } else if ((i >= minByteVal) && (i <= maxByteVal)) {\r
-        AddToBuffer(new IntInstr((int)IntOp.ldc_i4_s,i,true));\r
-      } else {\r
-        AddToBuffer(new IntInstr((int)IntOp.ldc_i4,i,false)); \r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to load a long on TOS\r
-    /// </summary>\r
-    /// <param name="l">the long value</param>\r
-    public void PushLong(long l) {\r
-      AddToBuffer(new LongInstr(0x21,l));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an instruction to push the boolean value true on TOS\r
-    /// </summary>\r
-    public void PushTrue() {\r
-      AddToBuffer(new Instr((int)Op.ldc_i4_1));\r
-    }\r
-\r
-    /// <summary>\r
-    ///  Add an instruction to push the boolean value false on TOS\r
-    /// </summary>\r
-    public void PushFalse() {\r
-      AddToBuffer(new Instr((int)Op.ldc_i4_0));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to load an argument on TOS.  This method\r
-    /// selects the correct instruction based on the value of argNo\r
-    /// </summary>\r
-    /// <param name="argNo">the number of the argument</param>\r
-    public void LoadArg(int argNo) {\r
-      if (argNo < 4) {\r
-        int op = (int)Op.ldarg_0 + argNo;\r
-        AddToBuffer(new Instr(op));\r
-      } else if (argNo <= maxUByteVal) {\r
-        AddToBuffer(new UIntInstr((int)IntOp.ldarg,argNo,true));\r
-      } else {\r
-        AddToBuffer(new UIntInstr(0x09,argNo,false)); \r
-      }\r
-   }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to load the address of an argument on TOS.\r
-    /// This method selects the correct instruction based on the value\r
-    /// of argNo.\r
-    /// </summary>\r
-    /// <param name="argNo">the number of the argument</param>\r
-    public void LoadArgAdr(int argNo) {\r
-      if (argNo <= maxUByteVal) {\r
-        AddToBuffer(new UIntInstr((int)IntOp.ldarga,argNo,true));\r
-      } else {\r
-        AddToBuffer(new UIntInstr(0x0A,argNo,false)); \r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to load a local on TOS.  This method selects\r
-    /// the correct instruction based on the value of locNo.\r
-    /// </summary>\r
-    /// <param name="locNo">the number of the local to load</param>\r
-    public void LoadLocal(int locNo) {\r
-      if (locNo < 4) {\r
-        int op = (int)Op.ldloc_0 + locNo;\r
-        AddToBuffer(new Instr(op));\r
-      } else if (locNo <= maxUByteVal) {\r
-        AddToBuffer(new UIntInstr((int)IntOp.ldloc,locNo,true));\r
-      } else {\r
-        AddToBuffer(new UIntInstr(0x0C,locNo,false)); \r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to load the address of a local on TOS.\r
-    /// This method selects the correct instruction based on the \r
-    /// value of locNo.\r
-    /// </summary>\r
-    /// <param name="locNo">the number of the local</param>\r
-    public void LoadLocalAdr(int locNo) {\r
-      if (locNo <= maxUByteVal) {\r
-        AddToBuffer(new UIntInstr((int)IntOp.ldloca,locNo,true));\r
-      } else {\r
-        AddToBuffer(new UIntInstr(0x0D,locNo,false)); \r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to store to an argument.  This method\r
-    /// selects the correct instruction based on the value of argNo.\r
-    /// </summary>\r
-    /// <param name="argNo">the argument to be stored to</param>\r
-    public void StoreArg(int argNo) {\r
-      if (argNo <= maxUByteVal) {\r
-        AddToBuffer(new UIntInstr((int)IntOp.starg,argNo,true));\r
-      } else {\r
-        AddToBuffer(new UIntInstr(0x0B,argNo,false)); \r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the instruction to store to a local.  This method selects\r
-    /// the correct instruction based on the value of locNo.\r
-    /// </summary>\r
-    /// <param name="locNo">the local to be stored to</param>\r
-    public void StoreLocal(int locNo) {\r
-      if (locNo < 4) {\r
-        int op = (int)Op.stloc_0 + locNo;\r
-        AddToBuffer(new Instr(op));\r
-      } else if (locNo <= maxUByteVal) {\r
-        AddToBuffer(new UIntInstr((int)IntOp.stloc,locNo,true));\r
-      } else {\r
-        AddToBuffer(new UIntInstr(0x0E,locNo,false)); \r
-      }\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new CIL label.  To place the label in the CIL instruction\r
-    /// stream use CodeLabel.\r
-    /// </summary>\r
-    /// <returns>a new CIL label</returns>\r
-    public CILLabel NewLabel() {\r
-      return new CILLabel();\r
-    }\r
-\r
-    public void AddTryBlock(TryBlock tryBlock) {\r
-      if (exceptions == null) \r
-        exceptions = new ArrayList();\r
-      else if (exceptions.Contains(tryBlock)) return;\r
-      exceptions.Add(tryBlock);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new label at this position in the code buffer\r
-    /// </summary>\r
-    /// <returns>the label at the current position</returns>\r
-    public CILLabel NewCodedLabel() {\r
-      CILLabel lab = new CILLabel();\r
-      AddToBuffer(new LabelInstr(lab));\r
-      return lab;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this position as the start of a new block\r
-    /// (try, catch, filter, finally or fault)\r
-    /// </summary>\r
-    public void StartBlock() {\r
-      if (blockStack == null) blockStack = new ArrayList();\r
-      blockStack.Insert(0,NewCodedLabel());\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this position as the end of the last started block and\r
-    /// make it a try block.  This try block is added to the current \r
-    /// instructions (ie do not need to call AddTryBlock)\r
-    /// </summary>\r
-    /// <returns>The try block just ended</returns>\r
-    public TryBlock EndTryBlock() {\r
-      TryBlock tBlock = new TryBlock((CILLabel)blockStack[0],NewCodedLabel());\r
-      blockStack.RemoveAt(0);\r
-      AddTryBlock(tBlock);\r
-      return tBlock;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this position as the end of the last started block and\r
-    /// make it a catch block.  This catch block is associated with the\r
-    /// specified try block.\r
-    /// </summary>\r
-    /// <param name="exceptType">the exception type to be caught</param>\r
-    /// <param name="tryBlock">the try block associated with this catch block</param>\r
-    public void EndCatchBlock(Class exceptType, TryBlock tryBlock) {\r
-      Catch catchBlock = new Catch(exceptType,(CILLabel)blockStack[0],\r
-        NewCodedLabel());\r
-      tryBlock.AddHandler(catchBlock);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this position as the end of the last started block and\r
-    /// make it a filter block.  This filter block is associated with the\r
-    /// specified try block.\r
-    /// </summary>\r
-    /// <param name="filterLab">the label where the filter code is</param>\r
-    /// <param name="tryBlock">the try block associated with this filter block</param>\r
-    public void EndFilterBlock(CILLabel filterLab, TryBlock tryBlock) {\r
-      Filter filBlock = new Filter(filterLab,(CILLabel)blockStack[0],NewCodedLabel());\r
-      tryBlock.AddHandler(filBlock);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this position as the end of the last started block and\r
-    /// make it a finally block.  This finally block is associated with the\r
-    /// specified try block.\r
-    /// </summary>\r
-    /// <param name="tryBlock">the try block associated with this finally block</param>\r
-    public void EndFinallyBlock(TryBlock tryBlock) {\r
-      Finally finBlock= new Finally((CILLabel)blockStack[0],NewCodedLabel());\r
-      tryBlock.AddHandler(finBlock);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this position as the end of the last started block and\r
-    /// make it a fault block.  This fault block is associated with the\r
-    /// specified try block.\r
-    /// </summary>\r
-    /// <param name="tryBlock">the try block associated with this fault block</param>\r
-    public void EndFaultBlock(TryBlock tryBlock) {\r
-      Fault fBlock= new Fault((CILLabel)blockStack[0],NewCodedLabel());\r
-      tryBlock.AddHandler(fBlock);\r
-    }\r
-\r
-    internal uint GetCodeSize() {\r
-      return codeSize + paddingNeeded + exceptSize;\r
-    }\r
-\r
-    internal void CheckCode(uint locSigIx, bool initLocals, int maxStack) {\r
-      if (tide == 0) return;\r
-      bool changed = true;\r
-      while (changed) {\r
-        changed = false;\r
-        for (int i=0; i < tide; i++) {\r
-          changed = buffer[i].Check(metaData) || changed;\r
-        }\r
-        if (changed) {\r
-          for (int i=1; i < tide; i++) {\r
-            buffer[i].offset = buffer[i-1].offset + buffer[i-1].size;\r
-          }\r
-          offset = buffer[tide-1].offset + buffer[tide-1].size;\r
-        }\r
-      }\r
-                       codeSize = offset;\r
-                       // Console.WriteLine("codeSize before header added = " + codeSize);\r
-      if ((offset < smallSize) && (maxStack <= 8) && (locSigIx == 0) && (exceptions == null)) {\r
-        // can use tiny header\r
-        //Console.WriteLine("Tiny Header");\r
-        tinyFormat = true;\r
-        headerFlags = (ushort)(TinyFormat | ((ushort)codeSize << 2));\r
-        codeSize++;\r
-        if ((codeSize % 4) != 0) { paddingNeeded = 4 - (codeSize % 4); }\r
-      } else {\r
-        //Console.WriteLine("Fat Header");\r
-        tinyFormat = false;\r
-        localSigIx = locSigIx;\r
-        this.maxStack = (short)maxStack;\r
-        headerFlags = FatFormat;\r
-        if (exceptions != null) {\r
-          // Console.WriteLine("Got exceptions");\r
-          headerFlags |= MoreSects;\r
-          uint numExceptClauses = 0;\r
-          for (int i=0; i < exceptions.Count; i++) {\r
-            TryBlock tryBlock = (TryBlock)exceptions[i];\r
-            tryBlock.SetSize();\r
-            numExceptClauses += (uint)tryBlock.NumHandlers();\r
-            if (tryBlock.isFat()) fatExceptionFormat = true;\r
-          }\r
-          // Console.WriteLine("numexceptclauses = " + numExceptClauses);\r
-          if (fatExceptionFormat) {\r
-            // Console.WriteLine("Fat exception format");\r
-            exceptHeader = FatExceptTable;\r
-            exceptSize = ExHeaderSize + numExceptClauses * FatExClauseSize;\r
-          } else {\r
-            // Console.WriteLine("Tiny exception format");\r
-            exceptHeader = SmlExceptTable;\r
-            exceptSize = ExHeaderSize + numExceptClauses * SmlExClauseSize;\r
-          }\r
-          // Console.WriteLine("exceptSize = " + exceptSize);\r
-        }\r
-        if (initLocals) headerFlags |= InitLocals;\r
-        if ((offset % 4) != 0) { paddingNeeded = 4 - (offset % 4); }\r
-        codeSize += FatSize;\r
-      }\r
-                 // Console.WriteLine("codeSize = " + codeSize + "  headerFlags = " + \r
-      //                   Hex.Short(headerFlags));\r
-    }\r
-\r
-               internal void Write(FileImage output) {\r
-      // Console.WriteLine("Writing header flags = " + Hex.Short(headerFlags));\r
-                       if (tinyFormat) {\r
-        // Console.WriteLine("Writing tiny code");\r
-                               output.Write((byte)headerFlags);\r
-                       } else {\r
-        // Console.WriteLine("Writing fat code");\r
-                               output.Write(headerFlags);\r
-                               output.Write((ushort)maxStack);\r
-                               output.Write(offset);\r
-                               output.Write(localSigIx);\r
-                       }\r
-      // Console.WriteLine(Hex.Int(tide) + " CIL instructions");\r
-      // Console.WriteLine("starting instructions at " + output.Seek(0,SeekOrigin.Current));\r
-                       for (int i=0; i < tide; i++) {\r
-                               buffer[i].Write(output);\r
-                       }\r
-      // Console.WriteLine("ending instructions at " + output.Seek(0,SeekOrigin.Current));\r
-      for (int i=0; i < paddingNeeded; i++) { output.Write((byte)0); }\r
-      if (exceptions != null) {\r
-        // Console.WriteLine("Writing exceptions");\r
-        // Console.WriteLine("header = " + Hex.Short(exceptHeader) + " exceptSize = " + Hex.Int(exceptSize));\r
-        output.Write(exceptHeader);\r
-        output.Write3Bytes((uint)exceptSize);\r
-        for (int i=0; i < exceptions.Count; i++) {\r
-          TryBlock tryBlock = (TryBlock)exceptions[i];\r
-          tryBlock.Write(output,fatExceptionFormat);\r
-        }\r
-      }\r
-               }\r
-\r
-  }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// A label in the IL\r
-       /// </summary>\r
-       public class CILLabel\r
-       {\r
-    CILInstruction branch;\r
-    CILInstruction[] multipleBranches;\r
-    int tide = 0;\r
-    CILInstruction labInstr;\r
-    uint offset = 0;\r
\r
-    public CILLabel (uint offset) {\r
-       this.offset = offset;\r
-       }\r
-       \r
-\r
-    internal CILLabel() {\r
-    }
-\r
-    internal void AddBranch(CILInstruction instr) {\r
-      if (branch == null) {\r
-        branch = instr;\r
-        return;\r
-      }\r
-      if (multipleBranches == null) {\r
-        multipleBranches = new CILInstruction[2];\r
-      } else if (tide >= multipleBranches.Length) {\r
-        CILInstruction[] tmp = multipleBranches;\r
-        multipleBranches = new CILInstruction[tmp.Length*2];\r
-        for (int i=0; i < tide; i++) {\r
-          multipleBranches[i] = tmp[i];\r
-        }\r
-      }\r
-      multipleBranches[tide++] = instr;\r
-    }\r
-\r
-    internal void AddLabelInstr(LabelInstr lInstr) {\r
-      labInstr = lInstr;\r
-    }\r
-\r
-    internal uint GetLabelOffset() {\r
-      if (labInstr == null) return 0;\r
-      return labInstr.offset + offset;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-  public abstract class CodeBlock {\r
-\r
-    private static readonly int maxCodeSize = 256;\r
-    protected CILLabel start, end;\r
-    protected bool small = true;\r
-\r
-    public CodeBlock(CILLabel start, CILLabel end) {\r
-      this.start = start;\r
-      this.end = end;\r
-    }\r
-\r
-    internal virtual bool isFat() {\r
-      // Console.WriteLine("block start = " + start.GetLabelOffset() +\r
-      //                  "  block end = " + end.GetLabelOffset());\r
-      return (end.GetLabelOffset() - start.GetLabelOffset()) > maxCodeSize;\r
-    }\r
-\r
-    internal virtual void Write(FileImage output, bool fatFormat) {\r
-      if (fatFormat) output.Write(start.GetLabelOffset());\r
-      else output.Write((short)start.GetLabelOffset());\r
-      uint len = end.GetLabelOffset() - start.GetLabelOffset();\r
-      if (fatFormat) output.Write(len);\r
-      else output.Write((byte)len);\r
-    }\r
-\r
-  }\r
-\r
-  /// <summary>\r
-  /// The descriptor for a guarded block (.try)\r
-  /// </summary>\r
-  public class TryBlock : CodeBlock {\r
-    protected bool fatFormat = false;\r
-    protected int flags = 0;\r
-    ArrayList handlers = new ArrayList();\r
-\r
-    /// <summary>\r
-    /// Create a new try block\r
-    /// </summary>\r
-    /// <param name="start">start label for the try block</param>\r
-    /// <param name="end">end label for the try block</param>\r
-    public TryBlock(CILLabel start, CILLabel end) : base(start,end) { }\r
-\r
-    /// <summary>\r
-    /// Add a handler to this try block\r
-    /// </summary>\r
-    /// <param name="handler">a handler to be added to the try block</param>\r
-    public void AddHandler(HandlerBlock handler) {\r
-      flags = handler.GetFlag();\r
-      handlers.Add(handler);\r
-    }\r
-\r
-    internal void SetSize() {\r
-      fatFormat = base.isFat();\r
-      if (fatFormat) return;\r
-      for (int i=0; i < handlers.Count; i++) {\r
-        HandlerBlock handler = (HandlerBlock)handlers[i];\r
-        if (handler.isFat()) {\r
-          fatFormat = true;\r
-          return;\r
-        }\r
-      }\r
-    }\r
-\r
-    internal int NumHandlers() {\r
-      return handlers.Count;\r
-  }\r
-\r
-    internal override bool isFat() {\r
-      return fatFormat;\r
-    }\r
-\r
-    internal override void Write(FileImage output, bool fatFormat) {\r
-      // Console.WriteLine("writing exception details");\r
-      for (int i=0; i < handlers.Count; i++) {\r
-        // Console.WriteLine("Except block " + i);\r
-        HandlerBlock handler = (HandlerBlock)handlers[i];\r
-        if (fatFormat) output.Write(flags);\r
-        else output.Write((short)flags);\r
-        // Console.WriteLine("flags = " + Hex.Short(flags));\r
-        base.Write(output,fatFormat);\r
-        handler.Write(output,fatFormat);\r
-      }\r
-    }\r
-  }\r
-\r
-  public abstract class HandlerBlock : CodeBlock \r
-  {\r
-    protected static readonly short ExceptionFlag = 0;\r
-    protected static readonly short FilterFlag = 0x01;\r
-    protected static readonly short FinallyFlag = 0x02;\r
-    protected static readonly short FaultFlag = 0x04;\r
-\r
-    public HandlerBlock(CILLabel start, CILLabel end) : base(start,end) { }\r
-\r
-    internal virtual short GetFlag() { return ExceptionFlag; }\r
-\r
-    internal override void Write(FileImage output, bool fatFormat) {\r
-      base.Write(output,fatFormat);\r
-    }\r
-\r
-  }\r
-\r
-  /// <summary>\r
-  /// The descriptor for a catch clause (.catch)\r
-  /// </summary>\r
-  public class Catch : HandlerBlock \r
-  {\r
-    Class exceptType;\r
-    \r
-    /// <summary>\r
-    /// Create a new catch clause\r
-    /// </summary>\r
-    /// <param name="except">the exception to be caught</param>\r
-    /// <param name="handlerStart">start of the handler code</param>\r
-    /// <param name="handlerEnd">end of the handler code</param>\r
-    public Catch(Class except, CILLabel handlerStart, CILLabel handlerEnd) \r
-                                            : base(handlerStart,handlerEnd) {\r
-      exceptType = except;\r
-    }\r
-\r
-    internal override void Write(FileImage output, bool fatFormat) {\r
-      base.Write(output,fatFormat);\r
-      output.Write(exceptType.Token());\r
-    }\r
-  }\r
-\r
-  /// <summary>\r
-  /// The descriptor for a filter clause (.filter)\r
-  /// </summary>\r
-  public class Filter : HandlerBlock \r
-  {\r
-    CILLabel filterLabel;\r
-\r
-    /// <summary>\r
-    /// Create a new filter clause\r
-    /// </summary>\r
-    /// <param name="filterLabel">the label where the filter code starts</param>\r
-    /// <param name="handlerStart">the start of the handler code</param>\r
-    /// <param name="handlerEnd">the end of the handler code</param>\r
-    public Filter(CILLabel filterLabel, CILLabel handlerStart, \r
-                        CILLabel handlerEnd) : base(handlerStart,handlerEnd) {\r
-      this.filterLabel = filterLabel;\r
-    }\r
-\r
-    internal override short GetFlag() { \r
-      return FilterFlag; \r
-    }\r
-\r
-    internal override void Write(FileImage output, bool fatFormat) {\r
-      base.Write(output,fatFormat);\r
-      output.Write(filterLabel.GetLabelOffset());\r
-    }\r
-\r
-  }\r
-\r
-  /// <summary>\r
-  /// Descriptor for a finally block (.finally)\r
-  /// </summary>\r
-  public class Finally : HandlerBlock \r
-  {\r
-    /// <summary>\r
-    /// Create a new finally clause\r
-    /// </summary>\r
-    /// <param name="finallyStart">start of finally code</param>\r
-    /// <param name="finallyEnd">end of finally code</param>\r
-    public Finally(CILLabel finallyStart, CILLabel finallyEnd)\r
-      : base(finallyStart,finallyEnd) { }\r
-\r
-    internal override short GetFlag() { \r
-      return FinallyFlag; \r
-    }\r
-\r
-    internal override void Write(FileImage output, bool fatFormat) {\r
-      base.Write(output,fatFormat);\r
-      output.Write((int)0);\r
-    }\r
-\r
-  }\r
-\r
-  /// <summary>\r
-  /// Descriptor for a fault block (.fault)\r
-  /// </summary>\r
-  public class Fault : HandlerBlock \r
-  {\r
-    /// <summary>\r
-    /// Create a new fault clause\r
-    /// </summary>\r
-    /// <param name="faultStart">start of the fault code</param>\r
-    /// <param name="faultEnd">end of the fault code</param>\r
-    public Fault(CILLabel faultStart, CILLabel faultEnd)\r
-                                              : base(faultStart,faultEnd) { }\r
-\r
-    internal override short GetFlag() { \r
-      return FaultFlag; \r
-    }\r
-\r
-    internal override void Write(FileImage output, bool fatFormat) {\r
-      base.Write(output,fatFormat);\r
-      output.Write((int)0);\r
-      \r
-    }\r
-  }\r
-\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-       /// The base descriptor for a class \r
-       /// </summary>\r
-       public abstract class Class : Type\r
-       {\r
-    protected int row = 0;\r
-    protected string name, nameSpace;\r
-    protected uint nameIx, nameSpaceIx;\r
-                protected MetaData _metaData;\r
-               internal Class(string nameSpaceName, string className, MetaData md)\r
-                                                              : base(0x12) {\r
-      nameSpace = nameSpaceName;\r
-      name = className;\r
-      nameIx = md.AddToStringsHeap(name);\r
-      nameSpaceIx = md.AddToStringsHeap(nameSpace);\r
-      _metaData = md;\r
-    }\r
-\r
-    internal Class(uint nsIx, uint nIx) : base(0x12) {\r
-      nameSpaceIx = nsIx;\r
-      nameIx = nIx;\r
-    }\r
-\r
-    public BoundArray GetBoundArray (uint dimensions, int[] loBounds,\r
-                    int[] upBounds) {\r
-            BoundArray bound_array = new BoundArray (this, _metaData, nameSpace,\r
-                            name, dimensions, loBounds, upBounds);\r
-            return bound_array;\r
-    }\r
-\r
-    public ZeroBasedArray GetZeroBasedArray () {\r
-            ZeroBasedArray array = new ZeroBasedArray (this, _metaData,\r
-                            nameSpace, name);\r
-            return array;\r
-    }\r
-\r
-    internal virtual uint TypeDefOrRefToken() { return 0; }\r
-\r
-    internal virtual void MakeValueClass() {\r
-      typeIndex = 0x11;\r
-    }\r
-       \r
-    internal virtual string TypeName() {\r
-      return (nameSpace + "." + name);\r
-    }\r
-\r
-    internal override MetaDataElement GetTypeSpec(MetaData md) {\r
-      return this;\r
-    }\r
-       }\r
-  /**************************************************************************/  \r
-  // This Class produces entries in the TypeDef table of the MetaData \r
-  // in the PE meta data.\r
-\r
-  // NOTE:  Entry 0 in TypeDef table is always the pseudo class <module> \r
-  // which is the parent for functions and variables declared a module level\r
-\r
-  /// <summary>\r
-       /// The descriptor for a class defined in the IL (.class) in the current assembly/module\r
-       /// </summary>\r
-       /// \r
-       public class ClassDef : Class\r
-       {\r
-    private static readonly uint HasSecurity = 0x00040000;\r
-    private static readonly byte ElementType_Class = 0x12;\r
-\r
-    Class superType;\r
-    ArrayList fields = new ArrayList();\r
-    ArrayList methods = new ArrayList();\r
-    ArrayList events;\r
-    ArrayList properties;\r
-    bool typeIndexChecked = true;\r
-    uint fieldIx = 0, methodIx = 0;\r
-    byte[] securityActions;\r
-    uint flags;\r
-    ClassLayout layout;\r
-    ClassDef parentClass;\r
-    MetaData metaData;\r
-    \r
-    internal ClassDef(TypeAttr attrSet, string nsName, string name, \r
-                      MetaData md) : base(nsName, name, md) {\r
-                       metaData = md;\r
-      superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);\r
-      flags = (uint)attrSet;\r
-      tabIx = MDTable.TypeDef;\r
-    }\r
-\r
-    internal void SetSuper(Class sClass) {\r
-      superType = sClass;\r
-      if (sClass is ClassRef)\r
-        typeIndex = superType.GetTypeIndex();\r
-      else\r
-        typeIndexChecked = false;\r
-    }\r
-\r
-    internal override void MakeValueClass() {\r
-      superType = metaData.mscorlib.ValueType();\r
-      typeIndex = superType.GetTypeIndex();\r
-    }\r
-\r
-    internal void SpecialNoSuper() {\r
-      superType = null;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an attribute to this class\r
-    /// </summary>\r
-    /// <param name="ta">the attribute to be added</param>\r
-    public void AddAttribute(TypeAttr ta) { \r
-      flags |= (uint)ta;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an interface that is implemented by this class\r
-    /// </summary>\r
-    /// <param name="iFace">the interface that is implemented</param>\r
-    public void AddImplementedInterface(Class iFace) {\r
-      metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));\r
-    }\r
-\r
-    /// <summary>\r
-    ///   Add a generic type parameter.\r
-    /// </summary>\r
-    public void AddGenericParameter (short index) {\r
-            metaData.AddToTable (MDTable.GenericParam, new GenericParameter (this, index));\r
-    }\r
-\r
-    /// <summary>\r
-    ///  Add a named generic type parameter\r
-    /// </summary>\r
-    public void AddGenericParameter (short index, string name) {\r
-        metaData.AddToTable (MDTable.GenericParam, new GenericParameter (this, index, name));\r
-    }\r
-\r
-    public void AddGenericParameter (short index, Type constraint) {\r
-        GenericParameter gp = new GenericParameter (this, index);\r
-        metaData.AddToTable (MDTable.GenericParam, gp);\r
-        metaData.AddToTable (MDTable.GenericParamConstraint,\r
-            new GenericParamConstraint (gp, constraint));\r
-    }\r
-\r
-    public void AddGenericParameter (short index, string name, Type constraint) {\r
-        GenericParameter gp = new GenericParameter (this, index, name);\r
-        metaData.AddToTable (MDTable.GenericParam, gp);\r
-        metaData.AddToTable (MDTable.GenericParamConstraint,\r
-            new GenericParamConstraint (gp, constraint));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a field to this class\r
-    /// </summary>\r
-    /// <param name="name">field name</param>\r
-    /// <param name="fType">field type</param>\r
-    /// <returns>a descriptor for this new field</returns>\r
-    public FieldDef AddField(string name, Type fType) {\r
-      FieldDef field = new FieldDef(name,fType);\r
-      fields.Add(field);\r
-      return field;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a field to this class\r
-    /// </summary>\r
-    /// <param name="fAtts">attributes for this field</param>\r
-    /// <param name="name">field name</param>\r
-    /// <param name="fType">field type</param>\r
-    /// <returns>a descriptor for this new field</returns>\r
-    public FieldDef AddField(FieldAttr fAtts, string name, Type fType) {\r
-      FieldDef field = new FieldDef(fAtts,name,fType);\r
-      fields.Add(field);\r
-      return field;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a method to this class\r
-    /// </summary>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">parameters</param>\r
-    /// <returns>a descriptor for this new method</returns>\r
-    public MethodDef AddMethod(string name, Type retType, Param[] pars) {\r
-      // Console.WriteLine("Adding method " + name + " to class " + this.name);\r
-      MethodDef meth = new MethodDef(metaData,name,retType, pars);\r
-      methods.Add(meth);\r
-      return meth;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a method to this class\r
-    /// </summary>\r
-    /// <param name="mAtts">attributes for this method</param>\r
-    /// <param name="iAtts">implementation attributes for this method</param>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">parameters</param>\r
-    /// <returns>a descriptor for this new method</returns>\r
-    public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, \r
-                               Type retType, Param[] pars) {\r
-      // Console.WriteLine("Adding method " + name + " to class " + this.name);\r
-      MethodDef meth = new MethodDef(metaData,mAtts,iAtts,name,retType,pars);\r
-      methods.Add(meth);\r
-      return meth;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an event to this class\r
-    /// </summary>\r
-    /// <param name="name">event name</param>\r
-    /// <param name="eType">event type</param>\r
-    /// <returns>a descriptor for this new event</returns>\r
-    public Event AddEvent(string name, Type eType) {\r
-      Event e = new Event(name,eType,this);\r
-      if (events == null) events = new ArrayList();\r
-      events.Add(e);\r
-      return e;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a property to this class\r
-    /// </summary>\r
-    /// <param name="name">property name</param>\r
-    /// <param name="propType">property type</param>\r
-    /// <returns>a descriptor for this new property</returns>\r
-    public Property AddProperty(string name, Type retType, Type[] pars) {\r
-      Property p = new Property(name, retType, pars, this);\r
-      if (properties == null) properties = new ArrayList();\r
-      properties.Add(p);\r
-      return p;\r
-    }\r
-\r
-\r
-    /// <summary>\r
-    /// Add a nested class to this class\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes for this nested class</param>\r
-    /// <param name="nsName">nested name space name</param>\r
-    /// <param name="name">nested class name</param>\r
-    /// <returns>a descriptor for this new nested class</returns>\r
-    public ClassDef AddNestedClass(TypeAttr attrSet, string nsName, \r
-                                   string name) {\r
-      ClassDef nClass = new ClassDef(attrSet,nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeDef,nClass);\r
-      metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));\r
-      nClass.parentClass = this;\r
-      return (nClass);\r
-     }\r
-\r
-    /// <summary>\r
-    /// Add a nested class to this class\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes for this nested class</param>\r
-    /// <param name="nsName">nested name space name</param>\r
-    /// <param name="name">nested class name</param>\r
-    /// <param name="sType">super type of this nested class</param>\r
-    /// <returns>a descriptor for this new nested class</returns>\r
-    public ClassDef AddNestedClass(TypeAttr attrSet, string nsName, \r
-                                   string name, Class sType) {\r
-      ClassDef nClass = new ClassDef(attrSet,nsName,name,metaData);\r
-      nClass.SetSuper(sType);\r
-      metaData.AddToTable(MDTable.TypeDef,nClass);\r
-      metaData.AddToTable(MDTable.NestedClass,\r
-                          new MapElem(nClass,Row,MDTable.TypeDef));\r
-      nClass.parentClass = this;\r
-      return (nClass);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add layout information for this class.  This class must have the\r
-    /// sequential or explicit attribute.\r
-    /// </summary>\r
-    /// <param name="packSize">packing size (.pack)</param>\r
-    /// <param name="classSize">class size (.size)</param>\r
-    public void AddLayoutInfo (int packSize, int classSize) {\r
-      layout = new ClassLayout(packSize,classSize,this);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Use a method as the implementation for another method (.override)\r
-    /// </summary>\r
-    /// <param name="decl">the method to be overridden</param>\r
-    /// <param name="body">the implementation to be used</param>\r
-    public void AddMethodOverride(Method decl, Method body) {\r
-      metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add security to this class NOT YET IMPLEMENTED\r
-    /// </summary>\r
-    /// <param name="permissionSet"></param>\r
-    public void AddSecurity(byte[] permissionSet) {\r
-      throw(new NotYetImplementedException("Class security "));\r
-      //flags |= HasSecurity;\r
-     // securityActions = permissionSet;\r
-    }\r
-\r
-    //public void AddLineInfo(int row, int col) { }\r
-\r
-    internal void CheckTypeIndex() {\r
-      if (typeIndexChecked) return;\r
-      if (!(superType is ClassRef)) \r
-        ((ClassDef)superType).CheckTypeIndex();\r
-      typeIndex = superType.GetTypeIndex();\r
-      typeIndexChecked = true;\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }\r
-      // Console.WriteLine("Building tables for " + name);\r
-      if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);\r
-      // Console.WriteLine("adding methods " + methods.Count);\r
-      methodIx = md.TableIndex(MDTable.Method);\r
-      for (int i=0; i < methods.Count; i++) {\r
-        md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);\r
-        ((MethodDef)methods[i]).BuildTables(md);\r
-      }\r
-      // Console.WriteLine("adding fields");\r
-      fieldIx = md.TableIndex(MDTable.Field);\r
-      for (int i=0; i < fields.Count; i++) {\r
-        md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);\r
-        ((FieldDef)fields[i]).BuildTables(md);\r
-      }\r
-      // Console.WriteLine("adding events and properties");\r
-      if (events != null) { \r
-        for (int i=0; i < events.Count; i++) {\r
-          md.AddToTable(MDTable.Event,(Event)events[i]);\r
-          ((Event)events[i]).BuildTables(md);\r
-        }\r
-        md.AddToTable(MDTable.EventMap,\r
-          new MapElem(this,((Event)events[0]).Row,MDTable.Event));\r
-      }\r
-      if (properties != null) { \r
-        for (int i=0; i < properties.Count; i++) {\r
-          md.AddToTable(MDTable.Property,(Property)properties[i]);\r
-          ((Property)properties[i]).BuildTables(md);\r
-        }\r
-        md.AddToTable(MDTable.PropertyMap,new MapElem(this,\r
-                          ((Property)properties[0]).Row,MDTable.Property));\r
-      }\r
-      DoCustomAttributes (md);\r
-      // Console.WriteLine("End of building tables");\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 4 + 2 * md.StringsIndexSize() + \r
-        md.CodedIndexSize(CIx.TypeDefOrRef) +\r
-        md.TableIndexSize(MDTable.Field) + \r
-        md.TableIndexSize(MDTable.Method);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.StringsIndex(nameIx);\r
-      output.StringsIndex(nameSpaceIx);\r
-      //if (superType != null) \r
-      // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));\r
-      output.WriteCodedIndex(CIx.TypeDefOrRef,superType);\r
-      output.WriteIndex(MDTable.Field,fieldIx);\r
-      output.WriteIndex(MDTable.Method,methodIx);\r
-    }\r
-\r
-    internal sealed override uint TypeDefOrRefToken() {\r
-      uint cIx = Row;\r
-      cIx = cIx << 2;\r
-      return cIx;\r
-    }\r
-\r
-    internal sealed override void TypeSig(MemoryStream sig) {\r
-      if (!typeIndexChecked) CheckTypeIndex();\r
-      sig.WriteByte(GetTypeIndex());\r
-      MetaData.CompressNum(TypeDefOrRefToken(),sig);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.TypeDefOrRef) : return 0; \r
-        case (CIx.HasCustomAttr) : return 3; \r
-        case (CIx.HasDeclSecurity) : return 0; \r
-        case (CIx.TypeOrMethodDef) : return 0; \r
-      }\r
-      return 0;\r
-    }\r
\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Layout information for a class (.class [sequential | explicit])\r
-       /// </summary>\r
-       internal class ClassLayout : MetaDataElement\r
-       {\r
-    ClassDef parent;\r
-    ushort packSize = 0;\r
-    uint classSize = 0;\r
-\r
-               internal ClassLayout(int pack, int cSize, ClassDef par) {\r
-      packSize = (ushort)pack;\r
-      classSize = (uint)cSize;\r
-      parent = par;\r
-      tabIx = MDTable.ClassLayout;\r
-               }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 6 + md.TableIndexSize(MDTable.TypeDef);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(packSize);\r
-      output.Write(classSize);\r
-      output.WriteIndex(MDTable.TypeDef,parent.Row);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a class/interface declared in another module of THIS \r
-       /// assembly, or in another assembly.\r
-       /// </summary>\r
-       public class ClassRef : Class\r
-       {\r
-    protected ResolutionScope parent;\r
-    ExternClass externClass;\r
-    protected MetaData metaData;\r
-\r
-               internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md) {\r
-      metaData = md;\r
-      tabIx = MDTable.TypeRef;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a method to this class\r
-    /// </summary>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">parameter types</param>\r
-    /// <returns>a descriptor for this method</returns>\r
-    public MethodRef AddMethod(string name, Type retType, Type[] pars) {\r
-      MethodRef meth = new MethodRef(this,name,retType,pars,false,null);\r
-      metaData.AddToTable(MDTable.MemberRef,meth);\r
-      return meth;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a method to this class\r
-    /// </summary>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">parameter types</param>\r
-    /// <returns>a descriptor for this method</returns>\r
-    public MethodRef AddVarArgMethod(string name, Type retType, \r
-                                     Type[] pars, Type[] optPars) {\r
-      MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);\r
-      metaData.AddToTable(MDTable.MemberRef,meth);\r
-      return meth;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a field to this class\r
-    /// </summary>\r
-    /// <param name="name">field name</param>\r
-    /// <param name="fType">field type</param>\r
-    /// <returns>a descriptor for this field</returns>\r
-    public FieldRef AddField(string name, Type fType) {\r
-      FieldRef field = new FieldRef(this,name,fType);\r
-      metaData.AddToTable(MDTable.MemberRef,field);\r
-      return field;\r
-    }\r
-\r
-    internal void SetParent(ResolutionScope par) {\r
-      parent = par;\r
-    }\r
-\r
-    internal override string TypeName() {\r
-      if ((parent != null) && (parent is AssemblyRef))\r
-        return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());\r
-      else \r
-        return (nameSpace + name);\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.CodedIndexSize(CIx.ResolutionScope) + 2 * \r
-             md.StringsIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteCodedIndex(CIx.ResolutionScope,parent);\r
-      output.StringsIndex(nameIx);\r
-      output.StringsIndex(nameSpaceIx);\r
-    }\r
-\r
-    internal override sealed uint TypeDefOrRefToken() {\r
-      uint cIx = Row;\r
-      cIx = (cIx << 2) | 0x1;\r
-      return cIx;\r
-    }\r
-\r
-    internal override void TypeSig(MemoryStream sig) {\r
-      sig.WriteByte(GetTypeIndex());\r
-      MetaData.CompressNum(TypeDefOrRefToken(),sig);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.TypeDefOrRef) : return 1; \r
-        case (CIx.HasCustomAttr) : return 2; \r
-        case (CIx.MemberRefParent) : return 1; \r
-        case (CIx.ResolutionScope) : return 3; \r
-      }\r
-      return 0;\r
-    }\r
\r
-       }\r
-  /**************************************************************************/  \r
-\r
-  public class ExternClassRef : ClassRef {\r
-\r
-    ExternClass externClass;\r
-\r
-    internal ExternClassRef(TypeAttr attrs, string nsName, string name,\r
-                          FileRef declFile, MetaData md) : base(nsName,name,md) {\r
-      externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declFile);\r
-      metaData.AddToTable(MDTable.ExportedType,externClass);\r
-    }\r
-\r
-    internal ExternClassRef(string name, MetaData md) : base(null,name,md) {\r
-    }\r
-\r
-    public ClassRef AddNestedClass(TypeAttr attrs, string name) {\r
-      ExternClassRef nestedClass = new ExternClassRef(name,metaData);\r
-      externClass = new ExternClass(attrs,0,nameIx,this.externClass);\r
-      metaData.AddToTable(MDTable.ExportedType,externClass);\r
-      return nestedClass;\r
-    }\r
\r
-  }\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// Descriptor for a constant value\r
-  /// </summary>\r
-  public abstract class Constant {\r
-    protected uint size = 0;\r
-    protected Type type;\r
-    protected uint blobIndex;\r
-    protected bool addedToBlobHeap = false;\r
-\r
-               internal Constant()     {       }\r
-\r
-    internal virtual uint GetBlobIndex(MetaData md) { return 0; }\r
-\r
-    internal uint GetSize() { return size; }\r
-\r
-    internal byte GetTypeIndex() { return type.GetTypeIndex(); }\r
-\r
-    internal virtual void Write(BinaryWriter bw) {  }\r
-\r
-       }\r
-  /// <summary>\r
-  /// Descriptor for a constant value\r
-  /// </summary>\r
-  public abstract class DataConstant : Constant {\r
-    private uint dataOffset = 0;\r
-\r
-    internal DataConstant() { }\r
-\r
-    public uint DataOffset {\r
-      get { return dataOffset; }\r
-      set { dataOffset = value; }\r
-    }\r
-\r
-  }\r
-\r
-  /// <summary>\r
-  /// Boolean constant\r
-  /// </summary>\r
-  public class BoolConst : Constant {\r
-    bool val;\r
-\r
-    /// <summary>\r
-    /// Create a new boolean constant with the value "val"\r
-    /// </summary>\r
-    /// <param name="val">value of this boolean constant</param>\r
-    public BoolConst(bool val) {\r
-      this.val = val;\r
-      size = 1;\r
-      type = PrimitiveType.Boolean;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        if (val) blobIndex = md.AddToBlobHeap((sbyte)1);\r
-        else blobIndex = md.AddToBlobHeap((sbyte)0);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      if (val) bw.Write((sbyte)1);\r
-      else bw.Write((sbyte)0);\r
-    }\r
-\r
-  }\r
-\r
-  public class ByteArrConst : DataConstant {\r
-    byte[] val;\r
-\r
-    public ByteArrConst(byte[] val) {\r
-      this.val = val;\r
-      size = (uint)val.Length;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap(val);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      bw.Write(val);\r
-    }\r
-\r
-  }\r
-\r
-  public class CharConst : Constant {\r
-    char val;\r
-\r
-    public CharConst(char val) {\r
-      this.val = val;\r
-      size = 2;\r
-      type = PrimitiveType.Char;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap(val);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      bw.Write(val);\r
-    }\r
-\r
-  }\r
-\r
-  public class FloatConst : DataConstant {\r
-    float val;\r
-\r
-    public FloatConst(float val) {\r
-      this.val = val;\r
-      size = 4;\r
-      type = PrimitiveType.Float32;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap(val);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      bw.Write(val);\r
-    }\r
-\r
-  }\r
-\r
-  public class DoubleConst : DataConstant {\r
-    double val;\r
-\r
-    public DoubleConst(double val) {\r
-      this.val = val;\r
-      size = 8;\r
-      type = PrimitiveType.Float64;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap(val);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      bw.Write(val);\r
-    }\r
-\r
-  }\r
-\r
-  public class IntConst : DataConstant {\r
-    long val;\r
-\r
-    public IntConst(sbyte val) {\r
-      this.val = val;\r
-      size = 8;\r
-      type = PrimitiveType.Int8;\r
-    }\r
-\r
-    public IntConst(short val) {\r
-      this.val = val;\r
-      size = 16;\r
-      type = PrimitiveType.Int16;\r
-    }\r
-\r
-    public IntConst(int val) {\r
-      this.val = val;\r
-      size = 32;\r
-      type = PrimitiveType.Int32;\r
-    }\r
-\r
-    public IntConst(long val) {\r
-      this.val = val;\r
-      size = 64;\r
-      type = PrimitiveType.Int64;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        switch (size) {\r
-          case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;\r
-          case (2) : blobIndex = md.AddToBlobHeap((short)val); break;\r
-          case (4) : blobIndex = md.AddToBlobHeap((int)val); break;\r
-          default : blobIndex = md.AddToBlobHeap(val); break; \r
-        }\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      switch (size) {\r
-        case (1) : bw.Write((sbyte)val); break;\r
-        case (2) : bw.Write((short)val); break;\r
-        case (4) : bw.Write((int)val); break;\r
-        default : bw.Write(val); break; \r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  public class UIntConst : Constant {\r
-    long val;\r
-\r
-    public UIntConst(sbyte val) {\r
-      this.val = val;\r
-      size = 8;\r
-      type = PrimitiveType.UInt8;\r
-    }\r
-    public UIntConst(short val) {\r
-      this.val = val;\r
-      size = 16;\r
-      type = PrimitiveType.UInt16;\r
-    }\r
-    public UIntConst(int val) {\r
-      this.val = val;\r
-      size = 32;\r
-      type = PrimitiveType.UInt32;\r
-    }\r
-    public UIntConst(long val) {\r
-      this.val = val;\r
-      size = 64;\r
-      type = PrimitiveType.UInt64;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        switch (size) {\r
-          case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;\r
-          case (2) : blobIndex = md.AddToBlobHeap((short)val); break;\r
-          case (4) : blobIndex = md.AddToBlobHeap((int)val); break;\r
-          default : blobIndex = md.AddToBlobHeap(val); break;\r
-        }\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      switch (size) {\r
-        case (1) : bw.Write((sbyte)val); break;\r
-        case (2) : bw.Write((short)val); break;\r
-        case (4) : bw.Write((int)val); break;\r
-        default : bw.Write(val); break;\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  public class StringConst : DataConstant {\r
-    string val;\r
-\r
-    public StringConst(string val) {\r
-      this.val = val;\r
-      size = (uint)val.Length;  // need to add null ??\r
-      type = PrimitiveType.String;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap(val);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      bw.Write(val);\r
-    }\r
-\r
-  }\r
-\r
-  public class NullConst : Constant {\r
\r
-    public NullConst() { \r
-      size = 4;\r
-      type = PrimitiveType.Class;\r
-    }\r
-\r
-    internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap((int)0);\r
-        addedToBlobHeap = true;\r
-      }\r
-      return blobIndex;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      bw.Write((int)0); \r
-    }\r
-\r
-  }\r
-\r
-  public class AddressConstant : DataConstant {\r
-    DataConstant data;\r
-\r
-    public AddressConstant(DataConstant dConst) {\r
-      data = dConst;\r
-      size = 4;\r
-      type = PrimitiveType.TypedRef;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      ((FileImage)bw).WriteDataRVA(data.DataOffset);\r
-    }\r
-\r
-  }\r
-\r
-  public class RepeatedConstant : DataConstant {\r
-    DataConstant data;\r
-    uint repCount;\r
-\r
-    public RepeatedConstant(DataConstant dConst, int repeatCount) {\r
-      data = dConst;\r
-      repCount = (uint)repeatCount;\r
-      int[] sizes = new int[1];\r
-      sizes[0] = repeatCount;\r
-      type = new BoundArray(type,1,sizes);\r
-      size = data.GetSize() * repCount;\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      for (int i=0; i < repCount; i++) {\r
-        data.Write(bw);\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  public class ArrayConstant : DataConstant {\r
-    DataConstant[] dataVals;\r
-\r
-    public ArrayConstant(DataConstant[] dVals) {\r
-      dataVals = dVals;\r
-      for (int i=0; i < dataVals.Length; i++) {\r
-        size += dataVals[i].GetSize();\r
-      }\r
-    }\r
-\r
-    internal sealed override void Write(BinaryWriter bw) {\r
-      for (int i=0; i < dataVals.Length; i++) {\r
-        dataVals[i].Write(bw);\r
-      }\r
-    }\r
-\r
-  }\r
-\r
-  public class ClassType : Constant {\r
-    string name;\r
-    Class desc;\r
-\r
-    public ClassType(string className) {\r
-      name = className;\r
-      type = PrimitiveType.ClassType;\r
-    }\r
-\r
-    public ClassType(Class classDesc) {\r
-      desc = classDesc;\r
-      type = PrimitiveType.ClassType;\r
-    }\r
-\r
-    internal override void Write(BinaryWriter bw) {\r
-      if (name == null)  name = desc.TypeName();\r
-      bw.Write(name);\r
-    }\r
-\r
-  }\r
-\r
-\r
-\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Summary description for ConstantElem.\r
-       /// </summary>\r
-       internal class ConstantElem : MetaDataElement\r
-       {\r
-    MetaDataElement parent;\r
-    Constant cValue;\r
-    uint valIx = 0;\r
-\r
-               internal ConstantElem(MetaDataElement parent, Constant val) {\r
-      this.parent = parent;\r
-      cValue = val;\r
-                       tabIx = MDTable.Constant;\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      valIx = cValue.GetBlobIndex(md);\r
-      done = true;\r
-    }\r
-\r
-    internal void AddToBlob(BinaryWriter bw) {\r
-      cValue.Write(bw);\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(cValue.GetTypeIndex());\r
-      output.Write((byte)0);\r
-      output.WriteCodedIndex(CIx.HasConst,parent);\r
-      output.BlobIndex(valIx);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a Custom Attribute (.custom) \r
-       /// </summary>\r
-\r
-       public class CustomAttribute : MetaDataElement\r
-       {\r
-    private static readonly ushort prolog = 0x0001;\r
-    MetaDataElement parent;\r
-    Method type;\r
-    uint valIx;\r
-    Constant cVal;\r
-    byte[] byteVal;\r
-    ushort numNamed = 0;\r
-    ArrayList names, vals;\r
-\r
-               internal CustomAttribute(MetaDataElement paren, Method constrType, \r
-                                                          Constant val) {\r
-      parent = paren;\r
-      type = constrType;\r
-      cVal = val;\r
-      tabIx = MDTable.CustomAttribute;\r
-      throw(new NotYetImplementedException("Custom Attributes "));\r
-               }\r
-\r
-    internal CustomAttribute(MetaDataElement paren, Method constrType,\r
-                                                          byte[] val) {\r
-      parent = paren;\r
-      type = constrType;\r
-      tabIx = MDTable.CustomAttribute;\r
-      byteVal = val;\r
-    }\r
-\r
-    public void AddFieldOrProp(string name, Constant val) {\r
-      if (numNamed == 0) {\r
-        names = new ArrayList();\r
-        vals = new ArrayList();\r
-      }\r
-      names.Add(name);\r
-      vals.Add(val);\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      BinaryWriter bw = new BinaryWriter(new MemoryStream());\r
-      bw.Write((ushort)1);\r
-      md.AddToTable(MDTable.CustomAttribute, this);\r
-      MemoryStream str = (MemoryStream)bw.BaseStream;\r
-      valIx = md.AddToBlobHeap(str.ToArray());\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteCodedIndex(CIx.HasCustomAttr,parent);\r
-      output.WriteCodedIndex(CIx.CustomAttributeType,type);\r
-      output.BlobIndex(valIx);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a custom modifier of a type (modopt or modreq)\r
-       /// </summary>\r
-\r
-       public class CustomModifiedType : Type\r
-       {\r
-    Type type;\r
-    Class cmodType;\r
-\r
-    /// <summary>\r
-    /// Create a new custom modifier for a type\r
-    /// </summary>\r
-    /// <param name="type">the type to be modified</param>\r
-    /// <param name="cmod">the modifier</param>\r
-    /// <param name="cmodType">the type reference to be associated with the type</param>\r
-               public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)\r
-                                                          : base((byte)cmod) {\r
-      this.type = type;\r
-      this.cmodType = cmodType;\r
-               }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-      MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);\r
-      type.TypeSig(str);\r
-    }\r
-  \r
-  }\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// Descriptor for security permissions for a class or a method NOT YET IMPLEMENTED\r
-  /// </summary>\r
-       \r
-       public class DeclSecurity : MetaDataElement\r
-       {\r
-    ushort action;\r
-    MetaDataElement parent;\r
-    uint permissionIx;\r
-\r
-               internal DeclSecurity(MetaDataElement paren, ushort act)        {\r
-      parent = paren;\r
-      action = act;\r
-      tabIx = MDTable.DeclSecurity;\r
-      throw(new NotYetImplementedException("Security "));\r
-               }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-// add permission to blob heap\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(action);\r
-      output.WriteCodedIndex(CIx.HasDeclSecurity,parent);\r
-      output.BlobIndex(permissionIx);\r
-    }\r
\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for an event\r
-       /// </summary>\r
-  public class Event : Feature\r
-       {\r
-    Type eventType;\r
-\r
-    internal Event(string name, Type eType, ClassDef parent) \r
-                                            : base(name, parent) {\r
-      eventType = eType;\r
-                       tabIx = MDTable.Event;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the addon method to this event\r
-    /// </summary>\r
-    /// <param name="addon">the addon method</param>\r
-    public void AddAddon(MethodDef addon) {\r
-      AddMethod(addon,MethodType.AddOn);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the removeon method to this event\r
-    /// </summary>\r
-    /// <param name="removeOn">the removeon method</param>\r
-    public void AddRemoveOn(MethodDef removeOn) {\r
-      AddMethod(removeOn,MethodType.RemoveOn);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add the fire method to this event\r
-    /// </summary>\r
-    /// <param name="fire">the fire method</param>\r
-    public void AddFire(MethodDef fire) {\r
-      AddMethod(fire,MethodType.Fire);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add another method to this event\r
-    /// </summary>\r
-    /// <param name="other">the method to be added</param>\r
-    public void AddOther(MethodDef other) {\r
-      AddMethod(other,MethodType.Other);\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(name);\r
-      for (int i=0; i < tide; i++) {\r
-        md.AddToTable(MDTable.MethodSemantics,methods[i]);\r
-      }\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.StringsIndex(nameIx);\r
-      output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 10; \r
-        case (CIx.HasSemantics) : return 0; \r
-      }\r
-      return 0;\r
-    }\r
-   \r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a class defined in another module of THIS assembly \r
-       /// and exported (.class extern)\r
-       /// </summary>\r
-\r
-  internal class ExternClass : Class\r
-       {\r
-               MetaDataElement parent;\r
-    uint flags;\r
-\r
-    internal ExternClass(TypeAttr attr, uint nsIx, uint nIx, \r
-                         MetaDataElement paren) : base(nsIx,nIx) {\r
-      flags = (uint)attr;\r
-           parent = paren;\r
-                       tabIx = MDTable.ExportedType;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.Write(0);\r
-      output.StringsIndex(nameIx);\r
-      output.StringsIndex(nameSpaceIx);\r
-      output.WriteCodedIndex(CIx.Implementation,parent);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 17; \r
-        case (CIx.Implementation) : return 2; \r
-      }\r
-      return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for Event and Property descriptors\r
-       /// </summary>\r
-\r
-  public class Feature : MetaDataElement\r
-       {\r
-    internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08, \r
-      RemoveOn = 0x10, Fire = 0x20 }\r
-\r
-    private static readonly int INITSIZE = 5;\r
-    private static readonly ushort specialName = 0x200;\r
-    private static readonly ushort rtSpecialName = 0x400;\r
-\r
-    protected ClassDef parent;\r
-    protected ushort flags = 0;\r
-    protected string name;\r
-    protected int tide = 0;\r
-    protected uint nameIx;\r
-    protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];\r
-    \r
-    internal Feature(string name, ClassDef par) {\r
-      parent = par;\r
-      this.name = name;\r
-    }\r
-\r
-    internal void AddMethod(MethodDef meth, MethodType mType) {\r
-      if (tide >= methods.Length) { \r
-        int len = methods.Length;\r
-        MethodSemantics[] mTmp = methods;\r
-        methods = new MethodSemantics[len * 2];\r
-        for (int i=0; i < len; i++) {\r
-          methods[i] = mTmp[i];\r
-        }\r
-      }\r
-      methods[tide++] = new MethodSemantics(mType,meth,this);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the specialName attribute for this Event or Property\r
-    /// </summary>\r
-    public void SetSpecialName() {\r
-      flags |= specialName;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the RTSpecialName attribute for this Event or Property\r
-    /// </summary>\r
-    public void SetRTSpecialName() {\r
-      flags |= rtSpecialName;\r
-    }\r
-  \r
-       }\r
-  /*****************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a field of a class\r
-       /// </summary>\r
-\r
-  public abstract class Field : Member\r
-       {\r
-    protected static readonly byte FieldSig = 0x6;\r
-\r
-    protected Type type;\r
-\r
-               internal Field(string pfName, Type pfType) : base(pfName)\r
-               {\r
-      type = pfType;\r
-               }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a field defined in a class of THIS assembly/module\r
-       /// </summary>\r
-  public class FieldDef : Field\r
-       {\r
-    //private static readonly uint PInvokeImpl = 0x2000;\r
-    private static readonly ushort HasFieldMarshal = 0x1000;\r
-    private static readonly ushort HasFieldRVA = 0x100;\r
-\r
-    FieldRVA rva;\r
-    ConstantElem constVal;\r
-    FieldLayout layout;\r
-    FieldMarshal marshalInfo;\r
-    ushort flags;\r
-\r
-    internal FieldDef(string name, Type fType) : base(name,fType) {\r
-      tabIx = MDTable.Field;\r
-    }\r
-\r
-    internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType) { \r
-      flags = (ushort)attrSet;\r
-      tabIx = MDTable.Field;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an attribute(s) to this field\r
-    /// </summary>\r
-    /// <param name="fa">the attribute(s) to be added</param>\r
-    public void AddFieldAttr(FieldAttr fa) {\r
-      flags |= (ushort)fa;\r
-    }\r
\r
-    /// <summary>\r
-    /// Add a value for this field\r
-    /// </summary>\r
-    /// <param name="val">the value for the field</param>\r
-    public void AddValue(Constant val) {\r
-      constVal = new ConstantElem(this,val);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an initial value for this field (at dataLabel) (.data)\r
-    /// </summary>\r
-    /// <param name="val">the value for the field</param>\r
-    /// <param name="repeatVal">the number of repetitions of this value</param>\r
-    public void AddDataValue(DataConstant val) {\r
-      flags |= HasFieldRVA;\r
-      rva = new FieldRVA(this,val);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the offset of the field.  Used for sequential or explicit classes.\r
-    /// (.field [offs])\r
-    /// </summary>\r
-    /// <param name="offs">field offset</param>\r
-    public void SetOffset(uint offs) {\r
-      layout = new FieldLayout(this,offs);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the marshalling info for a field\r
-    /// </summary>\r
-    /// <param name="mInf"></param>\r
-    public void SetMarshalInfo(NativeType marshallType) {\r
-      flags |= HasFieldMarshal;\r
-      marshalInfo = new FieldMarshal(this,marshallType);\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(name);\r
-      MemoryStream sig = new MemoryStream();\r
-      sig.WriteByte(FieldSig);\r
-      type.TypeSig(sig);\r
-      sigIx = md.AddToBlobHeap(sig.ToArray());\r
-      if (rva != null) {\r
-        md.AddToTable(MDTable.FieldRVA,rva);\r
-        rva.BuildTables(md);\r
-      } else if (constVal != null) {\r
-        md.AddToTable(MDTable.Constant,constVal);\r
-        constVal.BuildTables(md);\r
-      }\r
-      if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);\r
-      if (marshalInfo != null) {\r
-        md.AddToTable(MDTable.FieldMarshal,marshalInfo);\r
-        marshalInfo.BuildTables(md);\r
-      }\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.StringsIndexSize() + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.StringsIndex(nameIx);\r
-      output.BlobIndex(sigIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasConst) : return 0; \r
-        case (CIx.HasCustomAttr) : return 1; \r
-        case (CIx.HasFieldMarshal) : return 0; \r
-        case (CIx.MemberForwarded) : return 0; \r
-      }\r
-      return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for layout information for a field\r
-       /// </summary>\r
-       \r
-       public class FieldLayout : MetaDataElement\r
-       {\r
-    Field field;\r
-    uint offset;\r
-\r
-    internal FieldLayout(Field field, uint offset)     {\r
-      this.field = field;\r
-      this.offset = offset;\r
-                       tabIx = MDTable.FieldLayout;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 4 + md.TableIndexSize(MDTable.Field);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(offset);\r
-      output.WriteIndex(MDTable.Field,field.Row);\r
-    }\r
-\r
-       }\r
-  /*****************************************************************************/  \r
-       /// <summary>\r
-       /// Marshalling information for a field or param\r
-       /// </summary>\r
-  public class FieldMarshal : MetaDataElement\r
-       {\r
-    MetaDataElement field;\r
-    NativeType nt;\r
-    uint ntIx;\r
-\r
-    internal FieldMarshal(MetaDataElement field, NativeType nType)     {\r
-      this.field = field;\r
-      this.nt = nType;\r
-                       tabIx = MDTable.FieldMarshal;\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      ntIx = md.AddToBlobHeap(nt.ToBlob());\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteCodedIndex(CIx.HasFieldMarshal,field);\r
-      output.BlobIndex(ntIx);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a field of a class defined in another assembly/module\r
-       /// </summary>\r
-  public class FieldRef : Field\r
-       {\r
-    MetaDataElement parent;\r
-\r
-               internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)   {       \r
-      parent = paren;\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(name);\r
-      MemoryStream sig = new MemoryStream();\r
-      sig.WriteByte(FieldSig);\r
-      type.TypeSig(sig);\r
-      sigIx = md.AddToBlobHeap(sig.ToArray());\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteCodedIndex(CIx.MemberRefParent,parent);\r
-      output.StringsIndex(nameIx);\r
-      output.BlobIndex(sigIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) { return 6; }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for the address of a field's value in the PE file\r
-       /// </summary>\r
-  public class FieldRVA : MetaDataElement\r
-       {\r
-    Field field;\r
-    DataConstant data;\r
-\r
-    internal FieldRVA(Field field, DataConstant data)  {\r
-      this.field = field;\r
-      this.data = data;\r
-      tabIx = MDTable.FieldRVA;\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      md.AddData(data);\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 4 + md.TableIndexSize(MDTable.Field);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteDataRVA(data.DataOffset);\r
-      output.WriteIndex(MDTable.Field,field.Row);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Image for a PEFile\r
-       /// File Structure\r
-  ///     DOS Header (128 bytes) \r
-  ///     PE Signature ("PE\0\0") \r
-  ///     PEFileHeader (20 bytes)\r
-  ///     PEOptionalHeader (224 bytes) \r
-  ///     SectionHeaders (40 bytes * NumSections)\r
-  ///\r
-  ///     Sections .text (always present - contains metadata)\r
-  ///              .sdata (contains any initialised data in the file - may not be present)\r
-  ///                     (for ilams /debug this contains the Debug table)\r
-  ///              .reloc (always present - in pure CIL only has one fixup)\r
-  ///               others???  c# produces .rsrc section containing a Resource Table\r
-  ///\r
-  /// .text layout\r
-  ///     IAT (single entry 8 bytes for pure CIL)\r
-  ///     CLIHeader (72 bytes)\r
-  ///     CIL instructions for all methods (variable size)\r
-  ///     MetaData \r
-  ///       Root (20 bytes + UTF-8 Version String + quad align padding)\r
-  ///       StreamHeaders (8 bytes + null terminated name string + quad align padding)\r
-  ///       Streams \r
-  ///         #~        (always present - holds metadata tables)\r
-  ///         #Strings  (always present - holds identifier strings)\r
-  ///         #US       (Userstring heap)\r
-  ///         #Blob     (signature blobs)\r
-  ///         #GUID     (guids for assemblies or Modules)\r
-  ///    ImportTable (40 bytes)\r
-  ///    ImportLookupTable(8 bytes) (same as IAT for standard CIL files)\r
-  ///    Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)\r
-  ///    ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)\r
-  ///    Entry Point  (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)\r
-  ///\r
-  ///  #~ stream structure\r
-  ///    Header (24 bytes)\r
-  ///    Rows   (4 bytes * numTables)\r
-  ///    Tables\r
-  /// </summary>\r
-       internal class FileImage : BinaryWriter\r
-       {\r
-    internal readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};\r
-    internal readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00,\r
-                                                  0x0000000000FF0000, 0x00000000FF000000,\r
-                                                  0x000000FF00000000, 0x0000FF0000000000,\r
-                                                  0x00FF000000000000, 0xFF00000000000000 };\r
-    internal readonly static uint nibble0Mask = 0x0000000F;\r
-    internal readonly static uint nibble1Mask = 0x000000F0;\r
-\r
-    private static readonly byte[] DOSHeader = { 0x4d,0x5a,0x90,0x00,0x03,0x00,0x00,0x00,\r
-                                                 0x04,0x00,0x00,0x00,0xff,0xff,0x00,0x00,\r
-                                                 0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
-                                                 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
-                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
-                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
-                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
-                                                 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,\r
-                                                 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,\r
-                                                 0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,\r
-                                                 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,\r
-                                                 0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,\r
-                                                 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,\r
-                                                 0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,\r
-                                                 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,\r
-                                                 0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
-                                                 0x50,0x45,0x00,0x00};\r
-    private static byte[] PEHeader = { 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
-                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
-                                       0xE0, 0x00, 0x0E, 0x01, // PE Header Standard Fields\r
-                                       0x0B, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, \r
-                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
-                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
-                                     };\r
-\r
-    private static readonly uint minFileAlign = 0x200;\r
-    private static readonly uint maxFileAlign = 0x1000;\r
-    private static readonly uint fileHeaderSize = 0x178;\r
-    private static readonly uint sectionHeaderSize = 40;\r
-    private static readonly uint SectionAlignment = 0x2000;\r
-    private static readonly uint ImageBase = 0x400000;\r
-    private static readonly uint ImportTableSize = 40;\r
-    private static readonly uint IATSize = 8;\r
-    private static readonly uint CLIHeaderSize = 72;\r
-    private uint runtimeFlags = 0x01;  // COMIMAGE_FLAGS_ILONLY\r
-    // 32BITREQUIRED 0x02, STRONGNAMESIGNED 0x08, TRACKDEBUGDATA 0x10000\r
-               private static readonly uint relocFlags = 0x42000040;\r
-               private static readonly ushort exeCharacteristics = 0x010E;\r
-               private static readonly ushort dllCharacteristics = 0x210E;\r
-    // section names are all 8 bytes\r
-    private static readonly string textName = ".text\0\0\0";\r
-    private static readonly string sdataName = ".sdata\0\0";\r
-    private static readonly string relocName = ".reloc\0\0";\r
-    private static readonly string rsrcName = ".rsrc\0\0\0";\r
-    private static readonly string exeHintNameTable = "\0\0_CorExeMain\0";\r
-    private static readonly string dllHintNameTable = "\0\0_CorDllMain\0";\r
-    private static readonly string runtimeEngineName = "mscoree.dll\0\0";\r
-\r
-               private Section text, sdata, rsrc;\r
-               ArrayList data;\r
-    BinaryWriter reloc = new BinaryWriter(new MemoryStream());\r
-    uint dateStamp = 0;\r
-    DateTime origin = new DateTime(1970,1,1);\r
-    uint numSections = 2; // always have .text  and .reloc sections\r
-    internal SubSystem subSys = SubSystem.Windows_CUI;  // default is Windows Console mode\r
-    internal uint fileAlign = minFileAlign;\r
-    uint entryPointOffset, entryPointPadding, imageSize, headerSize, headerPadding, entryPointToken = 0;\r
-    uint relocOffset, relocRVA, relocSize, relocPadding, relocTide, hintNameTableOffset;\r
-    uint metaDataOffset, runtimeEngineOffset, initDataSize = 0, importTablePadding;\r
-    uint importTableOffset, importLookupTableOffset, totalImportTableSize;\r
-    MetaData metaData;\r
-    char[] runtimeEngine = runtimeEngineName.ToCharArray(), hintNameTable;\r
-               bool doDLL, largeStrings, largeGUID, largeUS, largeBlob;\r
-               ushort characteristics;\r
-\r
-    internal FileImage(bool makeDLL, string fileName) : base(new FileStream(fileName,FileMode.Create)) {\r
-      InitFileImage(makeDLL);\r
-      TimeSpan tmp = System.IO.File.GetCreationTime(fileName).Subtract(origin);\r
-      dateStamp = Convert.ToUInt32(tmp.TotalSeconds);\r
-    }\r
-\r
-    internal FileImage(bool makeDLL, Stream str) : base(str) {\r
-      InitFileImage(makeDLL);\r
-      TimeSpan tmp = DateTime.Now.Subtract(origin);\r
-      dateStamp = Convert.ToUInt32(tmp.TotalSeconds);\r
-    }\r
-\r
-    private void InitFileImage(bool makeDLL) {\r
-      doDLL = makeDLL;\r
-                       if (doDLL) {\r
-                               hintNameTable = dllHintNameTable.ToCharArray();\r
-                               characteristics = dllCharacteristics;\r
-                       } else {\r
-                               hintNameTable = exeHintNameTable.ToCharArray();\r
-                               characteristics = exeCharacteristics;\r
-                       }\r
-      text = new Section(textName,0x60000020);     // IMAGE_SCN_CNT  CODE, EXECUTE, READ\r
-//                     rsrc = new Section(rsrcName,0x40000040);     // IMAGE_SCN_CNT  INITIALIZED_DATA, READ\r
-      metaData = new MetaData(this);\r
-    }\r
-\r
-               internal MetaData GetMetaData() {\r
-                       return metaData;\r
-               }\r
-\r
-    private uint GetNextSectStart(uint rva, uint tide) {\r
-      if (tide < SectionAlignment) return rva + SectionAlignment;\r
-      return rva + ((tide / SectionAlignment) + 1) * SectionAlignment;\r
-    }\r
-\r
-    private void BuildTextSection() {\r
-      // .text layout\r
-      //    IAT (single entry 8 bytes for pure CIL)\r
-      //    CLIHeader (72 bytes)\r
-      //    CIL instructions for all methods (variable size)\r
-      //    MetaData \r
-      //    ImportTable (40 bytes)\r
-      //    ImportLookupTable(8 bytes) (same as IAT for standard CIL files)\r
-      //    Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)\r
-      //    ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)\r
-      //    Entry Point  (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)\r
-      metaData.BuildMetaData(IATSize + CLIHeaderSize);\r
-      metaDataOffset = IATSize + CLIHeaderSize;\r
-      // Console.WriteLine("Code starts at " + metaDataOffset);\r
-      metaDataOffset += metaData.CodeSize();\r
-      // resourcesStart =\r
-      // strongNameSig = metaData.GetStrongNameSig();\r
-      // fixUps = RVA for vtable\r
-      importTableOffset = metaDataOffset + metaData.Size();\r
-      importTablePadding = NumToAlign(importTableOffset,16);\r
-      importTableOffset += importTablePadding;\r
-      importLookupTableOffset = importTableOffset + ImportTableSize;\r
-      hintNameTableOffset = importLookupTableOffset + IATSize;\r
-      runtimeEngineOffset = hintNameTableOffset + (uint)hintNameTable.Length;\r
-      entryPointOffset = runtimeEngineOffset + (uint)runtimeEngine.Length;\r
-      totalImportTableSize = entryPointOffset - importTableOffset;\r
-      // Console.WriteLine("total import table size = " + totalImportTableSize);\r
-      // Console.WriteLine("entrypoint offset = " + entryPointOffset);\r
-      entryPointPadding = NumToAlign(entryPointOffset,4) + 2;\r
-      entryPointOffset += entryPointPadding;\r
-      text.AddReloc(entryPointOffset+2);\r
-      text.IncTide(entryPointOffset + 6);\r
-      //if (text.Tide() < fileAlign) fileAlign = minFileAlign;\r
-                       text.SetSize(NumToAlign(text.Tide(),fileAlign));\r
-      // Console.WriteLine("text size = " + text.Size() + " text tide = " + text.Tide() + " text padding = " + text.Padding());\r
-                       // Console.WriteLine("metaDataOffset = " + Hex.Int(metaDataOffset));\r
-                       // Console.WriteLine("importTableOffset = " + Hex.Int(importTableOffset));\r
-                       // Console.WriteLine("importLookupTableOffset = " + Hex.Int(importLookupTableOffset));\r
-                       // Console.WriteLine("hintNameTableOffset = " + Hex.Int(hintNameTableOffset));\r
-                       // Console.WriteLine("runtimeEngineOffset = " + Hex.Int(runtimeEngineOffset));\r
-                       // Console.WriteLine("entryPointOffset = " + Hex.Int(entryPointOffset));\r
-                       // Console.WriteLine("entryPointPadding = " + Hex.Int(entryPointPadding));\r
-\r
-    }\r
-\r
-    internal void BuildRelocSection() {\r
-                       text.DoRelocs(reloc);\r
-                       if (sdata != null) sdata.DoRelocs(reloc);\r
-                       if (rsrc != null) rsrc.DoRelocs(reloc);\r
-      relocTide = (uint)reloc.Seek(0,SeekOrigin.Current);\r
-      relocPadding = NumToAlign(relocTide,fileAlign);\r
-      relocSize = relocTide + relocPadding;\r
-                       imageSize = relocRVA + SectionAlignment;\r
-      initDataSize += relocSize;\r
-    }\r
-\r
-    private void CalcOffsets() {\r
-      headerSize = fileHeaderSize + (numSections * sectionHeaderSize);\r
-      headerPadding = NumToAlign(headerSize,fileAlign);\r
-      headerSize += headerPadding;\r
-      uint offset = headerSize;\r
-      uint rva = SectionAlignment;\r
-      text.SetOffset(offset);\r
-      text.SetRVA(rva);\r
-      offset += text.Size();\r
-      rva  = GetNextSectStart(rva,text.Tide());\r
-                       // Console.WriteLine("headerSize = " + headerSize);\r
-                       // Console.WriteLine("headerPadding = " + headerPadding);\r
-                       // Console.WriteLine("textOffset = " + Hex.Int(text.Offset()));\r
-                       if (sdata != null) { \r
-                               numSections++;\r
-                               sdata.SetSize(NumToAlign(sdata.Tide(),fileAlign));\r
-                               sdata.SetOffset(offset);\r
-        sdata.SetRVA(rva);\r
-        offset += sdata.Size();\r
-        rva = GetNextSectStart(rva,sdata.Tide());\r
-                               initDataSize += sdata.Size();\r
-      }\r
-      if (rsrc != null) { \r
-                               numSections++;\r
-                               rsrc.SetSize(NumToAlign(rsrc.Tide(),fileAlign));\r
-                               rsrc.SetOffset(offset);\r
-        rsrc.SetRVA(rva);\r
-        offset += rsrc.Size();\r
-        rva = GetNextSectStart(rva,rsrc.Tide());\r
-                               initDataSize += rsrc.Size();\r
-      }\r
-      relocOffset = offset;\r
-      relocRVA = rva;\r
-    }\r
-\r
-    internal void MakeFile() {\r
-      if (doDLL) hintNameTable = dllHintNameTable.ToCharArray();\r
-      else hintNameTable = exeHintNameTable.ToCharArray();\r
-      BuildTextSection();\r
-      CalcOffsets();\r
-      BuildRelocSection();\r
-      // now write it out\r
-      WriteHeader();\r
-      WriteSections();\r
-      Flush();\r
-      Close();\r
-    }\r
-\r
-    private void WriteHeader() {\r
-      Write(DOSHeader);\r
-                       // Console.WriteLine("Writing PEHeader at offset " + Seek(0,SeekOrigin.Current));\r
-                       WritePEHeader();\r
-                        // Console.WriteLine("Writing text section header at offset " + Hex.Long(Seek(0,SeekOrigin.Current)));\r
-                       text.WriteHeader(this,relocRVA);\r
-      if (sdata != null) sdata.WriteHeader(this,relocRVA);\r
-      if (rsrc != null) rsrc.WriteHeader(this,relocRVA);\r
-                       // Console.WriteLine("Writing reloc section header at offset " + Seek(0,SeekOrigin.Current));\r
-                       WriteRelocSectionHeader();\r
-                       // Console.WriteLine("Writing padding at offset " + Seek(0,SeekOrigin.Current));\r
-                       WriteZeros(headerPadding);\r
-    }\r
-\r
-    private void WriteSections() {\r
-                       // Console.WriteLine("Writing text section at offset " + Seek(0,SeekOrigin.Current));\r
-      WriteTextSection();\r
-      if (sdata != null) WriteSDataSection();\r
-      if (rsrc != null) WriteRsrcSection();\r
-      WriteRelocSection();\r
-    }\r
-\r
-     private void WriteIAT() {\r
-      Write(text.RVA() + hintNameTableOffset);\r
-      Write(0);\r
-    }\r
-\r
-               private void WriteImportTables() {\r
-                       // Import Table\r
-      WriteZeros(importTablePadding);\r
-      // Console.WriteLine("Writing import tables at offset " + Hex.Long(Seek(0,SeekOrigin.Current)));\r
-                       Write(importLookupTableOffset + text.RVA());\r
-                       WriteZeros(8); \r
-                       Write(runtimeEngineOffset + text.RVA());\r
-                       Write(text.RVA());    // IAT is at the beginning of the text section\r
-                       WriteZeros(20);\r
-                       // Import Lookup Table\r
-                       WriteIAT();                // lookup table and IAT are the same\r
-                       // Hint/Name Table\r
-       // Console.WriteLine("Writing hintname table at " + Hex.Long(Seek(0,SeekOrigin.Current)));\r
-                       Write(hintNameTable);\r
-      Write(runtimeEngineName.ToCharArray());\r
-               }\r
-\r
-    private void WriteTextSection() {\r
-      WriteIAT();\r
-      WriteCLIHeader();\r
-      // Console.WriteLine("Writing code at " + Hex.Long(Seek(0,SeekOrigin.Current)));\r
-      metaData.WriteByteCodes(this);\r
-      // Console.WriteLine("Finished writing code at " + Hex.Long(Seek(0,SeekOrigin.Current)));\r
-      largeStrings = metaData.LargeStringsIndex();\r
-      largeGUID = metaData.LargeGUIDIndex();\r
-      largeUS = metaData.LargeUSIndex();\r
-      largeBlob = metaData.LargeBlobIndex();\r
-      metaData.WriteMetaData(this);\r
-      WriteImportTables();\r
-                       WriteZeros(entryPointPadding);\r
-                       Write((ushort)0x25FF);\r
-                       Write(ImageBase + text.RVA());\r
-                       WriteZeros(text.Padding());\r
-    }\r
-\r
-    private void WriteCLIHeader() {\r
-      Write(CLIHeaderSize);       // Cb\r
-      Write((short)2);            // Major runtime version\r
-      Write((short)0);            // Minor runtime version\r
-      Write(text.RVA() + metaDataOffset);\r
-      Write(metaData.Size());\r
-      Write(runtimeFlags);\r
-      Write(entryPointToken);\r
-      WriteZeros(8);                     // Resources - used by Manifest Resources NYI\r
-      WriteZeros(8);                     // Strong Name stuff here!! NYI\r
-      WriteZeros(8);                     // CodeManagerTable\r
-      WriteZeros(8);                     // VTableFixups NYI\r
-      WriteZeros(16);                    // ExportAddressTableJumps, ManagedNativeHeader\r
-     }\r
-\r
-    private void WriteSDataSection() {\r
-      for (int i=0; i < data.Count; i++) {\r
-        ((DataConstant)data[i]).Write(this);\r
-      }\r
-    }\r
-\r
-               private void WriteRsrcSection() {\r
-               }\r
-\r
-    private void WriteRelocSection() {\r
-     // Console.WriteLine("Writing reloc section at " + Seek(0,SeekOrigin.Current) + " = " + relocOffset);\r
-      MemoryStream str = (MemoryStream)reloc.BaseStream;\r
-      Write(str.ToArray());\r
-      WriteZeros(NumToAlign((uint)str.Position,fileAlign));\r
-    }\r
-\r
-    internal void SetEntryPoint(uint entryPoint) {\r
-      entryPointToken = entryPoint;\r
-    }\r
-\r
-    internal void AddInitData(DataConstant cVal) {\r
-                       if (sdata == null) {                    \r
-                               sdata = new Section(sdataName,0xC0000040);   // IMAGE_SCN_CNT  INITIALIZED_DATA, READ, WRITE\r
-                               data = new ArrayList(); \r
-                       }\r
-      data.Add(cVal);\r
-      cVal.DataOffset = sdata.Tide();\r
-      sdata.IncTide(cVal.GetSize());\r
-    }\r
-\r
-    internal void WriteZeros(uint numZeros) {\r
-      for (int i=0; i < numZeros; i++) {\r
-        Write((byte)0);\r
-      }\r
-    }\r
-\r
-    internal void WritePEHeader() {\r
-      Write((ushort)0x014C);  // Machine - always 0x14C for Managed PE Files (allow others??)\r
-      Write((ushort)numSections);\r
-      Write(dateStamp);\r
-      WriteZeros(8); // Pointer to Symbol Table and Number of Symbols (always zero for ECMA CLI files)\r
-      Write((ushort)0x00E0);  // Size of Optional Header\r
-      Write(characteristics);\r
-      // PE Optional Header\r
-      Write((ushort)0x010B);   // Magic\r
-      Write((byte)0x6);        // LMajor pure-IL = 6   C++ = 7\r
-      Write((byte)0x0);        // LMinor\r
-      Write(text.Size());\r
-      Write(initDataSize);\r
-      Write(0);                // Check other sections here!!\r
-      Write(text.RVA() + entryPointOffset);\r
-      Write(text.RVA());\r
-                       uint dataBase = 0;\r
-                       if (sdata != null) dataBase = sdata.RVA();\r
-                       else if (rsrc != null) dataBase = rsrc.RVA();\r
-      else dataBase = relocRVA;\r
-                       Write(dataBase);\r
-      Write(ImageBase);\r
-      Write(SectionAlignment);\r
-      Write(fileAlign);\r
-      Write((ushort)0x04);     // OS Major\r
-      WriteZeros(6);                  // OS Minor, User Major, User Minor\r
-      Write((ushort)0x04);     // SubSys Major\r
-      WriteZeros(6);           // SybSys Minor, Reserved\r
-      Write(imageSize);\r
-      Write(headerSize);\r
-      Write((int)0);           // File Checksum\r
-      Write((ushort)subSys);\r
-      Write((short)0);         // DLL Flags\r
-      Write((uint)0x100000);   // Stack Reserve Size\r
-      Write((uint)0x1000);     // Stack Commit Size\r
-      Write((uint)0x100000);   // Heap Reserve Size\r
-      Write((uint)0x1000);     // Heap Commit Size\r
-      Write(0);                // Loader Flags\r
-      Write(0x10);             // Number of Data Directories\r
-      WriteZeros(8);                  // Export Table\r
-      Write(importTableOffset + text.RVA());\r
-      Write(totalImportTableSize);\r
-      WriteZeros(24);            // Resource, Exception and Certificate Tables\r
-      Write(relocRVA);\r
-      Write(relocTide);\r
-      WriteZeros(48);            // Debug, Copyright, Global Ptr, TLS, Load Config and Bound Import Tables\r
-      Write(text.RVA());         // IATRVA - IAT is at start of .text Section\r
-      Write(IATSize);\r
-      WriteZeros(8);             // Delay Import Descriptor\r
-      Write(text.RVA()+IATSize); // CLIHeader immediately follows IAT\r
-      Write(CLIHeaderSize);    \r
-      WriteZeros(8);             // Reserved\r
-    }\r
-\r
-    internal void WriteRelocSectionHeader() {\r
-      Write(relocName.ToCharArray());\r
-      Write(relocTide);\r
-      Write(relocRVA);\r
-      Write(relocSize);\r
-      Write(relocOffset);\r
-      WriteZeros(12);\r
-      Write(relocFlags);\r
-    }\r
-\r
-    private void Align (MemoryStream str, int val) {\r
-      if ((str.Position % val) != 0) {\r
-        for (int i=val - (int)(str.Position % val); i > 0; i--) {\r
-          str.WriteByte(0);\r
-        }\r
-      }\r
-    }\r
-\r
-    private uint Align(uint val, uint alignVal) {\r
-      if ((val % alignVal) != 0) {\r
-        val += alignVal - (val % alignVal);\r
-      }\r
-      return val;\r
-    }\r
-\r
-    private uint NumToAlign(uint val, uint alignVal) {\r
-      if ((val % alignVal) == 0) return 0;\r
-      return alignVal - (val % alignVal);\r
-    }\r
-\r
-    internal void StringsIndex(uint ix) {\r
-      if (largeStrings) Write(ix);\r
-      else Write((ushort)ix);\r
-    }\r
-\r
-    internal void GUIDIndex(uint ix) {\r
-      if (largeGUID) Write(ix);\r
-      else Write((ushort)ix);\r
-    }\r
-\r
-    internal void USIndex(uint ix) {\r
-      if (largeUS) Write(ix);\r
-      else Write((ushort)ix);\r
-    }\r
-\r
-    internal void BlobIndex(uint ix) {\r
-      if (largeBlob) Write(ix);\r
-      else Write((ushort)ix);\r
-    }\r
-\r
-    internal void WriteIndex(MDTable tabIx,uint ix) {\r
-      if (metaData.LargeIx(tabIx)) Write(ix);\r
-      else Write((ushort)ix);\r
-    }\r
-\r
-    internal void WriteCodedIndex(CIx code, MetaDataElement elem) {\r
-      metaData.WriteCodedIndex(code,elem,this);\r
-    }\r
-    \r
-    internal void WriteCodeRVA(uint offs) {\r
-      Write(text.RVA() + offs);\r
-    }\r
-\r
-    internal void WriteDataRVA(uint offs) {\r
-      Write(sdata.RVA() + offs);\r
-    }\r
-\r
-    internal void Write3Bytes(uint val) {\r
-      byte b3 = (byte)((val & FileImage.iByteMask[2]) >> 16);\r
-      byte b2 = (byte)((val & FileImage.iByteMask[1]) >> 8);;\r
-      byte b1 = (byte)(val & FileImage.iByteMask[0]);\r
-      Write(b1);\r
-      Write(b2);\r
-      Write(b3);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a file referenced in THIS assembly/module (.file)\r
-       /// </summary>\r
-       public class FileRef : MetaDataElement\r
-       {\r
-    private static readonly uint HasMetaData = 0x1;\r
-    uint nameIx = 0, hashIx = 0;\r
-    uint flags = 0;\r
-\r
-    internal FileRef(string name, byte[] hashBytes, bool metaData,\r
-                      bool entryPoint, MetaData md) {\r
-      if (metaData) flags = HasMetaData;\r
-      if (entryPoint) md.SetEntryPoint(this);\r
-      nameIx = md.AddToStringsHeap(name);\r
-      hashIx = md.AddToBlobHeap(hashBytes);\r
-      tabIx = MDTable.File;\r
-               }\r
-\r
-    internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,\r
-                      bool entryPoint, MetaData md) {\r
-      if (metaData) flags = HasMetaData;\r
-      if (entryPoint) md.SetEntryPoint(this);\r
-      this.nameIx = nameIx;\r
-      hashIx = md.AddToBlobHeap(hashBytes);\r
-      tabIx = MDTable.File;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 4 + md.StringsIndexSize() + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.StringsIndex(nameIx);\r
-      output.BlobIndex(hashIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 16; \r
-        case (CIx.Implementation) : return 0;\r
-      }\r
-      return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED\r
-       /// </summary>\r
-       public class ImplMap : MetaDataElement\r
-       {\r
-    private static readonly ushort NoMangle = 0x01;\r
-    ushort flags;\r
-    Method meth;\r
-    string importName;\r
-    uint iNameIx;\r
-    ModuleRef importScope;\r
-\r
-               internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope) {\r
-      flags = flag;\r
-      meth = implMeth;\r
-      importName = iName;\r
-      importScope = mScope;\r
-      tabIx = MDTable.ImplMap;\r
-      if (iName == null) flags |= NoMangle;\r
-      //throw(new NotYetImplementedException("PInvoke "));\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      iNameIx = md.AddToStringsHeap(importName);\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2+ md.CodedIndexSize(CIx.MemberForwarded) + \r
-        md.StringsIndexSize() +  md.TableIndexSize(MDTable.ModuleRef);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.WriteCodedIndex(CIx.MemberForwarded,meth);\r
-      output.StringsIndex(iNameIx);\r
-      output.WriteIndex(MDTable.ModuleRef,importScope.Row);\r
-    }\r
-\r
-       }\r
-\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// Descriptor for an IL instruction\r
-  /// </summary>\r
-  internal abstract class CILInstruction {\r
-    protected static readonly sbyte maxByteVal = 127;\r
-    protected static readonly sbyte minByteVal = -128;\r
-    protected static readonly byte leadByte = 0xFE;\r
-               protected static readonly uint USHeapIndex = 0x70000000;\r
-    protected static readonly int longInstrStart = (int)Op.arglist;\r
-    public bool twoByteInstr = false;\r
-    public uint size = 0;\r
-    public uint offset;\r
-\r
-    internal virtual bool Check(MetaData md) {\r
-      return false;\r
-    }\r
-\r
-               internal virtual void Write(FileImage output) { }\r
-\r
-  }\r
-\r
-  internal class CILByte : CILInstruction {\r
-    byte byteVal;\r
-\r
-    internal CILByte(byte bVal) {\r
-      byteVal = bVal;\r
-      size = 1;\r
-    }\r
-\r
-    internal override void Write(FileImage output) {\r
-      output.Write(byteVal);\r
-    }\r
-\r
-  }\r
-\r
-  \r
-  internal class Instr : CILInstruction {\r
-    protected int instr;\r
-\r
-    internal Instr(int inst) {\r
-      if (inst >= longInstrStart) {\r
-        instr = inst - longInstrStart;\r
-        twoByteInstr = true;\r
-        size = 2;\r
-      } else {\r
-        instr = inst;\r
-        size = 1;\r
-      }\r
-    }\r
-\r
-               internal override void Write(FileImage output) {\r
-      //Console.WriteLine("Writing instruction " + instr + " with size " + size);\r
-      if (twoByteInstr) output.Write(leadByte);\r
-      output.Write((byte)instr);\r
-               }\r
-\r
-  }\r
-\r
-  internal class IntInstr : Instr {\r
-    int val;\r
-    bool byteNum;\r
-\r
-    internal IntInstr(int inst, int num, bool byteSize) : base(inst) {\r
-      val = num;\r
-      byteNum = byteSize;\r
-      if (byteNum) size++;\r
-      else size += 4;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-      if (byteNum) \r
-        output.Write((sbyte)val);\r
-      else \r
-                               output.Write(val); \r
-               }\r
-\r
-  }\r
-\r
-  internal class UIntInstr : Instr {\r
-    int val;\r
-    bool byteNum;\r
-\r
-               internal UIntInstr(int inst, int num, bool byteSize) : base(inst) {\r
-                       val = num;\r
-      byteNum = byteSize;\r
-      if (byteNum) size++;\r
-      else size += 2;\r
-               }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-      if (byteNum)\r
-                         output.Write((byte)val);\r
-      else\r
-                               output.Write((ushort)val); \r
-               }\r
-       \r
-  }\r
-\r
-       internal class LongInstr : Instr {\r
-               long val;\r
-\r
-               internal LongInstr(int inst, long l) : base(inst) {\r
-                       val = l;\r
-                       size += 8;\r
-               }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(val);\r
-               }\r
-\r
-       }\r
-\r
-  internal class FloatInstr : Instr {\r
-    float fVal;\r
-\r
-    internal FloatInstr(int inst, float f) : base(inst) {\r
-      fVal = f;\r
-      size += 4;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(fVal);\r
-               }\r
-\r
-       }\r
-\r
-  internal class DoubleInstr : Instr {\r
-    double val;\r
-\r
-    internal DoubleInstr(int inst, double d) : base(inst) {\r
-      val = d;\r
-      size += 8;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(val);\r
-               }\r
-\r
-       }\r
-\r
-  internal class StringInstr : Instr {\r
-    string val;\r
-    uint strIndex;\r
-\r
-    internal StringInstr(int inst, string str) : base(inst) {\r
-      val = str;  \r
-      size += 4;\r
-    }\r
-\r
-    internal sealed override bool Check(MetaData md) {\r
-      strIndex = md.AddToUSHeap(val);\r
-      return false;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(USHeapIndex  | strIndex);\r
-               }\r
-\r
-       }\r
-\r
-  internal class LabelInstr : CILInstruction {\r
-    CILLabel label;\r
-\r
-    internal LabelInstr(CILLabel lab) {\r
-      label = lab;\r
-      label.AddLabelInstr(this);\r
-    }\r
-  }\r
-\r
-  internal class FieldInstr : Instr {\r
-    Field field;\r
-\r
-    internal FieldInstr(int inst, Field f) : base(inst) {\r
-      field = f;\r
-      size += 4;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(field.Token());\r
-               }\r
-\r
-       }\r
-\r
-  internal class MethInstr : Instr {\r
-    Method meth;\r
-\r
-    internal MethInstr(int inst, Method m) : base(inst) {\r
-      meth = m;\r
-      size += 4;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(meth.Token());\r
-               }\r
-\r
-  }\r
-\r
-  internal class SigInstr : Instr {\r
-    CalliSig signature;\r
-\r
-    internal SigInstr(int inst, CalliSig sig) : base(inst) {\r
-      signature = sig;\r
-      size += 4;\r
-    }\r
-\r
-    internal sealed override bool Check(MetaData md) {\r
-      md.AddToTable(MDTable.StandAloneSig,signature);\r
-      signature.BuildTables(md);\r
-      return false;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(signature.Token());\r
-               }\r
-  }\r
-\r
-  internal class TypeInstr : Instr {\r
-    MetaDataElement theType;\r
-\r
-    internal TypeInstr(int inst, Type aType, MetaData md) : base(inst) {\r
-      theType = aType.GetTypeSpec(md);\r
-      size += 4;\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      base.Write(output);\r
-      output.Write(theType.Token());\r
-               }\r
-\r
-  }\r
-\r
-  internal class BranchInstr : Instr {\r
-    CILLabel dest;\r
-    private bool shortVer = true;\r
-    private static readonly byte longInstrOffset = 13;\r
-    private int target = 0;\r
-\r
-    internal BranchInstr(int inst, CILLabel dst) : base(inst) {\r
-      dest = dst;\r
-      dest.AddBranch(this);\r
-      size++;\r
-    }\r
-\r
-    internal sealed override bool Check(MetaData md) {\r
-      target = (int)dest.GetLabelOffset() - (int)(offset + size);\r
-      if (shortVer && ((target < minByteVal) || (target > maxByteVal))) {\r
-        if (instr < (int)BranchOp.leave) instr += longInstrOffset;\r
-        else instr--;\r
-        shortVer = false;\r
-        size += 3;\r
-        return true;\r
-      }\r
-      return false;\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       if (shortVer)\r
-                               output.Write((sbyte)target);\r
-                       else\r
-                               output.Write(target);\r
-               }\r
-\r
-  }\r
-\r
-  internal class SwitchInstr : Instr {\r
-    CILLabel[] cases;\r
-               uint numCases = 0;\r
-\r
-    internal SwitchInstr(int inst, CILLabel[] dsts) : base(inst) {\r
-      cases = dsts;\r
-                       if (cases != null) numCases = (uint)cases.Length;\r
-      size += 4 + (numCases * 4);\r
-      for (int i=0; i < numCases; i++) {\r
-        cases[i].AddBranch(this);\r
-      }\r
-    }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       base.Write(output);\r
-                       output.Write(numCases);\r
-                       for (int i=0; i < numCases; i++) {\r
-                               int target = (int)cases[i].GetLabelOffset() - (int)(offset + size);\r
-                               output.Write(target);\r
-                       }\r
-               }\r
-\r
-  }\r
-  /**************************************************************************/  \r
-\r
-        internal class GenericParameter : MetaDataElement\r
-        {\r
-                ClassDef owner; /* FIXME: can also be a MethodDef */\r
-                string name;\r
-                uint nameIx;\r
-                short index;\r
-\r
-                public GenericParameter (ClassDef owner, short index) {\r
-                       this.owner = owner;\r
-                        this.index = index;\r
-                        tabIx = MDTable.GenericParam;\r
-                }\r
-\r
-                public GenericParameter (ClassDef owner, short index,\r
-                        string name) : this (owner, index) {\r
-                        this.name = name;\r
-                }\r
-\r
-                internal sealed override uint Size(MetaData md) {\r
-                        return (uint) (4 +\r
-                               md.CodedIndexSize(CIx.TypeOrMethodDef) + \r
-                               4 +\r
-                               md.TableIndexSize(MDTable.TypeDef));\r
-                }\r
-\r
-                internal sealed override void BuildTables(MetaData md) {\r
-                        if (done) return;\r
-                       if (name == null)\r
-                               nameIx = 0;\r
-                       else\r
-                               nameIx = md.AddToStringsHeap(name);\r
-                        done = true;\r
-                }\r
-\r
-                internal sealed override void Write(FileImage output) {\r
-                        output.Write ((short) index);\r
-                        output.Write ((short) 0);\r
-                        output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);\r
-                        output.Write ((uint) nameIx);\r
-                        output.WriteIndex(MDTable.TypeDef,owner.Row);\r
-                }\r
-\r
-    \r
-        }\r
-\r
-        internal class GenericParamConstraint : MetaDataElement\r
-        {\r
-                GenericParameter param;\r
-                Type type;\r
-\r
-                public GenericParamConstraint (GenericParameter param, Type type) {\r
-                        this.param = param;\r
-                        this.type = type;\r
-                        tabIx = MDTable.GenericParamConstraint;\r
-                }\r
-\r
-                internal sealed override uint Size(MetaData md) {\r
-                        return (uint) (md.TableIndexSize(MDTable.GenericParam) +\r
-                                       md.CodedIndexSize(CIx.TypeDefOrRef));\r
-                }\r
-\r
-                internal sealed override void Write(FileImage output) {\r
-                        output.WriteIndex(MDTable.GenericParam, param.Row);\r
-                        output.WriteCodedIndex(CIx.TypeDefOrRef, type);\r
-                }\r
-\r
-\r
-        }\r
-  /**************************************************************************/\r
-       /// <summary>\r
-       /// Descriptor for interface implemented by a class\r
-       /// </summary>\r
-       public class InterfaceImpl: MetaDataElement\r
-       { \r
-    ClassDef theClass;\r
-    Class theInterface;\r
-\r
-               internal InterfaceImpl(ClassDef theClass, Class theInterface) {\r
-      this.theClass = theClass;\r
-      this.theInterface = theInterface;\r
-                       tabIx = MDTable.InterfaceImpl;\r
-               }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.TableIndexSize(MDTable.TypeDef) + \r
-             md.CodedIndexSize(CIx.TypeDefOrRef);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteIndex(MDTable.TypeDef,theClass.Row);\r
-      output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) { return 5; }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a local of a method\r
-       /// </summary>\r
-  public class Local\r
-       {\r
-    private static readonly byte Pinned = 0x45;\r
-    string name;\r
-    Type type;\r
-    bool pinned = false, byref = false;\r
-\r
-    /// <summary>\r
-    /// Create a new local variable \r
-    /// </summary>\r
-    /// <param name="lName">name of the local variable</param>\r
-    /// <param name="lType">type of the local variable</param>\r
-    public Local(string lName, Type lType) {\r
-      name = lName;\r
-      type = lType;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new local variable that is byref and/or pinned\r
-    /// </summary>\r
-    /// <param name="lName">local name</param>\r
-    /// <param name="lType">local type</param>\r
-    /// <param name="byRef">is byref</param>\r
-    /// <param name="isPinned">has pinned attribute</param>\r
-               public Local(string lName, Type lType, bool byRef, bool isPinned)\r
-               {\r
-      name = lName;\r
-      type = lType;\r
-      byref = byRef;\r
-      pinned = isPinned;\r
-               }\r
-\r
-    internal void TypeSig(MemoryStream str) {\r
-      if (pinned) str.WriteByte(Pinned);\r
-      type.TypeSig(str);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for the locals for a method\r
-       /// </summary>\r
-\r
-  public class LocalSig : Signature\r
-       {\r
-               private static readonly byte LocalSigByte = 0x7;\r
-    Local[] locals;\r
-\r
-               public LocalSig(Local[] locals)         {\r
-      this.locals = locals;\r
-      tabIx = MDTable.StandAloneSig;\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      MemoryStream sig = new MemoryStream();\r
-      sig.WriteByte(LocalSigByte);\r
-      MetaData.CompressNum((uint)locals.Length,sig);\r
-      for (int i=0; i < locals.Length; i++) {\r
-        ((Local)locals[i]).TypeSig(sig);\r
-      }\r
-      sigIx = md.AddToBlobHeap(sig.ToArray());\r
-      done = true;\r
-    }\r
-\r
-  }\r
-\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for resources used in this PE file NOT YET IMPLEMENTED\r
-       /// </summary>\r
-\r
-  public class ManifestResource : MetaDataElement\r
-       {\r
-    private static readonly uint PublicResource = 0x1;\r
-    private static readonly uint PrivateResource = 0x2;\r
-\r
-    string mrName;\r
-    MetaDataElement rRef;\r
-    int fileOffset;\r
-    uint nameIx = 0;\r
-    uint flags = 0;\r
-\r
-    public ManifestResource(string name, bool isPub, FileRef fileRef) {\r
-      mrName = name;\r
-      if (isPub) flags = PublicResource;\r
-      else flags = PrivateResource;\r
-      rRef = fileRef;\r
-      tabIx = MDTable.ManifestResource;\r
-      throw(new NotYetImplementedException("Manifest Resources "));\r
-    }\r
-\r
-    public ManifestResource(string name, bool isPub, FileRef fileRef, \r
-                                                            int fileIx) {\r
-      mrName = name;\r
-      if (isPub) flags = PublicResource;\r
-      else flags = PrivateResource;\r
-      rRef = fileRef;\r
-      fileOffset = fileIx;\r
-    }\r
-\r
-    public ManifestResource(string name, bool isPub, AssemblyRef assemRef) {\r
-      mrName = name;\r
-      if (isPub) flags = PublicResource;\r
-      else flags = PrivateResource;\r
-      rRef = assemRef;\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(mrName);\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 8 + md.StringsIndexSize() + \r
-                 md.CodedIndexSize(CIx.Implementation);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(fileOffset);\r
-      output.Write(flags);\r
-      output.StringsIndex(nameIx);\r
-      output.WriteCodedIndex(CIx.Implementation,rRef);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) { return 18; }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for elements in the PropertyMap, EventMap and \r
-       /// NestedClass MetaData tables\r
-       /// </summary>\r
-  public class MapElem : MetaDataElement\r
-       {\r
-    ClassDef parent;\r
-    uint elemIx;\r
-    MDTable elemTable;\r
-\r
-               internal MapElem(ClassDef par, uint elIx, MDTable elemTab) {\r
-      parent = par;\r
-      elemIx = elIx;\r
-      elemTable = elemTab;\r
-               }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteIndex(MDTable.TypeDef,parent.Row);\r
-      output.WriteIndex(elemTable,elemIx);\r
-    }\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for field/methods (member of a class)\r
-       /// </summary>\r
-       public abstract class Member : MetaDataElement\r
-       {\r
-    protected string name;\r
-    protected uint nameIx = 0, sigIx = 0;\r
-    \r
-               internal Member(string memName)\r
-               {\r
-      name = memName;\r
-                       tabIx = MDTable.MemberRef;\r
-               }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-  /// MetaData \r
-  ///   Root (20 bytes + UTF-8 Version String + quad align padding)\r
-  ///   StreamHeaders (8 bytes + null terminated name string + quad align padding)\r
-  ///   Streams \r
-  ///     #~        (always present - holds metadata tables)\r
-  ///     #Strings  (always present - holds identifier strings)\r
-  ///     #US       (Userstring heap)\r
-  ///     #Blob     (signature blobs)\r
-  ///     #GUID     (guids for assemblies or Modules)\r
-  /// </summary>\r
-\r
-  public class MetaData \r
-       {\r
-               private static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};\r
-               private static readonly byte StringsHeapMask = 0x1;\r
-               private static readonly byte GUIDHeapMask = 0x2;\r
-               private static readonly byte BlobHeapMask = 0x4;\r
-    private static readonly uint MetaDataSignature = 0x424A5342;\r
-    private static readonly uint maxSmlIxSize = 0xFFFF;\r
-    private static readonly uint max1BitSmlIx = 0x7FFF;\r
-    private static readonly uint max2BitSmlIx = 0x3FFF;\r
-    private static readonly uint max3BitSmlIx = 0x1FFF;\r
-    private static readonly uint max5BitSmlIx = 0x7FF;\r
-    // NOTE: version and stream name strings MUST always be quad padded\r
-    private static readonly string version = "v1.0.3705\0\0\0";\r
-    private static readonly char[] tildeName = {'#','~','\0','\0'};\r
-    private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};\r
-    private static readonly char[] usName = {'#','U','S','\0'};\r
-    private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};\r
-    private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};\r
-               private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;\r
-    private static readonly uint TildeHeaderSize = 24;\r
-    private static readonly uint StreamHeaderSize = 8;\r
-    private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;\r
-    private static readonly uint tildeHeaderSize = 8 + (uint)tildeName.Length;\r
-\r
-    MetaDataStream strings, us, guid, blob;\r
-\r
-    MetaDataStream[] streams = new MetaDataStream[5];\r
-    uint numStreams = 5;\r
-    uint tildeTide = 0, tildePadding = 0, tildeStart = 0;\r
-    uint numTables = 0;\r
-    ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];\r
-    ArrayList byteCodes = new ArrayList();\r
-    uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;\r
-               ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;\r
-    bool[] largeIx = new bool[numMetaDataTables];\r
-    bool[] lgeCIx = new bool[(int)CIx.MaxCIx];\r
-               bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;\r
-               private FileImage file;\r
-    private byte heapSizes = 0;\r
-               MetaDataElement entryPoint;\r
-               BinaryWriter output;\r
-    public MSCorLib mscorlib;\r
-    private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];\r
-    long mdStart;\r
-\r
-    internal MetaData(FileImage file) {\r
-      // tilde = new MetaDataStream(tildeName,false,0);\r
-      this.file = file;\r
-                       strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);\r
-      us = new MetaDataStream(usName,new UnicodeEncoding(),true);\r
-      guid = new MetaDataStream(guidName,false);\r
-      blob = new MetaDataStream(blobName,true);\r
-      streams[1] = strings;\r
-      streams[2] = us;\r
-      streams[3] = guid;\r
-      streams[4] = blob;\r
-      for (int i=0; i < numMetaDataTables; i++) {\r
-        largeIx[i] = false;\r
-      }\r
-      for (int i=0; i < lgeCIx.Length; i++) {\r
-        lgeCIx[i] = false;\r
-      }\r
-      mscorlib = new MSCorLib(this);\r
-               }\r
\r
-    internal TypeSpec GetPrimitiveTypeSpec(int ix) {\r
-      return systemTypeSpecs[ix];\r
-    }\r
-\r
-    internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec) {\r
-      systemTypeSpecs[ix] = typeSpec;\r
-    }\r
-\r
-    internal uint Size() {\r
-      //Console.WriteLine("metaData size = " + metaDataSize);\r
-      return metaDataSize;\r
-    }\r
-\r
-               internal void StreamSize(byte mask) {\r
-                       heapSizes |= mask;\r
-               }\r
-\r
-    internal uint AddToUSHeap(string str) {\r
-      if (str == null) return 0;\r
-      return us.Add(str,true);\r
-   }\r
-\r
-    internal uint AddToStringsHeap(string str) {\r
-      if ((str == null) || (str.CompareTo("") == 0)) return 0;\r
-      return strings.Add(str,false);\r
-    }\r
-\r
-    internal uint AddToGUIDHeap(Guid guidNum) {\r
-      return guid.Add(guidNum);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(byte[] blobBytes) {\r
-      if (blobBytes == null) return 0;\r
-      return blob.Add(blobBytes);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(byte val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(sbyte val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(ushort val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(short val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(uint val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(int val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(ulong val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(long val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(float val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(double val) {\r
-      return blob.Add(val);\r
-    }\r
-\r
-    internal uint AddToBlobHeap(string val) {\r
-      return blob.Add(val,true);\r
-    }\r
-\r
-\r
-    private ArrayList GetTable(MDTable tableIx) {\r
-      int tabIx = (int)tableIx;\r
-      if (metaDataTables[tabIx] == null) {\r
-        metaDataTables[tabIx] = new ArrayList();\r
-        valid |= ((ulong)0x1 << tabIx);\r
-        // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);\r
-        numTables++;\r
-      }\r
-      return metaDataTables[tabIx];\r
-    }\r
\r
-    internal void AddToTable(MDTable tableIx, MetaDataElement elem) {\r
-      if (elem.Row > 0) {\r
-        // Console.Out.WriteLine("ERROR - element already in table " + tableIx);\r
-        return;\r
-      }\r
-      // updates Row field of the element\r
-      // Console.WriteLine("Adding element to table " + (uint)tableIx);\r
-      ArrayList table = GetTable(tableIx);\r
-      elem.Row = (uint)table.Count + 1;\r
-      table.Add(elem);\r
-    }\r
-\r
-    internal uint TableIndex(MDTable tableIx) {\r
-      if (metaDataTables[(int)tableIx] == null) return 1;\r
-      return (uint)metaDataTables[(int)tableIx].Count+1;\r
-    }\r
-\r
-    internal uint AddCode(CILInstructions byteCode) {\r
-      byteCodes.Add(byteCode);\r
-      uint offset = codeSize + codeStart;\r
-      codeSize += byteCode.GetCodeSize();\r
-      return offset;\r
-    }\r
-\r
-    internal void SetEntryPoint(MetaDataElement ep) {\r
-      entryPoint = ep;\r
-    }\r
-\r
-    internal void AddData(DataConstant cVal) {\r
-      file.AddInitData(cVal);\r
-    }\r
-\r
-               internal static void CompressNum(uint val, MemoryStream sig) {\r
-                       if (val < 0x7F) {\r
-                               sig.WriteByte((byte)val);\r
-                       } else if (val < 0x3FFF) {\r
-                               byte b1 = (byte)((val >> 8) | 0x80);\r
-                               byte b2 = (byte)(val & FileImage.iByteMask[0]);\r
-                               sig.WriteByte(b1);\r
-                               sig.WriteByte(b2);\r
-                       } else {\r
-                               byte b1 = (byte)((val >> 24) | 0xC0);\r
-                               byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);\r
-                               byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;\r
-                               byte b4 = (byte)(val & FileImage.iByteMask[0]);\r
-                               sig.WriteByte(b1);\r
-                               sig.WriteByte(b2);\r
-                               sig.WriteByte(b3);\r
-                               sig.WriteByte(b4);\r
-                       }\r
-               }\r
-\r
-    internal uint CodeSize() {\r
-      return codeSize + byteCodePadding;\r
-    }\r
-\r
-    internal uint StringsIndexSize() {\r
-      if (largeStrings) return 4;\r
-      return 2;\r
-    }\r
-\r
-    internal uint GUIDIndexSize() {\r
-      if (largeGUID) return 4;\r
-      return 2;\r
-    }\r
-\r
-    internal uint USIndexSize() {\r
-      if (largeUS) return 4;\r
-      return 2;\r
-    }\r
-\r
-    internal uint BlobIndexSize() {\r
-      if (largeBlob) return 4;\r
-      return 2;\r
-    }\r
-\r
-    internal uint CodedIndexSize(CIx code) {\r
-      if (lgeCIx[(uint)code]) return 4;\r
-      return 2;\r
-    }\r
-\r
-    internal uint TableIndexSize(MDTable tabIx) {\r
-      if (largeIx[(uint)tabIx]) return 4;\r
-      return 2;\r
-    }\r
-    \r
-    private void SetIndexSizes() {\r
-      for (int i=0; i < numMetaDataTables; i++) {\r
-        if (metaDataTables[i] != null) {\r
-          uint count = (uint)metaDataTables[i].Count;\r
-          if (count > maxSmlIxSize) {\r
-            largeIx[i] = true;\r
-                                               MDTable tabIx = (MDTable)i;\r
-            if (count > max5BitSmlIx) {\r
-              lgeCIx[(int)CIx.HasCustomAttr] = true;\r
-            }\r
-            if (count > max3BitSmlIx) {\r
-              if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec)) \r
-                lgeCIx[(int)CIx.CustomAttributeType] = true;\r
-              if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef)) \r
-                lgeCIx[(int)CIx.MemberRefParent] = true;\r
-            } else if (count > max2BitSmlIx) {\r
-              if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property)) \r
-                lgeCIx[(int)CIx.HasConst] = true;\r
-              if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))\r
-                lgeCIx[(int)CIx.TypeDefOrRef] = true;\r
-              if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))\r
-                lgeCIx[(int)CIx.HasDeclSecurity] = true;\r
-              if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))\r
-                lgeCIx[(int)CIx.Implementation] = true;\r
-              if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))\r
-                lgeCIx[(int)CIx.ResolutionScope] = true;\r
-            } else if (count > max1BitSmlIx) {\r
-              if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param)) \r
-                lgeCIx[(int)CIx.HasFieldMarshal] = true;\r
-              if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property)) \r
-                lgeCIx[(int)CIx.HasSemantics] = true;\r
-              if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef)) \r
-                lgeCIx[(int)CIx.MethodDefOrRef] = true;\r
-              if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method)) \r
-                lgeCIx[(int)CIx.MemberForwarded] = true; \r
-              if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method)) \r
-                lgeCIx[(int)CIx.TypeOrMethodDef] = true; \r
-            }\r
-          }\r
-        }\r
-      }\r
-                       if (strings.LargeIx()) {\r
-                               largeStrings = true;\r
-                               heapSizes |= StringsHeapMask;\r
-                       }\r
-                       if (guid.LargeIx()) {\r
-                               largeGUID = true;\r
-                               heapSizes |= GUIDHeapMask;\r
-                       }\r
-                       if (blob.LargeIx()) {\r
-                               largeBlob = true;\r
-                               heapSizes |= BlobHeapMask;\r
-                       }\r
-      largeUS = us.LargeIx();\r
-    }\r
-\r
-    private void SetStreamOffsets() {\r
-      uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;\r
-      for (int i=1; i < numStreams; i++) {\r
-        sizeOfHeaders += streams[i].headerSize();\r
-      }\r
-      metaDataSize = MetaDataHeaderSize + sizeOfHeaders;\r
-      // Console.WriteLine("Size of meta data headers (tildeStart) = " + metaDataSize);\r
-      tildeStart = metaDataSize;\r
-      metaDataSize += tildeTide + tildePadding;\r
-      //Console.WriteLine(tildeName + " - size = " + (tildeTide + tildePadding));\r
-      for (int i=1; i < numStreams; i++) {\r
-        // Console.WriteLine("Stream " + i + " starts at " + metaDataSize);\r
-        streams[i].Start = metaDataSize;\r
-        metaDataSize += streams[i].Size();\r
-        streams[i].WriteDetails();\r
-      }\r
-    }\r
-\r
-    internal void CalcTildeStreamSize() {\r
-      //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());\r
-      tildeTide = TildeHeaderSize;\r
-      tildeTide += 4 * numTables;\r
-      //Console.WriteLine("Tilde header + sizes = " + tildeTide);\r
-      for (int i=0; i < numMetaDataTables; i++) {\r
-        if (metaDataTables[i] != null) {\r
-          ArrayList table = metaDataTables[i];\r
-          // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);\r
-          tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);\r
-          // Console.WriteLine("Metadata table " + i + " has size " + table.Count);\r
-          // Console.WriteLine("tildeTide = " + tildeTide);\r
-        }\r
-      }\r
-      if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);\r
-      //Console.WriteLine("tildePadding = " + tildePadding);\r
-    }\r
-\r
-    internal void WriteTildeStream(FileImage output) {\r
-      long startTilde = output.Seek(0,SeekOrigin.Current);\r
-                       output.Write((uint)0); // Reserved\r
-                       output.Write((byte)1); // MajorVersion\r
-                       output.Write((byte)0); // MinorVersion\r
-                       output.Write(heapSizes);\r
-                       output.Write((byte)1); // Reserved\r
-                       output.Write(valid);\r
-                       output.Write(sorted);\r
-                       for (int i=0; i < numMetaDataTables; i++) {\r
-                               if (metaDataTables[i] != null) {\r
-                                       uint count = (uint)metaDataTables[i].Count;\r
-                                       output.Write(count);\r
-                               }\r
-                       }\r
-      long tabStart = output.Seek(0,SeekOrigin.Current);\r
-      // Console.WriteLine("Starting metaData tables at " + tabStart);\r
-                       for (int i=0; i < numMetaDataTables; i++) {\r
-                               if (metaDataTables[i] != null) {\r
-          // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));\r
-          ArrayList table = metaDataTables[i];\r
-                                       for (int j=0; j < table.Count; j++) {\r
-             ((MetaDataElement)table[j]).Write(output);\r
-                                       }\r
-                               }\r
-                       }\r
-      // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));\r
-      for (int i=0; i < tildePadding; i++) output.Write((byte)0);\r
-               }\r
-\r
-    private void BuildTable(ArrayList table) {\r
-      if (table == null) return;\r
-      for (int j=0; j < table.Count; j++) {\r
-        ((MetaDataElement)table[j]).BuildTables(this);\r
-      }\r
-    }\r
-\r
-    internal void BuildMetaData(uint codeStartOffset) {\r
-      codeStart = codeStartOffset;\r
-      BuildTable(metaDataTables[(int)MDTable.TypeDef]);\r
-      BuildTable(metaDataTables[(int)MDTable.MemberRef]);\r
-      BuildTable(metaDataTables[(int)MDTable.GenericParam]);\r
-      BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);\r
-      BuildTable(metaDataTables[(int)MDTable.CustomAttribute]);\r
-/*      for (int i=0; i < metaDataTables.Length; i++) {\r
-        ArrayList table = metaDataTables[i];\r
-        if (table != null) {\r
-          for (int j=0; j < table.Count; j++) {\r
-            ((MetaDataElement)table[j]).BuildTables(this);\r
-          }\r
-        }\r
-      }\r
-      */\r
-                       SetIndexSizes();\r
-                       for (int i=1; i < numStreams; i++) {\r
-                               streams[i].EndStream();\r
-                       }\r
-                       CalcTildeStreamSize();\r
-                       SetStreamOffsets();\r
-      byteCodePadding = NumToAlign(codeSize,4);\r
-      if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());\r
-    }\r
-\r
-    internal void WriteByteCodes(FileImage output) {\r
-      for (int i=0; i < byteCodes.Count; i++) {\r
-        ((CILInstructions)byteCodes[i]).Write(output);\r
-      }\r
-      for (int i=0; i < byteCodePadding; i++) {\r
-        output.Write((byte)0);\r
-      }\r
-    }\r
-\r
-    internal void WriteMetaData(FileImage output) {\r
-                       this.output = output;\r
-      mdStart = output.Seek(0,SeekOrigin.Current);\r
-      // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));\r
-      output.Write(MetaDataSignature);\r
-      output.Write((short)1);  // Major Version\r
-      output.Write((short)1);  // Minor Version  ECMA = 0, PEFiles = 1\r
-      output.Write(0);         // Reserved\r
-      output.Write(version.Length);\r
-      output.Write(version.ToCharArray());   // version string is already zero padded\r
-      output.Write((short)0);\r
-      output.Write((ushort)numStreams);\r
-      // write tilde header\r
-      output.Write(tildeStart);\r
-      output.Write(tildeTide + tildePadding);\r
-      output.Write(tildeName);\r
-      for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);\r
-      // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);\r
-      WriteTildeStream(output);\r
-      for (int i=1; i < numStreams; i++) streams[i].Write(output);\r
-      // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));\r
-    }\r
-\r
-               internal bool LargeStringsIndex() { return strings.LargeIx(); }\r
-               internal bool LargeGUIDIndex() { return guid.LargeIx(); }\r
-               internal bool LargeUSIndex() { return us.LargeIx(); }\r
-               internal bool LargeBlobIndex() { return blob.LargeIx(); }\r
-\r
-    internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }\r
-\r
-\r
-               private uint NumToAlign(uint val, uint alignVal) {\r
-                       if ((val % alignVal) == 0) return 0;\r
-                       return alignVal - (val % alignVal);\r
-               }\r
-\r
-    internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output) {\r
-      uint ix = 0;\r
-      if (elem != null) { \r
-        ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);\r
-        // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);\r
-      //} else {\r
-        // Console.WriteLine("elem for coded index is null");\r
-      }\r
-      if (lgeCIx[(uint)code]) \r
-        output.Write(ix);\r
-      else\r
-        output.Write((ushort)ix);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for all Meta Data table elements\r
-       /// </summary>\r
-\r
-  public abstract class MetaDataElement\r
-       {\r
-\r
-    protected ArrayList customAttributes;\r
-    private uint row = 0;\r
-    protected bool done = false;\r
-               protected MDTable tabIx;\r
-\r
-    internal MetaDataElement() { }\r
-\r
-    public uint Row {\r
-      get {\r
-        return row;\r
-      }\r
-      set {\r
-        if (row == 0) row = value;\r
-      }\r
-    }\r
-\r
-    internal virtual uint GetCodedIx(CIx code) { return 0; }\r
-\r
-    /// <summary>\r
-    /// Add a custom attribute to this item\r
-    /// </summary>\r
-    /// <param name="ctorMeth">the constructor method for this attribute</param>\r
-    /// <param name="val">the byte value of the parameters</param>\r
-    public void AddCustomAttribute(Method ctorMeth, byte[] val) {\r
-      if (customAttributes == null) {\r
-        customAttributes = new ArrayList();\r
-      } \r
-      customAttributes.Add(new CustomAttribute(this,ctorMeth,val));\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a custom attribute to this item\r
-    /// </summary>\r
-    /// <param name="ctorMeth">the constructor method for this attribute</param>\r
-    /// <param name="val">the constant values of the parameters</param>\r
-    public void AddCustomAttribute(Method ctorMeth, Constant[] cVals) {\r
-      if (customAttributes == null) {\r
-        customAttributes = new ArrayList();\r
-      } \r
-//      customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));\r
-    }\r
-\r
-    internal void DoCustomAttributes(MetaData md) {\r
-      if (customAttributes != null) {\r
-        for (int i=0; i < customAttributes.Count; i++) {\r
-          CustomAttribute ca = (CustomAttribute)customAttributes[i];\r
-          ca.BuildTables(md);\r
-        }\r
-      }\r
-    }\r
-\r
-    internal uint Token() {\r
-      return (((uint)tabIx << 24) | row);\r
-    }\r
-\r
-    internal virtual void BuildTables(MetaData md) {\r
-      done = true;\r
-    }\r
-\r
-    internal virtual uint Size(MetaData md) { \r
-      return 0;\r
-    }\r
-\r
-    internal virtual void Write(FileImage output) {   }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Stream in the Meta Data  (#Strings, #US, #Blob and #GUID)\r
-       /// </summary>\r
-\r
-  internal class MetaDataStream : BinaryWriter \r
-       {\r
-               private static readonly uint StreamHeaderSize = 8;\r
-               private static uint maxSmlIxSize = 0xFFFF;\r
-               \r
-    private uint start = 0; \r
-    uint size = 0, tide = 1;\r
-    bool largeIx = false;\r
-    uint sizeOfHeader;\r
-    char[] name;\r
-    Hashtable htable = new Hashtable();\r
-\r
-    internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream()) {\r
-      if (addInitByte) { Write((byte)0); size = 1; }\r
-      this.name = name;\r
-      sizeOfHeader = StreamHeaderSize + (uint)name.Length;\r
-    }\r
-\r
-    internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc) {\r
-      if (addInitByte) { Write((byte)0); size = 1; }\r
-      this.name = name;\r
-      sizeOfHeader = StreamHeaderSize + (uint)name.Length;\r
-               }\r
-\r
-    public uint Start {\r
-      get {\r
-        return start;\r
-      }\r
-      set {\r
-        start = value;\r
-      }\r
-    }\r
-  \r
-    internal uint headerSize() {\r
-      // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);\r
-      return sizeOfHeader;\r
-    }\r
-\r
-    internal void SetSize(uint siz) {\r
-      size = siz;\r
-    }\r
-\r
-    internal uint Size() {\r
-      return size;\r
-    }\r
-\r
-    internal bool LargeIx() {\r
-      return largeIx;\r
-    }\r
-\r
-    internal void WriteDetails() {\r
-      // Console.WriteLine(name + " - size = " + size);\r
-    }\r
-\r
-               internal uint Add(string str, bool prependSize) {\r
-      Object val = htable[str];\r
-      uint index = 0;\r
-      if (val == null) { \r
-        index = size;\r
-        htable[str] = index;\r
-        char[] arr = str.ToCharArray();\r
-        if (prependSize) CompressNum((uint)arr.Length*2+1);\r
-        Write(arr);\r
-        Write((byte)0);\r
-        size = (uint)Seek(0,SeekOrigin.Current);\r
-      } else {\r
-        index = (uint)val;\r
-      }\r
-                       return index;\r
-               }\r
-\r
-               internal uint Add(Guid guid) {\r
-                       Write(guid.ToByteArray());\r
-                       size =(uint)Seek(0,SeekOrigin.Current);\r
-                       return tide++;\r
-               }\r
-\r
-               internal uint Add(byte[] blob) {\r
-                       uint ix = size;\r
-                       CompressNum((uint)blob.Length);\r
-                       Write(blob);\r
-                       size = (uint)Seek(0,SeekOrigin.Current);\r
-                       return ix;\r
-               }\r
-\r
-    internal uint Add(byte val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(sbyte val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(ushort val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(short val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(uint val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(int val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(ulong val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(long val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(float val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-    internal uint Add(double val) {\r
-      uint ix = size;\r
-      Write(val);\r
-      size = (uint)Seek(0,SeekOrigin.Current);\r
-      return ix;\r
-    }\r
-\r
-               private void CompressNum(uint val) {\r
-      if (val < 0x7F) {\r
-        Write((byte)val);\r
-      } else if (val < 0x3FFF) {\r
-        byte b1 = (byte)((val >> 8) | 0x80);\r
-        byte b2 = (byte)(val & FileImage.iByteMask[0]);\r
-        Write(b1);\r
-        Write(b2);\r
-      } else {\r
-        byte b1 = (byte)((val >> 24) | 0xC0);\r
-        byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);\r
-        byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;\r
-        byte b4 = (byte)(val & FileImage.iByteMask[0]);\r
-        Write(b1);\r
-        Write(b2);\r
-        Write(b3);\r
-        Write(b4);\r
-      }\r
-    }\r
-\r
-    private void QuadAlign() {\r
-      if ((size % 4) != 0) {\r
-        uint pad = 4 - (size % 4);\r
-        size += pad;\r
-        for (int i=0; i < pad; i++) {\r
-          Write((byte)0);\r
-        }\r
-      }\r
-    }\r
-\r
-               internal void EndStream() {\r
-                       QuadAlign();\r
-                       if (size > maxSmlIxSize) {\r
-                               largeIx = true;\r
-                       }\r
-               }\r
-\r
-    internal void WriteHeader(BinaryWriter output) {\r
-      output.Write(start);\r
-      output.Write(size);\r
-      output.Write(name);\r
-    }\r
-\r
-               internal virtual void Write(BinaryWriter output) {\r
-       // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);\r
-      MemoryStream str = (MemoryStream)BaseStream;\r
-                       output.Write(str.ToArray());\r
-               }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for Method Descriptors\r
-       /// </summary>\r
-\r
-  public abstract class Method : Member\r
-       {\r
-    protected CallConv callConv = CallConv.Default;\r
-    protected Type retType;\r
-\r
-    internal Method(string methName, Type rType) : base(methName)\r
-               {\r
-      retType = rType;\r
-               }\r
-\r
-    /// <summary>\r
-    /// Add calling conventions to this method descriptor\r
-    /// </summary>\r
-    /// <param name="cconv"></param>\r
-    public void AddCallConv(CallConv cconv) {\r
-      callConv |= cconv;\r
-    }\r
-\r
-               internal abstract void TypeSig(MemoryStream sig);\r
-\r
-    internal uint GetSigIx(MetaData md) {\r
-      MemoryStream sig = new MemoryStream();\r
-                       TypeSig(sig);\r
-      return md.AddToBlobHeap(sig.ToArray());\r
-    }\r
-\r
-    internal Type GetRetType() {\r
-      return retType;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a method defined in THIS assembly/module\r
-       /// IL     .method\r
-       /// </summary>\r
-\r
-  public class MethodDef : Method\r
-       {\r
-    private static readonly ushort PInvokeImpl = 0x2000;\r
-    //private static readonly uint UnmanagedExport = 0x0008;\r
-   // private static readonly byte LocalSigByte = 0x7;\r
-    uint parIx = 0, textOffset = 0;\r
-\r
-    MetaData metaData;\r
-    CILInstructions code;\r
-    ArrayList securityActions = new ArrayList();\r
-               Param[] parList;\r
-    Local[] locals;\r
-    bool initLocals;\r
-    ushort methFlags = 0, implFlags = 0;\r
-    int maxStack = 0, numPars = 0;\r
-    bool entryPoint = false;\r
-    LocalSig localSig;\r
-                ArrayList varArgSigList;\r
-    ImplMap pinvokeImpl;\r
-\r
-\r
-               internal MethodDef(MetaData md, string name, Type retType, Param[] pars) : base(name,retType) {\r
-      metaData = md;\r
-                       parList = pars;\r
-                       if (parList != null) numPars = parList.Length;\r
-      tabIx = MDTable.Method;\r
-               }\r
-\r
-    internal MethodDef(MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, Type retType, Param[] pars) : base(name,retType) {\r
-      metaData = md;\r
-                       parList = pars;\r
-                       if (parList != null) numPars = parList.Length;\r
-      // Console.WriteLine("Creating method " + name + " with " + numPars + " parameters");\r
-                       methFlags = (ushort)mAttrSet;\r
-      implFlags = (ushort)iAttrSet;\r
-      tabIx = MDTable.Method;\r
-    }\r
-\r
-               internal Param[] GetPars() {\r
-                       return parList;\r
-               }\r
-\r
-    /// <summary>\r
-    /// Add some attributes to this method descriptor\r
-    /// </summary>\r
-    /// <param name="ma">the attributes to be added</param>\r
-    public void AddMethAttribute(MethAttr ma) {\r
-      methFlags |= (ushort)ma;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add some implementation attributes to this method descriptor\r
-    /// </summary>\r
-    /// <param name="ia">the attributes to be added</param>\r
-    public void AddImplAttribute(ImplAttr ia) {\r
-      implFlags |= (ushort)ia;\r
-    }\r
-\r
-    public void AddPInvokeInfo(ModuleRef scope, string methName,\r
-                               PInvokeAttr callAttr) {\r
-      pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);\r
-      methFlags |= PInvokeImpl;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the maximum stack height for this method\r
-    /// </summary>\r
-    /// <param name="maxStack">the maximum height of the stack</param>\r
-    public void SetMaxStack(int maxStack) {\r
-      this.maxStack = maxStack; \r
-    }\r
-\r
-    /// <summary>\r
-    /// Add local variables to this method\r
-    /// </summary>\r
-    /// <param name="locals">the locals to be added</param>\r
-    /// <param name="initLocals">are locals initialised to default values</param>\r
-    public void AddLocals(Local[] locals, bool initLocals) {\r
-      this.locals = locals;\r
-      this.initLocals = initLocals;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Mark this method as having an entry point\r
-    /// </summary>\r
-    public void DeclareEntryPoint() {\r
-      entryPoint = true;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a code buffer for this method to add the IL instructions to\r
-    /// </summary>\r
-    /// <returns>a buffer for this method's IL instructions</returns>\r
-    public CILInstructions CreateCodeBuffer() {\r
-      code = new CILInstructions(metaData);\r
-      return code;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Make a method reference descriptor for this method to be used \r
-    /// as a callsite signature for this vararg method\r
-    /// </summary>\r
-    /// <param name="optPars">the optional pars for the vararg method call</param>\r
-    /// <returns></returns>\r
-    public MethodRef MakeVarArgSignature(Type[] optPars) {\r
-      Type[] pars = new Type[numPars];\r
-      MethodRef varArgSig;\r
-      for (int i=0; i < numPars; i++) {\r
-        pars[i] = parList[i].GetParType();\r
-      }\r
-      varArgSig = new MethodRef(this,name,retType,pars,true,optPars);\r
-\r
-      if (varArgSigList == null)\r
-              varArgSigList = new ArrayList ();\r
-      varArgSigList.Add (varArgSig);\r
-      return varArgSig;\r
-    }\r
-\r
-               internal sealed override void TypeSig(MemoryStream sig) {\r
-                       sig.WriteByte((byte)callConv);\r
-                       MetaData.CompressNum((uint)numPars,sig);\r
-                       retType.TypeSig(sig);\r
-                       for (ushort i=0; i < numPars; i++) {\r
-                               parList[i].seqNo = (ushort)(i+1);\r
-                               parList[i].TypeSig(sig);\r
-                       }\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      if (pinvokeImpl != null) {\r
-        md.AddToTable(MDTable.ImplMap,pinvokeImpl);\r
-        pinvokeImpl.BuildTables(md);\r
-      }\r
-      if (entryPoint) md.SetEntryPoint(this);\r
-      uint locToken = 0;\r
-      if (locals != null) {\r
-        localSig = new LocalSig(locals);\r
-        md.AddToTable(MDTable.StandAloneSig,localSig);\r
-        localSig.BuildTables(md);\r
-        locToken = localSig.Token();\r
-      }\r
-                       if (code != null) {\r
-                               code.CheckCode(locToken,initLocals,maxStack);\r
-                               textOffset = md.AddCode(code);\r
-                       }\r
-      nameIx = md.AddToStringsHeap(name);\r
-      sigIx = GetSigIx(md);\r
-      parIx = md.TableIndex(MDTable.Param);\r
-                       for (int i=0; i < numPars; i++) {\r
-                               md.AddToTable(MDTable.Param,parList[i]);\r
-                               parList[i].BuildTables(md);\r
-                       }\r
-      if (varArgSigList != null) {\r
-              foreach (MethodRef varArgSig in varArgSigList) {\r
-        md.AddToTable(MDTable.MemberRef,varArgSig);\r
-        varArgSig.BuildTables(md);\r
-      }\r
-      }\r
-      DoCustomAttributes (md);\r
-      // Console.WriteLine("method has " + numPars + " parameters");\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      if (ZeroRva ()) output.Write(0);\r
-      else output.WriteCodeRVA(textOffset);\r
-      output.Write(implFlags);\r
-      output.Write(methFlags);\r
-      output.StringsIndex(nameIx);\r
-      output.BlobIndex(sigIx);\r
-      output.WriteIndex(MDTable.Param,parIx);\r
-    }\r
-\r
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+
+namespace PEAPI 
+{
+  public class Hex {
+    readonly static char[] hexDigit = {'0','1','2','3','4','5','6','7',
+                                        '8','9','A','B','C','D','E','F'};
+    readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};
+    readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00, 
+                                          0x0000000000FF0000, 0x00000000FF000000,
+                                          0x000000FF00000000, 0x0000FF0000000000,
+                                          0x00FF000000000000, 0xFF00000000000000 };
+    readonly static uint nibble0Mask = 0x0000000F;
+    readonly static uint nibble1Mask = 0x000000F0;
+
+    public static String Byte(int b) {
+      char[] str = new char[2];
+      uint num = (uint)b;
+      uint b1 = num & nibble0Mask;
+      uint b2 = (num & nibble1Mask) >> 4;
+      str[0] = hexDigit[b2];
+      str[1] = hexDigit[b1];
+      return new String(str);
+    }
+
+    public static String Short(int b) {
+      char[] str = new char[4];
+      uint num1 = (uint)b & iByteMask[0];
+      uint num2 = ((uint)b & iByteMask[1]) >> 8;
+      uint b1 = num1 & nibble0Mask;
+      uint b2 = (num1 & nibble1Mask) >> 4;
+      uint b3 = num2 & nibble0Mask;
+      uint b4 = (num2 & nibble1Mask) >> 4;
+      str[0] = hexDigit[b4];
+      str[1] = hexDigit[b3];
+      str[2] = hexDigit[b2];
+      str[3] = hexDigit[b1];
+      return new String(str);
+    }
+
+    public static String Int(int val) {
+      char[] str = new char[8];
+      uint num = (uint)val;
+      int strIx = 7;
+      for (int i=0; i < iByteMask.Length; i++) {
+        uint b = num & iByteMask[i];
+        b >>= (i*8);
+        uint b1 = b & nibble0Mask;
+        uint b2 = (b & nibble1Mask) >> 4;
+        str[strIx--] = hexDigit[b1];
+        str[strIx--] = hexDigit[b2];
+      }
+      return new String(str);
+    }
+    public static String Int(uint num) {
+      char[] str = new char[8];
+      int strIx = 7;
+      for (int i=0; i < iByteMask.Length; i++) {
+        uint b = num & iByteMask[i];
+        b >>= (i*8);
+        uint b1 = b & nibble0Mask;
+        uint b2 = (b & nibble1Mask) >> 4;
+        str[strIx--] = hexDigit[b1];
+        str[strIx--] = hexDigit[b2];
+      }
+      return new String(str);
+    }
+
+    public static String Long(long lnum) {
+      ulong num = (ulong)lnum;
+      char[] str = new char[16];
+      int strIx = 15;
+      for (int i=0; i < lByteMask.Length; i++) {
+        ulong b = num & lByteMask[i];
+        b >>= (i*8);
+        ulong b1 = b & nibble0Mask;
+        ulong b2 = (b & nibble1Mask) >> 4;
+        str[strIx--] = hexDigit[b1];
+        str[strIx--] = hexDigit[b2];
+      }
+      return new String(str);
+    }
+  }
+
+  public class NotYetImplementedException : System.Exception 
+  {
+     public NotYetImplementedException(string msg) : base(msg + " Not Yet Implemented") { }
+  }
+
+  public class TypeSignatureException : System.Exception {
+    public TypeSignatureException(string msg) : base(msg) { }
+  }
+
+                   public class ClassRefInst : Type {
+
+                          private Type type;
+                          private bool is_value;
+
+            public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ()) {
+                    this.type = type;
+                    this.is_value = is_value;
+                    if (is_value)
+                          typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
+                    tabIx = MDTable.TypeSpec;
+            }
+
+            internal sealed override void TypeSig(MemoryStream str) {
+                    type.TypeSig (str);
+            }
+    }
+                  
+  public class MVar : Type {
+
+            private int index;
+
+            public MVar (int index) : base (0x1E) {
+                    this.index = index;
+                    tabIx = MDTable.TypeSpec;
+            }
+
+            internal sealed override void TypeSig(MemoryStream str) {
+                    str.WriteByte(typeIndex);
+                    MetaData.CompressNum ((uint) index, str);
+            }
+    }
+
+    public class GenericTypeSpec : Type {
+
+            private int index;
+
+            public GenericTypeSpec (int index) : base (0x13) {
+                    this.index = index;
+                    tabIx = MDTable.TypeSpec;
+            }
+
+            internal sealed override void TypeSig(MemoryStream str) {
+                    str.WriteByte(typeIndex);
+                    MetaData.CompressNum ((uint) index, str);
+            }
+    }
+
+  public class GenericTypeInst : Type {
+
+          private Type gen_type;
+          private Type[] gen_param;
+
+          public GenericTypeInst (Type gen_type, Type[] gen_param) : base (0x15)
+          {
+                  typeIndex = 0x15;
+                  this.gen_type = gen_type;
+                  this.gen_param = gen_param;
+                  tabIx = MDTable.TypeSpec;
+  }
+
+          internal sealed override void TypeSig(MemoryStream str) {
+                  str.WriteByte(typeIndex);
+                  gen_type.TypeSig (str);
+                  MetaData.CompressNum ((uint) gen_param.Length, str);
+                  foreach (Type param in gen_param)
+                          param.TypeSig (str);
+            }
+  }
+
+  public class GenericMethodSig {
+
+          private Type[] gen_param;
+
+          public GenericMethodSig (Type[] gen_param)
+          {
+                  this.gen_param = gen_param;
+          }
+
+          internal void TypeSig (MemoryStream str)
+          {
+                  MetaData.CompressNum ((uint) gen_param.Length, str); // THIS IS NOT RIGHT, but works
+                  MetaData.CompressNum ((uint) gen_param.Length, str);
+                  foreach (Type param in gen_param)
+                          param.TypeSig (str);
+          }
+
+          internal uint GetSigIx (MetaData md)
+          {
+                  MemoryStream sig = new MemoryStream();
+                  TypeSig (sig);
+                  return md.AddToBlobHeap (sig.ToArray());
+          }
+  }
+
+        public class Sentinel : Type {
+
+            public Sentinel () : base (0x41) { }
+
+            internal sealed override void TypeSig(MemoryStream str) {
+                    str.WriteByte(typeIndex);
+            }
+        }
+
+        /// <summary>
+        /// The IL Array type
+        /// </summary>
+        public abstract class Array : Type
+        {
+
+    protected Type elemType;
+                protected MetaData metaData;
+                protected string cnameSpace, cname;
+
+    internal Array(Type eType, byte TypeId) : base(TypeId) {
+      elemType = eType;
+                        tabIx = MDTable.TypeSpec;
+    }
+
+        }
+
+  /**************************************************************************/  
+  
+  /// <summary>
+  /// Single dimensional array with zero lower bound
+  /// </summary>
+  public class ZeroBasedArray : Array {
+
+    /// <summary>
+    /// Create a new array  -   elementType[]
+    /// </summary>
+    /// <param name="elementType">the type of the array elements</param>
+    public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
+
+    internal sealed override void TypeSig(MemoryStream str) {
+      str.WriteByte(typeIndex);
+      elemType.TypeSig(str); 
+    }
+
+  }
+
+
+  /**************************************************************************/           
+
+  /// <summary>
+  /// Multi dimensional array with explicit bounds
+  /// </summary>
+  public class BoundArray : Array {
+    int[] lowerBounds;
+    int[] sizes;
+    uint numDims;
+
+    /// <summary>
+    /// Create a new multi dimensional array type 
+    /// eg. elemType[1..5,3..10,5,,] would be 
+    /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
+    /// </summary>
+    /// <param name="elementType">the type of the elements</param>
+    /// <param name="dimensions">the number of dimensions</param>
+    /// <param name="loBounds">lower bounds of dimensions</param>
+    /// <param name="upBounds">upper bounds of dimensions</param>
+    public BoundArray(Type elementType, uint dimensions, int[] loBounds, 
+      int[] upBounds) : base (elementType,0x14) {
+      numDims = dimensions;
+      lowerBounds = loBounds;
+      sizes = new int[loBounds.Length];
+      for (int i=0; i < loBounds.Length; i++) {
+        sizes[i] = upBounds[i] - loBounds[i] + 1;
+      }
+    }
+
+    /// <summary>
+    /// Create a new multi dimensional array type 
+    /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
+    /// </summary>
+    /// <param name="elementType">the type of the elements</param>
+    /// <param name="dimensions">the number of dimensions</param>
+    /// <param name="size">the sizes of the dimensions</param>
+    public BoundArray(Type elementType, uint dimensions, int[] size) 
+                                                  : base (elementType,0x14) {
+      numDims = dimensions;
+      sizes = size;
+    }
+
+    /// <summary>
+    /// Create a new multi dimensional array type 
+    /// eg. elemType[,,] would be new BoundArray(elemType,3)
+    /// </summary>
+    /// <param name="elementType">the type of the elements</param>
+    /// <param name="dimensions">the number of dimensions</param>
+    public BoundArray(Type elementType, uint dimensions)
+                                                  : base (elementType,0x14) {
+      numDims = dimensions;
+    }
+
+    internal sealed override void TypeSig(MemoryStream str) {
+      str.WriteByte(typeIndex);
+      elemType.TypeSig(str);
+      MetaData.CompressNum(numDims,str);
+      if ((sizes != null) && (sizes.Length > 0)) {
+        MetaData.CompressNum((uint)sizes.Length,str);
+        for (int i=0; i < sizes.Length; i++) {
+          MetaData.CompressNum((uint)sizes[i],str);
+        }
+      } else str.WriteByte(0);
+      if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
+        MetaData.CompressNum((uint)lowerBounds.Length,str);
+        for (int i=0; i < lowerBounds.Length; i++) {
+          MetaData.CompressNum((uint)lowerBounds[i],str);
+        }
+      } else str.WriteByte(0);
+    }
+  
+  }
+  /**************************************************************************/  
+  /// <summary>
+  /// Descriptor for THIS assembly (.assembly)
+  /// </summary>
+  public class Assembly : ResolutionScope 
+  {
+    ushort majorVer, minorVer, buildNo, revisionNo;
+    uint flags;
+    uint hashAlgId;
+    uint keyIx = 0, cultIx = 0;
+    bool hasPublicKey = false;
+    
+    internal Assembly(string name, MetaData md) : base(name,md) {
+      tabIx = MDTable.Assembly;
+    }
+
+    /// <summary>
+    /// Add details about THIS assembly
+    /// </summary>
+    /// <param name="majVer">Major Version</param>
+    /// <param name="minVer">Minor Version</param>
+    /// <param name="bldNo">Build Number</param>
+    /// <param name="revNo">Revision Number</param>
+    /// <param name="key">Hash Key</param>
+    /// <param name="hash">Hash Algorithm</param>
+    /// <param name="cult">Culture</param>
+    public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo, 
+                              byte[] key, uint hash, string cult) {
+      majorVer = (ushort)majVer;
+      minorVer = (ushort)minVer;
+      buildNo = (ushort)bldNo;
+      revisionNo = (ushort)revNo;
+      hashAlgId = hash;
+      hasPublicKey = (key != null);
+      keyIx = metaData.AddToBlobHeap(key);
+      cultIx = metaData.AddToStringsHeap(cult);
+    }
+
+    /// <summary>
+    /// Add an attribute to THIS assembly
+    /// </summary>
+    /// <param name="aa">assembly attribute</param>
+    public void AddAssemblyAttr(AssemAttr aa) {
+      flags |= (uint)aa;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+//      Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
+      output.Write((uint)hashAlgId);
+      output.Write(majorVer);
+      output.Write(minorVer);
+      output.Write(buildNo);
+      output.Write(revisionNo);
+      output.Write(flags);
+      output.BlobIndex(keyIx);
+      output.StringsIndex(nameIx);
+      output.StringsIndex(cultIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 14; 
+        case (CIx.HasDeclSecurity) : return 2; 
+      }
+      return 0;
+    }
+
+    internal bool HasPublicKey {
+      get { return hasPublicKey; }
+    }
+  }     
+  /**************************************************************************/  
+
+        public interface IExternRef  {
+                ClassRef AddClass(string nsName, string name);
+                ClassRef AddValueClass(string nsName, string name);
+        }
+        
+        /// <summary>
+        /// A reference to an external assembly (.assembly extern)
+        /// </summary>
+        public class AssemblyRef : ResolutionScope, IExternRef
+        {
+    private ushort major, minor, build, revision;
+    uint flags, keyIx, hashIx, cultIx;
+    bool hasVersion = false, isKeyToken = false;
+    byte[] keyBytes;
+    string culture;
+
+    internal AssemblyRef(MetaData md, string name) : base(name,md) {
+      tabIx = MDTable.AssemblyRef;
+                }
+
+    /// <summary>
+    /// Add version information about this external assembly
+    /// </summary>
+    /// <param name="majVer">Major Version</param>
+    /// <param name="minVer">Minor Version</param>
+    /// <param name="bldNo">Build Number</param>
+    /// <param name="revNo">Revision Number</param>
+    public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo) {
+      major = (ushort)majVer;
+      minor = (ushort)minVer;
+      build = (ushort)bldNo;
+      revision = (ushort)revNo;
+      hasVersion = true;
+    }
+
+    /// <summary>
+    /// Add the hash value for this external assembly
+    /// </summary>
+    /// <param name="hash">bytes of the hash value</param>
+    public void AddHash(byte[] hash) {
+      hashIx = metaData.AddToBlobHeap(hash); 
+    }
+
+    /// <summary>
+    /// Set the culture for this external assembly
+    /// </summary>
+    /// <param name="cult">the culture string</param>
+    public void AddCulture(string cult) {
+      cultIx = metaData.AddToStringsHeap(cult);
+      culture = cult;
+    }
+
+    /// <summary>
+    /// Add the full public key for this external assembly
+    /// </summary>
+    /// <param name="key">bytes of the public key</param>
+    public void AddKey(byte[] key) {
+      flags |= 0x0001;   // full public key
+      keyBytes = key;
+      keyIx = metaData.AddToBlobHeap(key); 
+    }
+
+    /// <summary>
+    /// Add the public key token (low 8 bytes of the public key)
+    /// </summary>
+    /// <param name="key">low 8 bytes of public key</param>
+    public void AddKeyToken(byte[] key) {
+      keyIx = metaData.AddToBlobHeap(key); 
+      keyBytes = key;
+      isKeyToken = true;
+    }
+
+    /// <summary>
+    /// Add a class to this external assembly
+    /// </summary>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns></returns>
+    public virtual ClassRef AddClass(string nsName, string name) {
+      ClassRef aClass = new ClassRef(nsName,name,metaData);
+      metaData.AddToTable(MDTable.TypeRef,aClass);
+      aClass.SetParent(this);
+      return aClass;
+    }
+
+    /// <summary>
+    /// Add a value class to this external assembly
+    /// </summary>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns></returns>
+    public virtual ClassRef AddValueClass(string nsName, string name) {
+      ClassRef aClass = new ClassRef(nsName,name,metaData);
+      metaData.AddToTable(MDTable.TypeRef,aClass);
+      aClass.SetParent(this);
+      aClass.MakeValueClass(ValueClass.ValueType);
+      return aClass;
+    }
+
+    internal string TypeName() {
+      string result = name;
+      if (hasVersion) 
+        result = result + ", Version=" + major + "." + minor + "." + 
+                  build + "." + revision;
+      if (keyBytes != null) {
+        string tokenStr = "=";
+        if (isKeyToken) tokenStr = "Token=";
+        result = result + ", PublicKey" + tokenStr;
+        for (int i=0; i < keyBytes.Length; i++) {
+          result = result + Hex.Byte(keyBytes[i]);
+        }
+      }
+      if (culture != null) 
+        result = result + ", Culture=" + culture;
+      return result;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(major);
+      output.Write(minor);
+      output.Write(build);
+      output.Write(revision);
+      output.Write(flags);
+      output.BlobIndex(keyIx);
+      output.StringsIndex(nameIx);
+      output.StringsIndex(cultIx);
+      output.BlobIndex(hashIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.ResolutionScope) : return 2; 
+        case (CIx.HasCustomAttr) : return 15; 
+        case (CIx.Implementation) : return 1; 
+      }
+      return 0;
+    }
+
+        }
+  /**************************************************************************/  
+
+  /// <summary>
+  /// flags for the assembly (.corflags)
+  /// </summary>
+  public enum CorFlags {CF_IL_ONLY = 1, CF_32_BITREQUIRED = 2,
+                        CF_STRONGNAMESIGNED = 8, CF_TRACKDEBUGDATA = 0x10000 }
+
+  /// <summary>
+  /// subsystem for the assembly (.subsystem)
+  /// </summary>
+  public enum SubSystem { Native = 1, Windows_GUI = 2, 
+    Windows_CUI = 3, OS2_CUI = 5, POSIX_CUI = 7, Native_Windows = 8, 
+    Windows_CE_GUI = 9}
+  /// <summary>
+  /// Hash algorithms for the assembly
+  /// </summary>
+  public enum HashAlgorithm { None, SHA1 }
+
+  /// <summary>
+  /// Attributes for this assembly
+  /// </summary>
+  public enum AssemAttr { EnableJITCompileTracking = 0x8000, 
+                          DisableJITCompileOptimizer = 0x4000}
+
+  /// <summary>
+  /// Method call conventions
+  /// </summary>
+  public enum CallConv { Default, Cdecl, Stdcall, Thiscall, 
+    Fastcall, Vararg, Instance = 0x20, Generic = 0x10, InstanceExplicit = 0x60 }
+
+  /// <summary>
+  /// Type custom modifier
+  /// </summary>
+  public enum CustomModifier { modreq = 0x1F, modopt };
+
+  /// <summary>
+  /// Attibutes for a class
+  /// </summary>
+  public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate, 
+    NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem, 
+    SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20, 
+    Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100, 
+    PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800, 
+    Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
+    AutoClass = 0x20000, BeforeFieldInit = 0x100000 }
+
+  /// <summary>
+  /// Attributes for a field
+  /// </summary>
+  public enum FieldAttr {Default, Private, FamAndAssem, Assembly, 
+    Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16, 
+    Initonly = 0x20, Literal = 0x40, Notserialized = 0x80, 
+    SpecialName = 0x200, RTSpecialName = 0x400 }
+  
+  /// <summary>
+  /// Attributes for a method
+  /// </summary>
+  public enum MethAttr { Default, Private, FamAndAssem, Assembly,
+    Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16, 
+    Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040, 
+    PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080, 
+    NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,
+    RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800, 
+    RequireSecObject = 0x8000}
+
+  /// <summary>
+  /// Attributes for .pinvokeimpl method declarations
+  /// </summary>
+  public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
+                            lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
+                            stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500 }
+
+  /// <summary>
+  /// Implementation attributes for a method
+  /// </summary>
+  public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,
+    ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000, 
+    Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, Optil = 0x0002}
+
+  /// <summary>
+  /// Modes for a parameter
+  /// </summary>
+  public enum ParamAttr { Default, In, Out, Opt = 16 }
+
+  /// <summary>
+  /// CIL instructions
+  /// </summary>
+  public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,
+    ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3, 
+    ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3, 
+    ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop, 
+    ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4, 
+    ldind_u4, ldind_i8, ldind_i,  ldind_r4, ldind_r8, ldind_ref, stind_ref, 
+    stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
+    div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not, 
+    conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8, 
+    conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
+    conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un, 
+    conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un, 
+    ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2, 
+    ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8, 
+    ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,
+    stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2, 
+    conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3, 
+    conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf, 
+    add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally, 
+    stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un, 
+    localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_, 
+    cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D}
+
+  /// <summary>
+  /// CIL instructions requiring an integer parameter
+  /// </summary>
+  public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s, 
+                     stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
+                     ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
+
+  /// <summary>
+  /// CIL instructions requiring a field parameter
+  /// </summary>
+  public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
+                       stsfld, ldtoken = 0xD0 }
+
+  /// <summary>
+  /// CIL instructions requiring a method parameter
+  /// </summary>
+  public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73, 
+                        ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
+
+  /// <summary>
+  /// CIL instructions requiring a type parameter
+  /// </summary>
+  public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst, 
+                      unbox = 0x79, stobj = 0x81, box = 0x8C, newarr, 
+                      ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6, 
+                      ldtoken = 0xD0, initobj = 0xFE15, sizeOf = 0xFE1C,
+                      ldelem = 0xA3, stelem = 0xA4, unbox_any }
+
+  /// <summary>
+  /// CIL branch instructions
+  /// </summary>
+  public enum BranchOp {
+          // short branches
+          br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
+          ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
+          // long branches
+          br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,
+          bne_un, bge_un, bgt_un, ble_un, blt_un,
+
+          leave = 0xDD, leave_s }
+
+  /// <summary>
+  /// Index for all the tables in the meta data
+  /// </summary>
+  public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
+    Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute, 
+    FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig, 
+    EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics, 
+    MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20, 
+    AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor, 
+    AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
+    GenericParam, MethodSpec, GenericParamConstraint  }
+
+  public enum SafeArrayType { int16 = 2, int32, float32, float64,
+    currency, date, bstr, dispatch, error, boolean, variant, unknown,
+    Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }
+
+  internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,
+    HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef, 
+    MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
+    TypeOrMethodDef, MaxCIx }
+
+  internal enum MapType { eventMap, propertyMap, nestedClass }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// The assembly for mscorlib.  
+        /// </summary>
+        public sealed class MSCorLib : AssemblyRef
+        {
+    private static readonly int valueTypeIx = 18;
+    private readonly string systemName = "System";
+    private ClassRef[] systemClasses = new ClassRef[valueTypeIx+2];
+    private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
+    private TypeSpec[] specialTypeSpecs = new TypeSpec[valueTypeIx];
+    private static int[] specialNames = {
+      PrimitiveType.Void.GetName().GetHashCode(),
+      PrimitiveType.Boolean.GetName().GetHashCode(),
+      PrimitiveType.Char.GetName().GetHashCode(),
+      PrimitiveType.Int8.GetName().GetHashCode(),
+      PrimitiveType.UInt8.GetName().GetHashCode(),
+      PrimitiveType.Int16.GetName().GetHashCode(),
+      PrimitiveType.UInt16.GetName().GetHashCode(),
+      PrimitiveType.Int32.GetName().GetHashCode(),
+      PrimitiveType.UInt32.GetName().GetHashCode(),
+      PrimitiveType.Int64.GetName().GetHashCode(),
+      PrimitiveType.UInt64.GetName().GetHashCode(),
+      PrimitiveType.Float32.GetName().GetHashCode(),
+      PrimitiveType.Float64.GetName().GetHashCode(),
+      PrimitiveType.String.GetName().GetHashCode(),
+      PrimitiveType.TypedRef.GetName().GetHashCode(),
+      PrimitiveType.IntPtr.GetName().GetHashCode(),
+      PrimitiveType.UIntPtr.GetName().GetHashCode(),
+      PrimitiveType.Object.GetName().GetHashCode(),
+      PrimitiveType.ValueType.GetName ().GetHashCode(),
+      "Enum".GetHashCode()
+    };
+
+    internal MSCorLib(MetaData md) : base(md,"mscorlib") {
+      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;
+    }
+
+    /// <summary>
+    /// Add a class to the mscorlib assembly
+    /// </summary>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns></returns>
+    public override ClassRef AddClass(string nsName, string name) {
+      ClassRef aClass = GetSpecialClass(nsName,name);
+      if (aClass == null) {
+        aClass = new ClassRef(nsName,name,metaData);
+        metaData.AddToTable(MDTable.TypeRef,aClass);
+        aClass.SetParent(this);
+      }
+      return aClass;
+    }
+
+    private ClassRef GetSpecialClass(string nsName,string name) {
+      if (nsName.CompareTo(systemName) != 0) return null;
+      int hash = name.GetHashCode();
+      for (int i=0; i < specialNames.Length; i++) {
+        if (hash == specialNames[i]) {
+          if (systemClasses[i] == null) {
+            if (i < valueTypeIx) {
+              systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
+              if ((systemTypes[i] != PrimitiveType.Object) &&
+                (systemTypes[i] != PrimitiveType.String)) {
+                systemClasses[i].MakeValueClass(ValueClass.ValueType);
+              }
+            } else {
+              systemClasses[i] = new ClassRef(nsName,name,metaData);
+              systemClasses[i].SetParent(this);
+              if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
+                systemClasses[i].MakeValueClass(ValueClass.ValueType);
+            }
+            metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
+          }
+          return systemClasses[i];
+        }
+      }
+      return null;
+    }
+
+    internal ClassRef GetSpecialSystemClass(PrimitiveType pType) {
+      int ix = pType.GetSystemTypeIx();
+      if (systemClasses[ix] == null) {
+        systemClasses[ix] = new SystemClass(pType,this,metaData);
+        metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
+      }
+      return systemClasses[ix];
+    }
+        
+    private ClassRef GetValueClass(string name, int hash) {
+      int ix = valueTypeIx;
+      if (hash != specialNames[valueTypeIx]) ix++;
+      if (systemClasses[ix] == null) {
+        systemClasses[ix] = new ClassRef(systemName,name,metaData);
+        systemClasses[ix].SetParent(this);
+        systemClasses[ix].MakeValueClass(ValueClass.ValueType);
+        metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
+      }
+      return systemClasses[ix];
+    }
+
+    internal ClassRef ValueType() {
+      if (systemClasses[valueTypeIx] == null) {
+        ClassRef valType = new ClassRef("System","ValueType",metaData);
+        valType.SetParent(this);
+        valType.MakeValueClass(ValueClass.ValueType);
+        metaData.AddToTable(MDTable.TypeRef,valType);
+        systemClasses[valueTypeIx] = valType;
+      }
+      return systemClasses[valueTypeIx];
+    }
+
+    internal ClassRef EnumType() {
+      //systemClasses [ valueTypeIx + 1] -> System.Enum
+      if (systemClasses[valueTypeIx + 1] == null) {
+        ClassRef valType = new ClassRef("System","Enum",metaData);
+        valType.SetParent(this);
+        valType.MakeValueClass(ValueClass.Enum);
+        metaData.AddToTable(MDTable.TypeRef,valType);
+        systemClasses[valueTypeIx + 1] = valType;
+      }
+      return systemClasses[valueTypeIx + 1];
+    }
+
+    /// <summary>
+    /// Add a value class to this external assembly
+    /// </summary>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns></returns>
+    public override ClassRef AddValueClass(string nsName, string name) {
+      if (nsName.CompareTo(systemName) == 0) {
+        int hash = name.GetHashCode();
+        if ((hash == specialNames[valueTypeIx]) ||
+            (hash == specialNames[valueTypeIx+1])) {
+          return GetValueClass(name,hash);
+        }
+      }
+      ClassRef aClass = new ClassRef(nsName,name,metaData);
+      metaData.AddToTable(MDTable.TypeRef,aClass);
+      aClass.SetParent(this);
+      aClass.MakeValueClass(ValueClass.ValueType);
+      return aClass;
+    }
+
+        }
+        public enum ValueClass
+        {
+                ValueType,
+                Enum
+        }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Signature for calli instruction
+        /// </summary>
+        public class CalliSig : Signature
+        {
+    private static readonly byte Sentinel = 0x41;
+    CallConv callConv;
+    Type returnType;
+    Type[] parameters, optParams;
+                uint numPars = 0, numOptPars = 0;
+
+    /// <summary>
+    /// Create a signature for a calli instruction
+    /// </summary>
+    /// <param name="cconv">calling conventions</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">parameter types</param>
+    public CalliSig(CallConv cconv, Type retType, Type[] pars) {
+                        tabIx = MDTable.StandAloneSig;
+      callConv = cconv;
+      returnType = retType;
+      parameters = pars;
+                        if (pars != null) numPars = (uint)pars.Length;
+    }
+
+    /// <summary>
+    /// Add the optional parameters to a vararg method
+    /// This method sets the vararg calling convention
+    /// </summary>
+    /// <param name="optPars">the optional pars for the vararg call</param>
+    public void AddVarArgs(Type[] optPars) {
+      optParams = optPars;
+      if (optPars != null) numOptPars = (uint)optPars.Length;
+      callConv |= CallConv.Vararg;
+    }
+
+    /// <summary>
+    /// Add extra calling conventions to this callsite signature
+    /// </summary>
+    /// <param name="cconv"></param>
+    public void AddCallingConv(CallConv cconv) {
+      callConv |= cconv;
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      MemoryStream sig = new MemoryStream();
+      sig.WriteByte((byte)callConv);
+      MetaData.CompressNum(numPars+numOptPars,sig);
+      returnType.TypeSig(sig);
+      for (int i=0; i < numPars; i++) {
+        parameters[i].TypeSig(sig);
+      }
+      sigIx = md.AddToBlobHeap(sig.ToArray());
+      if (numOptPars > 0) {
+        sig.WriteByte(Sentinel);
+        for (int i=0; i < numOptPars; i++) {
+          optParams[i].TypeSig(sig);
+        }
+      }
+      done = true;
+    }
+
+        }
+  /**************************************************************************/  
+  /// <summary>
+  /// The IL instructions for a method
+  /// </summary>
+  public class CILInstructions 
+  {
+
+    private static readonly uint ExHeaderSize = 4;
+    private static readonly uint FatExClauseSize = 24;
+    private static readonly uint SmlExClauseSize = 12;
+    private static readonly sbyte maxByteVal = 127;
+    private static readonly sbyte minByteVal = -128;
+    private static readonly byte maxUByteVal = 255;
+    private static readonly int smallSize = 64;
+    private static readonly ushort TinyFormat = 0x2;
+    private static readonly ushort FatFormat = 0x3003;
+    private static readonly ushort MoreSects = 0x8;
+    private static readonly ushort InitLocals = 0x10;
+    private static readonly uint FatSize = 12;
+    private static readonly uint FatWords = FatSize/4;
+    private static readonly byte FatExceptTable = 0x41;
+    private static readonly byte SmlExceptTable = 0x01; 
+
+    private MetaData metaData;
+    private ArrayList exceptions, blockStack;
+    //private bool codeChecked = false;
+    private static readonly int INITSIZE = 5;
+    private CILInstruction[] buffer = new CILInstruction[INITSIZE];
+    private int tide = 0;
+    private uint offset = 0;
+    private ushort headerFlags = 0;
+    private short maxStack;
+    private uint paddingNeeded = 0;
+    private byte exceptHeader = 0;
+    uint localSigIx = 0;
+    uint codeSize = 0, exceptSize = 0;
+    bool tinyFormat, fatExceptionFormat = false;
+
+    public uint Offset {
+       get { return offset; }
+    }  
+
+    internal CILInstructions(MetaData md) {
+      metaData = md;
+    }
+
+    private void AddToBuffer(CILInstruction inst) {
+      if (tide >= buffer.Length) {
+        CILInstruction[] tmp = buffer;
+        buffer = new CILInstruction[tmp.Length * 2];
+        for (int i=0; i < tide; i++) {
+          buffer[i] = tmp[i];
+        }
+      }
+                        //Console.WriteLine("Adding instruction at offset " + offset + " with size " + inst.size);
+                        inst.offset = offset;
+      offset += inst.size;
+      buffer[tide++] = inst;
+    }
+
+    /// <summary>
+    /// Add a simple IL instruction
+    /// </summary>
+    /// <param name="inst">the IL instruction</param>
+    public void Inst(Op inst) {
+      AddToBuffer(new Instr((int)inst));
+    }
+
+    /// <summary>
+    /// Add an IL instruction with an integer parameter
+    /// </summary>
+    /// <param name="inst">the IL instruction</param>
+    /// <param name="val">the integer parameter value</param>
+    public void IntInst(IntOp inst, int val) {
+      int instr = (int)inst;
+      if ((inst == IntOp.ldc_i4_s) || (inst == IntOp.ldc_i4)) 
+        AddToBuffer(new IntInstr(instr,val,(inst == IntOp.ldc_i4_s)));
+      else
+        AddToBuffer(new UIntInstr(instr,val,((inst < IntOp.ldc_i4_s) ||
+                                              (inst == IntOp.unaligned))));
+    }
+
+    /// <summary>
+    /// Add the load long instruction
+    /// </summary>
+    /// <param name="cVal">the long value</param>
+    public void ldc_i8(long cVal) {
+      AddToBuffer(new LongInstr(0x21,cVal));
+    }
+
+    /// <summary>
+    /// Add the load float32 instruction
+    /// </summary>
+    /// <param name="cVal">the float value</param>
+    public void ldc_r4(float cVal) {
+      AddToBuffer(new FloatInstr(0x22,cVal));
+    }
+
+    /// <summary>
+    /// Add the load float64 instruction
+    /// </summary>
+    /// <param name="cVal">the float value</param>
+    public void ldc_r8(double cVal) {
+      AddToBuffer(new DoubleInstr(0x23,cVal));
+    }
+
+    /// <summary>
+    /// Add the load string instruction
+    /// </summary>
+    /// <param name="str">the string value</param>
+    public void ldstr(string str) {
+      AddToBuffer(new StringInstr(0x72,str));
+    }
+
+          /// <summary>
+          /// Add the load string instruction
+          /// </summary>
+          public void ldstr (byte[] str) {
+                  AddToBuffer (new StringInstr (0x72, str));
+          }
+          
+    /// <summary>
+    /// Add the calli instruction
+    /// </summary>
+    /// <param name="sig">the signature for the calli</param>
+    public void calli(CalliSig sig) {
+      AddToBuffer(new SigInstr(0x29,sig));
+    }
+
+    /// <summary>
+    /// Add a label to the CIL instructions
+    /// </summary>
+    /// <param name="lab">the label to be added</param>
+    public void CodeLabel(CILLabel lab) {
+      AddToBuffer(new LabelInstr(lab));
+    }
+
+    /// <summary>
+    /// Add an instruction with a field parameter
+    /// </summary>
+    /// <param name="inst">the CIL instruction</param>
+    /// <param name="f">the field parameter</param>
+    public void FieldInst(FieldOp inst, Field f) {
+      AddToBuffer(new FieldInstr((int)inst,f));
+    }
+
+    /// <summary>
+    /// Add an instruction with a method parameter
+    /// </summary>
+    /// <param name="inst">the CIL instruction</param>
+    /// <param name="m">the method parameter</param>
+    public void MethInst(MethodOp inst, Method m) {
+      AddToBuffer(new MethInstr((int)inst,m));
+    }
+
+    /// <summary>
+    /// Add an instruction with a type parameter
+    /// </summary>
+    /// <param name="inst">the CIL instruction</param>
+    /// <param name="t">the type argument for the CIL instruction</param>
+    public void TypeInst(TypeOp inst, Type aType) {
+      AddToBuffer(new TypeInstr((int)inst,aType,metaData));
+    }
+
+    /// <summary>
+    /// Add a branch instruction
+    /// </summary>
+    /// <param name="inst">the branch instruction</param>
+    /// <param name="lab">the label that is the target of the branch</param>
+    public void Branch(BranchOp inst,  CILLabel lab) {
+      AddToBuffer(new BranchInstr((int)inst,lab));
+    }
+
+    /// <summary>
+    /// Add a switch instruction
+    /// </summary>
+    /// <param name="labs">the target labels for the switch</param>
+    public void Switch(CILLabel[] labs) {
+      AddToBuffer(new SwitchInstr(0x45,labs));
+    }
+
+    /// <summary>
+    /// Add a byte to the CIL instructions (.emitbyte)
+    /// </summary>
+    /// <param name="bVal"></param>
+    public void emitbyte(byte bVal) { 
+      AddToBuffer(new CILByte(bVal));
+    }
+
+    /// <summary>
+    /// Add an instruction which puts an integer on TOS.  This method
+    /// selects the correct instruction based on the value of the integer.
+    /// </summary>
+    /// <param name="i">the integer value</param>
+    public void PushInt(int i) {
+      if (i == -1) {
+        AddToBuffer(new Instr((int)Op.ldc_i4_m1));
+      } else if ((i >= 0) && (i <= 8)) {
+        Op op = (Op)(Op.ldc_i4_0 + i);
+        AddToBuffer(new Instr((int)op));
+      } else if ((i >= minByteVal) && (i <= maxByteVal)) {
+        AddToBuffer(new IntInstr((int)IntOp.ldc_i4_s,i,true));
+      } else {
+        AddToBuffer(new IntInstr((int)IntOp.ldc_i4,i,false)); 
+      }
+    }
+
+    /// <summary>
+    /// Add the instruction to load a long on TOS
+    /// </summary>
+    /// <param name="l">the long value</param>
+    public void PushLong(long l) {
+      AddToBuffer(new LongInstr(0x21,l));
+    }
+
+    /// <summary>
+    /// Add an instruction to push the boolean value true on TOS
+    /// </summary>
+    public void PushTrue() {
+      AddToBuffer(new Instr((int)Op.ldc_i4_1));
+    }
+
+    /// <summary>
+    ///  Add an instruction to push the boolean value false on TOS
+    /// </summary>
+    public void PushFalse() {
+      AddToBuffer(new Instr((int)Op.ldc_i4_0));
+    }
+
+    /// <summary>
+    /// Add the instruction to load an argument on TOS.  This method
+    /// selects the correct instruction based on the value of argNo
+    /// </summary>
+    /// <param name="argNo">the number of the argument</param>
+    public void LoadArg(int argNo) {
+      if (argNo < 4) {
+        int op = (int)Op.ldarg_0 + argNo;
+        AddToBuffer(new Instr(op));
+      } else if (argNo <= maxUByteVal) {
+        AddToBuffer(new UIntInstr((int)IntOp.ldarg,argNo,true));
+      } else {
+        AddToBuffer(new UIntInstr(0x09,argNo,false)); 
+      }
+   }
+
+    /// <summary>
+    /// Add the instruction to load the address of an argument on TOS.
+    /// This method selects the correct instruction based on the value
+    /// of argNo.
+    /// </summary>
+    /// <param name="argNo">the number of the argument</param>
+    public void LoadArgAdr(int argNo) {
+      if (argNo <= maxUByteVal) {
+        AddToBuffer(new UIntInstr((int)IntOp.ldarga,argNo,true));
+      } else {
+        AddToBuffer(new UIntInstr(0x0A,argNo,false)); 
+      }
+    }
+
+    /// <summary>
+    /// Add the instruction to load a local on TOS.  This method selects
+    /// the correct instruction based on the value of locNo.
+    /// </summary>
+    /// <param name="locNo">the number of the local to load</param>
+    public void LoadLocal(int locNo) {
+      if (locNo < 4) {
+        int op = (int)Op.ldloc_0 + locNo;
+        AddToBuffer(new Instr(op));
+      } else if (locNo <= maxUByteVal) {
+        AddToBuffer(new UIntInstr((int)IntOp.ldloc,locNo,true));
+      } else {
+        AddToBuffer(new UIntInstr(0x0C,locNo,false)); 
+      }
+    }
+
+    /// <summary>
+    /// Add the instruction to load the address of a local on TOS.
+    /// This method selects the correct instruction based on the 
+    /// value of locNo.
+    /// </summary>
+    /// <param name="locNo">the number of the local</param>
+    public void LoadLocalAdr(int locNo) {
+      if (locNo <= maxUByteVal) {
+        AddToBuffer(new UIntInstr((int)IntOp.ldloca,locNo,true));
+      } else {
+        AddToBuffer(new UIntInstr(0x0D,locNo,false)); 
+      }
+    }
+
+    /// <summary>
+    /// Add the instruction to store to an argument.  This method
+    /// selects the correct instruction based on the value of argNo.
+    /// </summary>
+    /// <param name="argNo">the argument to be stored to</param>
+    public void StoreArg(int argNo) {
+      if (argNo <= maxUByteVal) {
+        AddToBuffer(new UIntInstr((int)IntOp.starg,argNo,true));
+      } else {
+        AddToBuffer(new UIntInstr(0x0B,argNo,false)); 
+      }
+    }
+
+    /// <summary>
+    /// Add the instruction to store to a local.  This method selects
+    /// the correct instruction based on the value of locNo.
+    /// </summary>
+    /// <param name="locNo">the local to be stored to</param>
+    public void StoreLocal(int locNo) {
+      if (locNo < 4) {
+        int op = (int)Op.stloc_0 + locNo;
+        AddToBuffer(new Instr(op));
+      } else if (locNo <= maxUByteVal) {
+        AddToBuffer(new UIntInstr((int)IntOp.stloc,locNo,true));
+      } else {
+        AddToBuffer(new UIntInstr(0x0E,locNo,false)); 
+      }
+    }
+
+    /// <summary>
+    /// Create a new CIL label.  To place the label in the CIL instruction
+    /// stream use CodeLabel.
+    /// </summary>
+    /// <returns>a new CIL label</returns>
+    public CILLabel NewLabel() {
+      return new CILLabel();
+    }
+
+    public void AddTryBlock(TryBlock tryBlock) {
+      if (exceptions == null) 
+        exceptions = new ArrayList();
+      else if (exceptions.Contains(tryBlock)) return;
+      exceptions.Add(tryBlock);
+    }
+
+    /// <summary>
+    /// Create a new label at this position in the code buffer
+    /// </summary>
+    /// <returns>the label at the current position</returns>
+    public CILLabel NewCodedLabel() {
+      CILLabel lab = new CILLabel();
+      AddToBuffer(new LabelInstr(lab));
+      return lab;
+    }
+
+    /// <summary>
+    /// Mark this position as the start of a new block
+    /// (try, catch, filter, finally or fault)
+    /// </summary>
+    public void StartBlock() {
+      if (blockStack == null) blockStack = new ArrayList();
+      blockStack.Insert(0,NewCodedLabel());
+    }
+
+    /// <summary>
+    /// Mark this position as the end of the last started block and
+    /// make it a try block.  This try block is added to the current 
+    /// instructions (ie do not need to call AddTryBlock)
+    /// </summary>
+    /// <returns>The try block just ended</returns>
+    public TryBlock EndTryBlock() {
+      TryBlock tBlock = new TryBlock((CILLabel)blockStack[0],NewCodedLabel());
+      blockStack.RemoveAt(0);
+      AddTryBlock(tBlock);
+      return tBlock;
+    }
+
+    /// <summary>
+    /// Mark this position as the end of the last started block and
+    /// make it a catch block.  This catch block is associated with the
+    /// specified try block.
+    /// </summary>
+    /// <param name="exceptType">the exception type to be caught</param>
+    /// <param name="tryBlock">the try block associated with this catch block</param>
+    public void EndCatchBlock(Class exceptType, TryBlock tryBlock) {
+      Catch catchBlock = new Catch(exceptType,(CILLabel)blockStack[0],
+        NewCodedLabel());
+      tryBlock.AddHandler(catchBlock);
+    }
+
+    /// <summary>
+    /// Mark this position as the end of the last started block and
+    /// make it a filter block.  This filter block is associated with the
+    /// specified try block.
+    /// </summary>
+    /// <param name="filterLab">the label where the filter code is</param>
+    /// <param name="tryBlock">the try block associated with this filter block</param>
+    public void EndFilterBlock(CILLabel filterLab, TryBlock tryBlock) {
+      Filter filBlock = new Filter(filterLab,(CILLabel)blockStack[0],NewCodedLabel());
+      tryBlock.AddHandler(filBlock);
+    }
+
+    /// <summary>
+    /// Mark this position as the end of the last started block and
+    /// make it a finally block.  This finally block is associated with the
+    /// specified try block.
+    /// </summary>
+    /// <param name="tryBlock">the try block associated with this finally block</param>
+    public void EndFinallyBlock(TryBlock tryBlock) {
+      Finally finBlock= new Finally((CILLabel)blockStack[0],NewCodedLabel());
+      tryBlock.AddHandler(finBlock);
+    }
+
+    /// <summary>
+    /// Mark this position as the end of the last started block and
+    /// make it a fault block.  This fault block is associated with the
+    /// specified try block.
+    /// </summary>
+    /// <param name="tryBlock">the try block associated with this fault block</param>
+    public void EndFaultBlock(TryBlock tryBlock) {
+      Fault fBlock= new Fault((CILLabel)blockStack[0],NewCodedLabel());
+      tryBlock.AddHandler(fBlock);
+    }
+
+    internal uint GetCodeSize() {
+      return codeSize + paddingNeeded + exceptSize;
+    }
+
+    internal void CheckCode(uint locSigIx, bool initLocals, int maxStack) {
+      if (tide == 0) return;
+      bool changed = true;
+      while (changed) {
+        changed = false;
+        for (int i=0; i < tide; i++) {
+          changed = buffer[i].Check(metaData) || changed;
+        }
+        if (changed) {
+          for (int i=1; i < tide; i++) {
+            buffer[i].offset = buffer[i-1].offset + buffer[i-1].size;
+          }
+          offset = buffer[tide-1].offset + buffer[tide-1].size;
+        }
+      }
+                        codeSize = offset;
+                        // Console.WriteLine("codeSize before header added = " + codeSize);
+      if ((offset < smallSize) && (maxStack <= 8) && (locSigIx == 0) && (exceptions == null)) {
+        // can use tiny header
+        //Console.WriteLine("Tiny Header");
+        tinyFormat = true;
+        headerFlags = (ushort)(TinyFormat | ((ushort)codeSize << 2));
+        codeSize++;
+        if ((codeSize % 4) != 0) { paddingNeeded = 4 - (codeSize % 4); }
+      } else {
+        //Console.WriteLine("Fat Header");
+        tinyFormat = false;
+        localSigIx = locSigIx;
+        this.maxStack = (short)maxStack;
+        headerFlags = FatFormat;
+        if (exceptions != null) {
+          // Console.WriteLine("Got exceptions");
+          headerFlags |= MoreSects;
+          uint numExceptClauses = 0;
+          for (int i=0; i < exceptions.Count; i++) {
+            TryBlock tryBlock = (TryBlock)exceptions[i];
+            tryBlock.SetSize();
+            numExceptClauses += (uint)tryBlock.NumHandlers();
+            if (tryBlock.isFat()) fatExceptionFormat = true;
+          }
+
+          uint data_size = ExHeaderSize + numExceptClauses *
+                 (fatExceptionFormat ? FatExClauseSize : SmlExClauseSize);
+
+          if (data_size > 256)
+                  fatExceptionFormat = true;
+                  
+          // Console.WriteLine("numexceptclauses = " + numExceptClauses);
+          if (fatExceptionFormat) {
+            // Console.WriteLine("Fat exception format");
+            exceptHeader = FatExceptTable;
+            exceptSize = ExHeaderSize + numExceptClauses * FatExClauseSize;
+          } else {
+            // Console.WriteLine("Tiny exception format");
+            exceptHeader = SmlExceptTable;
+            exceptSize = ExHeaderSize + numExceptClauses * SmlExClauseSize;
+          }
+          // Console.WriteLine("exceptSize = " + exceptSize);
+        }
+        if (initLocals) headerFlags |= InitLocals;
+        if ((offset % 4) != 0) { paddingNeeded = 4 - (offset % 4); }
+        codeSize += FatSize;
+      }
+                  // Console.WriteLine("codeSize = " + codeSize + "  headerFlags = " + 
+      //                   Hex.Short(headerFlags));
+    }
+
+                internal void Write(FileImage output) {
+      // Console.WriteLine("Writing header flags = " + Hex.Short(headerFlags));
+                        if (tinyFormat) {
+        // Console.WriteLine("Writing tiny code");
+                                output.Write((byte)headerFlags);
+                        } else {
+        // Console.WriteLine("Writing fat code");
+                                output.Write(headerFlags);
+                                output.Write((ushort)maxStack);
+                                output.Write(offset);
+                                output.Write(localSigIx);
+                        }
+      // Console.WriteLine(Hex.Int(tide) + " CIL instructions");
+      // Console.WriteLine("starting instructions at " + output.Seek(0,SeekOrigin.Current));
+                        for (int i=0; i < tide; i++) {
+                                buffer[i].Write(output);
+                        }
+      // Console.WriteLine("ending instructions at " + output.Seek(0,SeekOrigin.Current));
+      for (int i=0; i < paddingNeeded; i++) { output.Write((byte)0); }
+      if (exceptions != null) {
+        // Console.WriteLine("Writing exceptions");
+        // Console.WriteLine("header = " + Hex.Short(exceptHeader) + " exceptSize = " + Hex.Int(exceptSize));
+        output.Write(exceptHeader);
+        output.Write3Bytes((uint)exceptSize);
+        for (int i=0; i < exceptions.Count; i++) {
+          TryBlock tryBlock = (TryBlock)exceptions[i];
+          tryBlock.Write(output,fatExceptionFormat);
+        }
+      }
+                }
+
+  }
+  /**************************************************************************/  
+        /// <summary>
+        /// A label in the IL
+        /// </summary>
+        public class CILLabel
+        {
+    CILInstruction branch;
+    CILInstruction[] multipleBranches;
+    int tide = 0;
+    CILInstruction labInstr;
+    uint offset = 0;
+    public CILLabel (uint offset) {
+        this.offset = offset;
+        }
+        
+
+    internal CILLabel() {
+    }
+
+    internal void AddBranch(CILInstruction instr) {
+      if (branch == null) {
+        branch = instr;
+        return;
+      }
+      if (multipleBranches == null) {
+        multipleBranches = new CILInstruction[2];
+      } else if (tide >= multipleBranches.Length) {
+        CILInstruction[] tmp = multipleBranches;
+        multipleBranches = new CILInstruction[tmp.Length*2];
+        for (int i=0; i < tide; i++) {
+          multipleBranches[i] = tmp[i];
+        }
+      }
+      multipleBranches[tide++] = instr;
+    }
+
+    internal void AddLabelInstr(LabelInstr lInstr) {
+      labInstr = lInstr;
+    }
+
+    internal uint GetLabelOffset() {
+      if (labInstr == null) return 0;
+      return labInstr.offset + offset;
+    }
+
+        }
+  /**************************************************************************/  
+  public abstract class CodeBlock {
+
+    private static readonly int maxCodeSize = 256;
+    protected CILLabel start, end;
+    protected bool small = true;
+
+    public CodeBlock(CILLabel start, CILLabel end) {
+      this.start = start;
+      this.end = end;
+    }
+
+    internal virtual bool isFat() {
+      // Console.WriteLine("block start = " + start.GetLabelOffset() +
+      //                  "  block end = " + end.GetLabelOffset());
+      return (end.GetLabelOffset() - start.GetLabelOffset()) > maxCodeSize;
+    }
+
+    internal virtual void Write(FileImage output, bool fatFormat) {
+      if (fatFormat) output.Write(start.GetLabelOffset());
+      else output.Write((short)start.GetLabelOffset());
+      uint len = end.GetLabelOffset() - start.GetLabelOffset();
+      if (fatFormat) output.Write(len);
+      else output.Write((byte)len);
+    }
+
+  }
+
+  /// <summary>
+  /// The descriptor for a guarded block (.try)
+  /// </summary>
+  public class TryBlock : CodeBlock {
+    protected bool fatFormat = false;
+    protected int flags = 0;
+    ArrayList handlers = new ArrayList();
+
+    /// <summary>
+    /// Create a new try block
+    /// </summary>
+    /// <param name="start">start label for the try block</param>
+    /// <param name="end">end label for the try block</param>
+    public TryBlock(CILLabel start, CILLabel end) : base(start,end) { }
+
+    /// <summary>
+    /// Add a handler to this try block
+    /// </summary>
+    /// <param name="handler">a handler to be added to the try block</param>
+    public void AddHandler(HandlerBlock handler) {
+      flags = handler.GetFlag();
+      handlers.Add(handler);
+    }
+
+    internal void SetSize() {
+      fatFormat = base.isFat();
+      if (fatFormat) return;
+      for (int i=0; i < handlers.Count; i++) {
+        HandlerBlock handler = (HandlerBlock)handlers[i];
+        if (handler.isFat()) {
+          fatFormat = true;
+          return;
+        }
+      }
+    }
+
+    internal int NumHandlers() {
+      return handlers.Count;
+  }
+
+    internal override bool isFat() {
+      return fatFormat;
+    }
+
+    internal override void Write(FileImage output, bool fatFormat) {
+      // Console.WriteLine("writing exception details");
+      for (int i=0; i < handlers.Count; i++) {
+        // Console.WriteLine("Except block " + i);
+        HandlerBlock handler = (HandlerBlock)handlers[i];
+        if (fatFormat) output.Write(flags);
+        else output.Write((short)flags);
+        // Console.WriteLine("flags = " + Hex.Short(flags));
+        base.Write(output,fatFormat);
+        handler.Write(output,fatFormat);
+      }
+    }
+  }
+
+  public abstract class HandlerBlock : CodeBlock 
+  {
+    protected static readonly short ExceptionFlag = 0;
+    protected static readonly short FilterFlag = 0x01;
+    protected static readonly short FinallyFlag = 0x02;
+    protected static readonly short FaultFlag = 0x04;
+
+    public HandlerBlock(CILLabel start, CILLabel end) : base(start,end) { }
+
+    internal virtual short GetFlag() { return ExceptionFlag; }
+
+    internal override void Write(FileImage output, bool fatFormat) {
+      base.Write(output,fatFormat);
+    }
+
+  }
+
+  /// <summary>
+  /// The descriptor for a catch clause (.catch)
+  /// </summary>
+  public class Catch : HandlerBlock 
+  {
+    Class exceptType;
+    
+    /// <summary>
+    /// Create a new catch clause
+    /// </summary>
+    /// <param name="except">the exception to be caught</param>
+    /// <param name="handlerStart">start of the handler code</param>
+    /// <param name="handlerEnd">end of the handler code</param>
+    public Catch(Class except, CILLabel handlerStart, CILLabel handlerEnd) 
+                                            : base(handlerStart,handlerEnd) {
+      exceptType = except;
+    }
+
+    internal override void Write(FileImage output, bool fatFormat) {
+      base.Write(output,fatFormat);
+      output.Write(exceptType.Token());
+    }
+  }
+
+  /// <summary>
+  /// The descriptor for a filter clause (.filter)
+  /// </summary>
+  public class Filter : HandlerBlock 
+  {
+    CILLabel filterLabel;
+
+    /// <summary>
+    /// Create a new filter clause
+    /// </summary>
+    /// <param name="filterLabel">the label where the filter code starts</param>
+    /// <param name="handlerStart">the start of the handler code</param>
+    /// <param name="handlerEnd">the end of the handler code</param>
+    public Filter(CILLabel filterLabel, CILLabel handlerStart, 
+                        CILLabel handlerEnd) : base(handlerStart,handlerEnd) {
+      this.filterLabel = filterLabel;
+    }
+
+    internal override short GetFlag() { 
+      return FilterFlag; 
+    }
+
+    internal override void Write(FileImage output, bool fatFormat) {
+      base.Write(output,fatFormat);
+      output.Write(filterLabel.GetLabelOffset());
+    }
+
+  }
+
+  /// <summary>
+  /// Descriptor for a finally block (.finally)
+  /// </summary>
+  public class Finally : HandlerBlock 
+  {
+    /// <summary>
+    /// Create a new finally clause
+    /// </summary>
+    /// <param name="finallyStart">start of finally code</param>
+    /// <param name="finallyEnd">end of finally code</param>
+    public Finally(CILLabel finallyStart, CILLabel finallyEnd)
+      : base(finallyStart,finallyEnd) { }
+
+    internal override short GetFlag() { 
+      return FinallyFlag; 
+    }
+
+    internal override void Write(FileImage output, bool fatFormat) {
+      base.Write(output,fatFormat);
+      output.Write((int)0);
+    }
+
+  }
+
+  /// <summary>
+  /// Descriptor for a fault block (.fault)
+  /// </summary>
+  public class Fault : HandlerBlock 
+  {
+    /// <summary>
+    /// Create a new fault clause
+    /// </summary>
+    /// <param name="faultStart">start of the fault code</param>
+    /// <param name="faultEnd">end of the fault code</param>
+    public Fault(CILLabel faultStart, CILLabel faultEnd)
+                                              : base(faultStart,faultEnd) { }
+
+    internal override short GetFlag() { 
+      return FaultFlag; 
+    }
+
+    internal override void Write(FileImage output, bool fatFormat) {
+      base.Write(output,fatFormat);
+      output.Write((int)0);
+      
+    }
+  }
+
+  /**************************************************************************/  
+  /// <summary>
+        /// The base descriptor for a class 
+        /// </summary>
+        public abstract class Class : Type
+        {
+    protected int row = 0;
+    public string name, nameSpace;
+    protected uint nameIx, nameSpaceIx;
+                protected MetaData _metaData;
+                internal Class(string nameSpaceName, string className, MetaData md)
+                                                              : base(PrimitiveType.Class.GetTypeIndex ()) {
+      nameSpace = nameSpaceName;
+      name = className;
+      nameIx = md.AddToStringsHeap(name);
+      nameSpaceIx = md.AddToStringsHeap(nameSpace);
+      _metaData = md;
+    }
+
+    internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ()) {
+      nameSpaceIx = nsIx;
+      nameIx = nIx;
+    }
+
+    internal virtual uint TypeDefOrRefToken() { return 0; }
+
+    internal virtual void MakeValueClass(ValueClass vClass) {
+      typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
+    }
+        
+    internal virtual string TypeName() {
+      return (nameSpace + "." + name);
+    }
+
+    internal override MetaDataElement GetTypeSpec(MetaData md) {
+      return this;
+    }
+        }
+  /**************************************************************************/  
+  // This Class produces entries in the TypeDef table of the MetaData 
+  // in the PE meta data.
+
+  // NOTE:  Entry 0 in TypeDef table is always the pseudo class <module> 
+  // which is the parent for functions and variables declared a module level
+
+  /// <summary>
+        /// The descriptor for a class defined in the IL (.class) in the current assembly/module
+        /// </summary>
+        /// 
+        public class ClassDef : Class
+        {
+    private static readonly uint HasSecurity = 0x00040000;
+    private static readonly byte ElementType_Class = 0x12;
+
+    Class superType;
+    ArrayList fields = new ArrayList();
+    ArrayList methods = new ArrayList();
+    ArrayList events;
+    ArrayList properties;
+    bool typeIndexChecked = true;
+    uint fieldIx = 0, methodIx = 0;
+    byte[] securityActions;
+    uint flags;
+    ClassLayout layout;
+    ClassDef parentClass;
+    MetaData metaData;
+    
+    internal ClassDef(TypeAttr attrSet, string nsName, string name, 
+                      MetaData md) : base(nsName, name, md) {
+                        metaData = md;
+      superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
+      flags = (uint)attrSet;
+      tabIx = MDTable.TypeDef;
+    }
+
+    internal void SetSuper(Class sClass) {
+      superType = sClass;
+      if (sClass is ClassRef)
+        typeIndex = superType.GetTypeIndex();
+      else
+        typeIndexChecked = false;
+    }
+
+    internal override void MakeValueClass(ValueClass vClass) {
+      if (vClass == ValueClass.Enum)  
+        superType = metaData.mscorlib.EnumType();
+      else  
+        superType = metaData.mscorlib.ValueType();
+
+      typeIndex = superType.GetTypeIndex();
+    }
+
+    public void SpecialNoSuper() {
+      superType = null;
+    }
+
+    /// <summary>
+    /// Add an attribute to this class
+    /// </summary>
+    /// <param name="ta">the attribute to be added</param>
+    public void AddAttribute(TypeAttr ta) { 
+      flags |= (uint)ta;
+    }
+
+    /// <summary>
+    /// Add an interface that is implemented by this class
+    /// </summary>
+    /// <param name="iFace">the interface that is implemented</param>
+    public void AddImplementedInterface(Class iFace) {
+      metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
+    }
+
+    /// <summary>
+    ///  Add a named generic type parameter
+    /// </summary>
+    public GenericParameter AddGenericParameter (short index, string name) {
+            GenericParameter gp = new GenericParameter (this, metaData, index, name);
+            metaData.AddToTable (MDTable.GenericParam, gp);
+            return gp;
+    }
+
+    /// <summary>
+    /// Add a field to this class
+    /// </summary>
+    /// <param name="name">field name</param>
+    /// <param name="fType">field type</param>
+    /// <returns>a descriptor for this new field</returns>
+    public FieldDef AddField(string name, Type fType) {
+      FieldDef field = new FieldDef(name,fType);
+      fields.Add(field);
+      return field;
+    }
+
+    /// <summary>
+    /// Add a field to this class
+    /// </summary>
+    /// <param name="fAtts">attributes for this field</param>
+    /// <param name="name">field name</param>
+    /// <param name="fType">field type</param>
+    /// <returns>a descriptor for this new field</returns>
+    public FieldDef AddField(FieldAttr fAtts, string name, Type fType) {
+      FieldDef field = new FieldDef(fAtts,name,fType);
+      fields.Add(field);
+      return field;
+    }
+
+    public void SetFieldOrder (ArrayList fields)
+    {
+            this.fields = fields;
+    }
+
+    /// <summary>
+    /// Add a method to this class
+    /// </summary>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">parameters</param>
+    /// <returns>a descriptor for this new method</returns>
+    public MethodDef AddMethod(string name, Type retType, Param[] pars) {
+      // Console.WriteLine("Adding method " + name + " to class " + this.name);
+      MethodDef meth = new MethodDef(metaData,name,retType, pars);
+      methods.Add(meth);
+      return meth;
+    }
+
+    /// <summary>
+    /// Add a method to this class
+    /// </summary>
+    /// <param name="mAtts">attributes for this method</param>
+    /// <param name="iAtts">implementation attributes for this method</param>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">parameters</param>
+    /// <returns>a descriptor for this new method</returns>
+    public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, 
+                               Type retType, Param[] pars) {
+      // Console.WriteLine("Adding method " + name + " to class " + this.name);
+      MethodDef meth = new MethodDef(metaData,mAtts,iAtts,name,retType,pars);
+      methods.Add(meth);
+      return meth;
+    }
+
+    /// <summary>
+    /// Add an event to this class
+    /// </summary>
+    /// <param name="name">event name</param>
+    /// <param name="eType">event type</param>
+    /// <returns>a descriptor for this new event</returns>
+    public Event AddEvent(string name, Type eType) {
+      Event e = new Event(name,eType,this);
+      if (events == null) events = new ArrayList();
+      events.Add(e);
+      return e;
+    }
+
+    /// <summary>
+    /// Add a property to this class
+    /// </summary>
+    /// <param name="name">property name</param>
+    /// <param name="propType">property type</param>
+    /// <returns>a descriptor for this new property</returns>
+    public Property AddProperty(string name, Type retType, Type[] pars) {
+      Property p = new Property(name, retType, pars, this);
+      if (properties == null) properties = new ArrayList();
+      properties.Add(p);
+      return p;
+    }
+
+
+    /// <summary>
+    /// Add a nested class to this class
+    /// </summary>
+    /// <param name="attrSet">attributes for this nested class</param>
+    /// <param name="nsName">nested name space name</param>
+    /// <param name="name">nested class name</param>
+    /// <returns>a descriptor for this new nested class</returns>
+    public ClassDef AddNestedClass(TypeAttr attrSet, string nsName, 
+                                   string name) {
+      ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
+      metaData.AddToTable(MDTable.TypeDef,nClass);
+      metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
+      nClass.parentClass = this;
+      return (nClass);
+     }
+    public static bool IsValueType (Class type)
+    {
+        return IsValueType (type.nameSpace, type.name);
+    }
+
+    public static bool IsEnum (Class type)
+    {
+        return IsEnum (type.nameSpace, type.name);
+    }
+    
+    public static bool IsValueType (string nsName, string name)
+    {
+      return ((nsName.CompareTo ("System") == 0) && 
+        (name.CompareTo ("ValueType") == 0));
+    }
+
+    public static bool IsEnum (string nsName, string name)
+    {
+      return ((nsName.CompareTo ("System") == 0) && 
+        (name.CompareTo ("Enum") == 0));
+    }
+
+    /// <summary>
+    /// Add a nested class to this class
+    /// </summary>
+    /// <param name="attrSet">attributes for this nested class</param>
+    /// <param name="nsName">nested name space name</param>
+    /// <param name="name">nested class name</param>
+    /// <param name="sType">super type of this nested class</param>
+    /// <returns>a descriptor for this new nested class</returns>
+    public ClassDef AddNestedClass(TypeAttr attrSet, string nsName, 
+                                   string name, Class sType) {
+      ClassDef nClass = AddNestedClass (attrSet, nsName, name);
+      nClass.SetSuper(sType);
+      if (ClassDef.IsValueType (sType))
+        nClass.MakeValueClass (ValueClass.ValueType);
+      else
+      if (ClassDef.IsEnum (sType))
+        nClass.MakeValueClass (ValueClass.Enum);
+      
+      if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
+        nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
+
+      return (nClass);
+    }
+
+    /// <summary>
+    /// Add layout information for this class.  This class must have the
+    /// sequential or explicit attribute.
+    /// </summary>
+    /// <param name="packSize">packing size (.pack)</param>
+    /// <param name="classSize">class size (.size)</param>
+    public void AddLayoutInfo (int packSize, int classSize) {
+      layout = new ClassLayout(packSize,classSize,this);
+    }
+
+    /// <summary>
+    /// Use a method as the implementation for another method (.override)
+    /// </summary>
+    /// <param name="decl">the method to be overridden</param>
+    /// <param name="body">the implementation to be used</param>
+    public void AddMethodOverride(Method decl, Method body) {
+      metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
+    }
+
+    /// <summary>
+    /// Add security to this class NOT YET IMPLEMENTED
+    /// </summary>
+    /// <param name="permissionSet"></param>
+    public void AddSecurity(byte[] permissionSet) {
+      throw(new NotYetImplementedException("Class security "));
+      //flags |= HasSecurity;
+     // securityActions = permissionSet;
+    }
+
+    //public void AddLineInfo(int row, int col) { }
+
+    internal void CheckTypeIndex() {
+      if (typeIndexChecked) return;
+      if (!(superType is ClassRef)) 
+        ((ClassDef)superType).CheckTypeIndex();
+      typeIndex = superType.GetTypeIndex();
+      typeIndexChecked = true;
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
+      // Console.WriteLine("Building tables for " + name);
+      if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
+      // Console.WriteLine("adding methods " + methods.Count);
+      methodIx = md.TableIndex(MDTable.Method);
+      for (int i=0; i < methods.Count; i++) {
+        md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
+        ((MethodDef)methods[i]).BuildTables(md);
+      }
+      // Console.WriteLine("adding fields");
+      fieldIx = md.TableIndex(MDTable.Field);
+      for (int i=0; i < fields.Count; i++) {
+        md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
+        ((FieldDef)fields[i]).BuildTables(md);
+      }
+      // Console.WriteLine("adding events and properties");
+      if (events != null) { 
+        for (int i=0; i < events.Count; i++) {
+          md.AddToTable(MDTable.Event,(Event)events[i]);
+          ((Event)events[i]).BuildTables(md);
+        }
+        md.AddToTable(MDTable.EventMap,
+          new MapElem(this,((Event)events[0]).Row,MDTable.Event));
+      }
+      if (properties != null) { 
+        for (int i=0; i < properties.Count; i++) {
+          md.AddToTable(MDTable.Property,(Property)properties[i]);
+          ((Property)properties[i]).BuildTables(md);
+        }
+        md.AddToTable(MDTable.PropertyMap,new MapElem(this,
+                          ((Property)properties[0]).Row,MDTable.Property));
+      }
+      // Console.WriteLine("End of building tables");
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 4 + 2 * md.StringsIndexSize() + 
+        md.CodedIndexSize(CIx.TypeDefOrRef) +
+        md.TableIndexSize(MDTable.Field) + 
+        md.TableIndexSize(MDTable.Method);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.StringsIndex(nameIx);
+      output.StringsIndex(nameSpaceIx);
+      //if (superType != null) 
+      // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
+      output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
+      output.WriteIndex(MDTable.Field,fieldIx);
+      output.WriteIndex(MDTable.Method,methodIx);
+    }
+
+    internal sealed override uint TypeDefOrRefToken() {
+      uint cIx = Row;
+      cIx = cIx << 2;
+      return cIx;
+    }
+
+    internal sealed override void TypeSig(MemoryStream sig) {
+      if (!typeIndexChecked) CheckTypeIndex();
+      sig.WriteByte(GetTypeIndex());
+      MetaData.CompressNum(TypeDefOrRefToken(),sig);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.TypeDefOrRef) : return 0; 
+        case (CIx.HasCustomAttr) : return 3; 
+        case (CIx.HasDeclSecurity) : return 0; 
+        case (CIx.TypeOrMethodDef) : return 0; 
+      }
+      return 0;
+    }
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Layout information for a class (.class [sequential | explicit])
+        /// </summary>
+        internal class ClassLayout : MetaDataElement
+        {
+    ClassDef parent;
+    ushort packSize = 0;
+    uint classSize = 0;
+
+                internal ClassLayout(int pack, int cSize, ClassDef par) {
+      packSize = (ushort)pack;
+      classSize = (uint)cSize;
+      parent = par;
+      tabIx = MDTable.ClassLayout;
+                }
+
+    internal sealed override uint Size(MetaData md) {
+      return 6 + md.TableIndexSize(MDTable.TypeDef);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(packSize);
+      output.Write(classSize);
+      output.WriteIndex(MDTable.TypeDef,parent.Row);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a class/interface declared in another module of THIS 
+        /// assembly, or in another assembly.
+        /// </summary>
+        public class ClassRef : Class
+        {
+    protected ResolutionScope parent;
+    ExternClass externClass;
+    protected MetaData metaData;
+
+                internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md) {
+      metaData = md;
+      tabIx = MDTable.TypeRef;
+    }
+
+    /// <summary>
+    /// Add a method to this class
+    /// </summary>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">parameter types</param>
+    /// <returns>a descriptor for this method</returns>
+    public MethodRef AddMethod(string name, Type retType, Type[] pars) {
+      MethodRef meth = new MethodRef(this,name,retType,pars,false,null);
+      metaData.AddToTable(MDTable.MemberRef,meth);
+      return meth;
+    }
+
+    /// <summary>
+    /// Add a method to this class
+    /// </summary>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">parameter types</param>
+    /// <returns>a descriptor for this method</returns>
+    public MethodRef AddVarArgMethod(string name, Type retType, 
+                                     Type[] pars, Type[] optPars) {
+      MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);
+      metaData.AddToTable(MDTable.MemberRef,meth);
+      return meth;
+    }
+
+    /// <summary>
+    /// Add a field to this class
+    /// </summary>
+    /// <param name="name">field name</param>
+    /// <param name="fType">field type</param>
+    /// <returns>a descriptor for this field</returns>
+    public FieldRef AddField(string name, Type fType) {
+      FieldRef field = new FieldRef(this,name,fType);
+      metaData.AddToTable(MDTable.MemberRef,field);
+      return field;
+    }
+
+    internal void SetParent(ResolutionScope par) {
+      parent = par;
+    }
+
+    internal override string TypeName() {
+      if ((parent != null) && (parent is AssemblyRef))
+        return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
+      else 
+        return (nameSpace + name);
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.CodedIndexSize(CIx.ResolutionScope) + 2 * 
+             md.StringsIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteCodedIndex(CIx.ResolutionScope,parent);
+      output.StringsIndex(nameIx);
+      output.StringsIndex(nameSpaceIx);
+    }
+
+    internal override sealed uint TypeDefOrRefToken() {
+      uint cIx = Row;
+      cIx = (cIx << 2) | 0x1;
+      return cIx;
+    }
+
+    internal override void TypeSig(MemoryStream sig) {
+      sig.WriteByte(GetTypeIndex());
+      MetaData.CompressNum(TypeDefOrRefToken(),sig);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.TypeDefOrRef) : return 1; 
+        case (CIx.HasCustomAttr) : return 2; 
+        case (CIx.MemberRefParent) : return 1; 
+        case (CIx.ResolutionScope) : return 3; 
+      }
+      return 0;
+    }
+        }
+  /**************************************************************************/  
+
+  public class ExternClassRef : ClassRef {
+
+    ExternClass externClass;
+
+    internal ExternClassRef(TypeAttr attrs, string nsName, string name,
+                          FileRef declFile, MetaData md) : base(nsName,name,md) {
+      externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declFile);
+      metaData.AddToTable(MDTable.ExportedType,externClass);
+    }
+
+    internal ExternClassRef(string name, MetaData md) : base(null,name,md) {
+    }
+
+    public ClassRef AddNestedClass(TypeAttr attrs, string name) {
+      ExternClassRef nestedClass = new ExternClassRef(name,metaData);
+      externClass = new ExternClass(attrs,0,nameIx,this.externClass);
+      metaData.AddToTable(MDTable.ExportedType,externClass);
+      return nestedClass;
+    }
+  }
+  /**************************************************************************/  
+  /// <summary>
+  /// Descriptor for a constant value
+  /// </summary>
+  public abstract class Constant {
+    protected uint size = 0;
+    protected Type type;
+    protected uint blobIndex;
+    protected bool addedToBlobHeap = false;
+
+                internal Constant()     {       }
+
+    internal virtual uint GetBlobIndex(MetaData md) { return 0; }
+
+    internal uint GetSize() { return size; }
+
+    internal byte GetTypeIndex() { return type.GetTypeIndex(); }
+
+    internal virtual void Write(BinaryWriter bw) {  }
+
+        }
+  /// <summary>
+  /// Descriptor for a constant value
+  /// </summary>
+  public abstract class DataConstant : Constant {
+    private uint dataOffset = 0;
+
+    internal DataConstant() { }
+
+    public uint DataOffset {
+      get { return dataOffset; }
+      set { dataOffset = value; }
+    }
+
+  }
+
+  /// <summary>
+  /// Boolean constant
+  /// </summary>
+  public class BoolConst : Constant {
+    bool val;
+
+    /// <summary>
+    /// Create a new boolean constant with the value "val"
+    /// </summary>
+    /// <param name="val">value of this boolean constant</param>
+    public BoolConst(bool val) {
+      this.val = val;
+      size = 1;
+      type = PrimitiveType.Boolean;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
+        else blobIndex = md.AddToBlobHeap((sbyte)0);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      if (val) bw.Write((sbyte)1);
+      else bw.Write((sbyte)0);
+    }
+
+  }
+
+  public class ByteArrConst : DataConstant {
+    byte[] val;
+
+    public ByteArrConst(byte[] val) {
+      type = PrimitiveType.String;
+      this.val = val;
+      size = (uint)val.Length;
+    }
+
+    public Type Type {
+            get { return type; }
+            set { type = value; }
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        blobIndex = md.AddToBlobHeap(val);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      bw.Write(val);
+    }
+
+  }
+
+  public class CharConst : Constant {
+    char val;
+
+    public CharConst(char val) {
+      this.val = val;
+      size = 2;
+      type = PrimitiveType.Char;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        blobIndex = md.AddToBlobHeap(val);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      bw.Write(val);
+    }
+
+  }
+
+  public class FloatConst : DataConstant {
+    float val;
+
+    public FloatConst(float val) {
+      this.val = val;
+      size = 4;
+      type = PrimitiveType.Float32;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        blobIndex = md.AddToBlobHeap(val);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      bw.Write(val);
+    }
+
+  }
+
+  public class DoubleConst : DataConstant {
+    double val;
+
+    public DoubleConst(double val) {
+      this.val = val;
+      size = 8;
+      type = PrimitiveType.Float64;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        blobIndex = md.AddToBlobHeap(val);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      bw.Write(val);
+    }
+
+  }
+
+  public class IntConst : DataConstant {
+    long val;
+
+    public IntConst(sbyte val) {
+      this.val = val;
+      size = 1;
+      type = PrimitiveType.Int8;
+    }
+
+    public IntConst(short val) {
+      this.val = val;
+      size = 2;
+      type = PrimitiveType.Int16;
+    }
+
+    public IntConst(int val) {
+      this.val = val;
+      size = 4;
+      type = PrimitiveType.Int32;
+    }
+
+    public IntConst(long val) {
+      this.val = val;
+      size = 8;
+      type = PrimitiveType.Int64;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        switch (size) {
+          case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
+          case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
+          case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
+          default : blobIndex = md.AddToBlobHeap(val); break; 
+        }
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      switch (size) {
+        case (1) : bw.Write((sbyte)val); break;
+        case (2) : bw.Write((short)val); break;
+        case (4) : bw.Write((int)val); break;
+        default : bw.Write(val); break; 
+      }
+    }
+
+  }
+
+  public class UIntConst : Constant {
+    long val;
+
+    public UIntConst(sbyte val) {
+      this.val = val;
+      size = 1;
+      type = PrimitiveType.UInt8;
+    }
+    public UIntConst(short val) {
+      this.val = val;
+      size = 2;
+      type = PrimitiveType.UInt16;
+    }
+    public UIntConst(int val) {
+      this.val = val;
+      size = 4;
+      type = PrimitiveType.UInt32;
+    }
+    public UIntConst(long val) {
+      this.val = val;
+      size = 8;
+      type = PrimitiveType.UInt64;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        switch (size) {
+          case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
+          case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
+          case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
+          default : blobIndex = md.AddToBlobHeap(val); break;
+        }
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      switch (size) {
+        case (1) : bw.Write((sbyte)val); break;
+        case (2) : bw.Write((short)val); break;
+        case (4) : bw.Write((int)val); break;
+        default : bw.Write(val); break;
+      }
+    }
+
+  }
+
+  public class StringConst : DataConstant {
+    string val;
+
+    public StringConst(string val) {
+      this.val = val;
+      size = (uint)val.Length;  // need to add null ??
+      type = PrimitiveType.String;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        byte [] b = Encoding.Unicode.GetBytes (val);
+        blobIndex = md.AddToBlobHeap(b);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      bw.Write(val);
+    }
+
+  }
+
+  public class NullConst : Constant {
+    public NullConst() { 
+      size = 4;
+      type = PrimitiveType.Class;
+    }
+
+    internal sealed override uint GetBlobIndex(MetaData md) {
+      if (!addedToBlobHeap) {
+        blobIndex = md.AddToBlobHeap((int)0);
+        addedToBlobHeap = true;
+      }
+      return blobIndex;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      bw.Write((int)0); 
+    }
+
+  }
+
+  public class AddressConstant : DataConstant {
+    DataConstant data;
+
+    public AddressConstant(DataConstant dConst) {
+      data = dConst;
+      size = 4;
+      type = PrimitiveType.TypedRef;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      ((FileImage)bw).WriteDataRVA(data.DataOffset);
+    }
+
+  }
+
+  public class RepeatedConstant : DataConstant {
+    DataConstant data;
+    uint repCount;
+
+    public RepeatedConstant(DataConstant dConst, int repeatCount) {
+      data = dConst;
+      repCount = (uint)repeatCount;
+      int[] sizes = new int[1];
+      sizes[0] = repeatCount;
+      type = new BoundArray(type,1,sizes);
+      size = data.GetSize() * repCount;
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      for (int i=0; i < repCount; i++) {
+        data.Write(bw);
+      }
+    }
+
+  }
+
+  public class ArrayConstant : DataConstant {
+    DataConstant[] dataVals;
+
+    public ArrayConstant(DataConstant[] dVals) {
+      dataVals = dVals;
+      for (int i=0; i < dataVals.Length; i++) {
+        size += dataVals[i].GetSize();
+      }
+    }
+
+    internal sealed override void Write(BinaryWriter bw) {
+      for (int i=0; i < dataVals.Length; i++) {
+        dataVals[i].Write(bw);
+      }
+    }
+
+  }
+
+  public class ClassType : Constant {
+    string name;
+    Class desc;
+
+    public ClassType(string className) {
+      name = className;
+      type = PrimitiveType.ClassType;
+    }
+
+    public ClassType(Class classDesc) {
+      desc = classDesc;
+      type = PrimitiveType.ClassType;
+    }
+
+    internal override void Write(BinaryWriter bw) {
+      if (name == null)  name = desc.TypeName();
+      bw.Write(name);
+    }
+
+  }
+
+
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Summary description for ConstantElem.
+        /// </summary>
+        internal class ConstantElem : MetaDataElement
+        {
+    MetaDataElement parent;
+    Constant cValue;
+    uint valIx = 0;
+
+                internal ConstantElem(MetaDataElement parent, Constant val) {
+      this.parent = parent;
+      cValue = val;
+                        tabIx = MDTable.Constant;
+                        sortTable = true;
+                }
+
+   internal override uint SortKey() 
+   {  
+     return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasConst]) 
+             | parent.GetCodedIx(CIx.HasConst);
+   }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      valIx = cValue.GetBlobIndex(md);
+      done = true;
+    }
+
+    internal void AddToBlob(BinaryWriter bw) {
+      cValue.Write(bw);
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(cValue.GetTypeIndex());
+      output.Write((byte)0);
+      output.WriteCodedIndex(CIx.HasConst,parent);
+      output.BlobIndex(valIx);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a Custom Attribute (.custom) 
+        /// </summary>
+
+        public class CustomAttribute : MetaDataElement
+        {
+    private static readonly ushort prolog = 0x0001;
+    MetaDataElement parent;
+    Method type;
+    uint valIx;
+    Constant cVal;
+    byte[] byteVal;
+    ushort numNamed = 0;
+    ArrayList names, vals;
+
+                internal CustomAttribute(MetaDataElement paren, Method constrType, 
+                                                          Constant val) {
+      parent = paren;
+      type = constrType;
+      cVal = val;
+      tabIx = MDTable.CustomAttribute;
+                }
+
+    internal CustomAttribute(MetaDataElement paren, Method constrType,
+                                                          byte[] val) {
+      parent = paren;
+      type = constrType;
+      tabIx = MDTable.CustomAttribute;
+      byteVal = val;
+    }
+
+    internal override uint SortKey() {
+      return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
+              | parent.GetCodedIx(CIx.HasCustomAttr);
+    }
+
+    public void AddFieldOrProp(string name, Constant val) {
+      if (numNamed == 0) {
+        names = new ArrayList();
+        vals = new ArrayList();
+      }
+      names.Add(name);
+      vals.Add(val);
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      BinaryWriter bw = new BinaryWriter(new MemoryStream());
+      bw.Write(byteVal);
+      md.AddToTable(MDTable.CustomAttribute, this);
+      MemoryStream str = (MemoryStream)bw.BaseStream;
+      valIx = md.AddToBlobHeap(str.ToArray());
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteCodedIndex(CIx.HasCustomAttr,parent);
+      output.WriteCodedIndex(CIx.CustomAttributeType,type);
+      output.BlobIndex(valIx);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a custom modifier of a type (modopt or modreq)
+        /// </summary>
+
+        public class CustomModifiedType : Type
+        {
+    Type type;
+    Class cmodType;
+
+    /// <summary>
+    /// Create a new custom modifier for a type
+    /// </summary>
+    /// <param name="type">the type to be modified</param>
+    /// <param name="cmod">the modifier</param>
+    /// <param name="cmodType">the type reference to be associated with the type</param>
+                public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
+                                                          : base((byte)cmod) {
+      this.type = type;
+      this.cmodType = cmodType;
+                }
+
+    internal sealed override void TypeSig(MemoryStream str) {
+      str.WriteByte(typeIndex);
+      MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
+      type.TypeSig(str);
+    }
+  
+  }
+  /**************************************************************************/  
+  /// <summary>
+  /// Descriptor for security permissions for a class or a method NOT YET IMPLEMENTED
+  /// </summary>
+        
+        public class DeclSecurity : MetaDataElement
+        {
+    ushort action;
+    MetaDataElement parent;
+    uint permissionIx;
+
+                internal DeclSecurity(MetaDataElement paren, ushort act)        {
+      parent = paren;
+      action = act;
+      tabIx = MDTable.DeclSecurity;
+      throw(new NotYetImplementedException("Security "));
+                }
+
+    internal override uint SortKey() {
+      return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
+              | parent.GetCodedIx(CIx.HasDeclSecurity);
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+// add permission to blob heap
+      done = true;
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(action);
+      output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
+      output.BlobIndex(permissionIx);
+    }
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for an event
+        /// </summary>
+  public class Event : Feature
+        {
+    Type eventType;
+
+    internal Event(string name, Type eType, ClassDef parent) 
+                                            : base(name, parent) {
+      eventType = eType;
+                        tabIx = MDTable.Event;
+    }
+
+    /// <summary>
+    /// Add the addon method to this event
+    /// </summary>
+    /// <param name="addon">the addon method</param>
+    public void AddAddon(MethodDef addon) {
+      AddMethod(addon,MethodType.AddOn);
+    }
+
+    /// <summary>
+    /// Add the removeon method to this event
+    /// </summary>
+    /// <param name="removeOn">the removeon method</param>
+    public void AddRemoveOn(MethodDef removeOn) {
+      AddMethod(removeOn,MethodType.RemoveOn);
+    }
+
+    /// <summary>
+    /// Add the fire method to this event
+    /// </summary>
+    /// <param name="fire">the fire method</param>
+    public void AddFire(MethodDef fire) {
+      AddMethod(fire,MethodType.Fire);
+    }
+
+    /// <summary>
+    /// Add another method to this event
+    /// </summary>
+    /// <param name="other">the method to be added</param>
+    public void AddOther(MethodDef other) {
+      AddMethod(other,MethodType.Other);
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      nameIx = md.AddToStringsHeap(name);
+      for (int i=0; i < tide; i++) {
+        md.AddToTable(MDTable.MethodSemantics,methods[i]);
+      }
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.StringsIndex(nameIx);
+      output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 10; 
+        case (CIx.HasSemantics) : return 0; 
+      }
+      return 0;
+    }
+   
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a class defined in another module of THIS assembly 
+        /// and exported (.class extern)
+        /// </summary>
+
+  internal class ExternClass : Class
+        {
+                MetaDataElement parent;
+    uint flags;
+
+    internal ExternClass(TypeAttr attr, uint nsIx, uint nIx, 
+                         MetaDataElement paren) : base(nsIx,nIx) {
+      flags = (uint)attr;
+            parent = paren;
+                        tabIx = MDTable.ExportedType;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.Write(0);
+      output.StringsIndex(nameIx);
+      output.StringsIndex(nameSpaceIx);
+      output.WriteCodedIndex(CIx.Implementation,parent);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 17; 
+        case (CIx.Implementation) : return 2; 
+      }
+      return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for Event and Property descriptors
+        /// </summary>
+
+  public class Feature : MetaDataElement
+        {
+    internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08, 
+      RemoveOn = 0x10, Fire = 0x20 }
+
+    private static readonly int INITSIZE = 5;
+    private static readonly ushort specialName = 0x200;
+    private static readonly ushort rtSpecialName = 0x400;
+
+    protected ClassDef parent;
+    protected ushort flags = 0;
+    protected string name;
+    protected int tide = 0;
+    protected uint nameIx;
+    protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
+    
+    internal Feature(string name, ClassDef par) {
+      parent = par;
+      this.name = name;
+    }
+
+    internal void AddMethod(MethodDef meth, MethodType mType) {
+      if (tide >= methods.Length) { 
+        int len = methods.Length;
+        MethodSemantics[] mTmp = methods;
+        methods = new MethodSemantics[len * 2];
+        for (int i=0; i < len; i++) {
+          methods[i] = mTmp[i];
+        }
+      }
+      methods[tide++] = new MethodSemantics(mType,meth,this);
+    }
+
+    /// <summary>
+    /// Set the specialName attribute for this Event or Property
+    /// </summary>
+    public void SetSpecialName() {
+      flags |= specialName;
+    }
+
+    /// <summary>
+    /// Set the RTSpecialName attribute for this Event or Property
+    /// </summary>
+    public void SetRTSpecialName() {
+      flags |= rtSpecialName;
+    }
+  
+        }
+  /*****************************************************************************/  
+        /// <summary>
+        /// Descriptor for a field of a class
+        /// </summary>
+
+  public abstract class Field : Member
+        {
+    protected static readonly byte FieldSig = 0x6;
+
+    protected Type type;
+
+                internal Field(string pfName, Type pfType) : base(pfName)
+                {
+      type = pfType;
+                }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a field defined in a class of THIS assembly/module
+        /// </summary>
+  public class FieldDef : Field
+        {
+    //private static readonly uint PInvokeImpl = 0x2000;
+    private static readonly ushort HasFieldMarshal = 0x1000;
+    private static readonly ushort HasFieldRVA = 0x100;
+    private static readonly ushort HasDefault = 0x8000;
+
+    FieldRVA rva;
+    ConstantElem constVal;
+    FieldLayout layout;
+    FieldMarshal marshalInfo;
+    ushort flags;
+
+    internal FieldDef(string name, Type fType) : base(name,fType) {
+      tabIx = MDTable.Field;
+    }
+
+    internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType) { 
+      flags = (ushort)attrSet;
+      tabIx = MDTable.Field;
+    }
+
+    /// <summary>
+    /// Add an attribute(s) to this field
+    /// </summary>
+    /// <param name="fa">the attribute(s) to be added</param>
+    public void AddFieldAttr(FieldAttr fa) {
+      flags |= (ushort)fa;
+    }
+    /// <summary>
+    /// Add a value for this field
+    /// </summary>
+    /// <param name="val">the value for the field</param>
+    public void AddValue(Constant val) {
+      constVal = new ConstantElem(this,val);
+      flags |= HasDefault;
+    }
+
+    /// <summary>
+    /// Add an initial value for this field (at dataLabel) (.data)
+    /// </summary>
+    /// <param name="val">the value for the field</param>
+    /// <param name="repeatVal">the number of repetitions of this value</param>
+    public void AddDataValue(DataConstant val) {
+      flags |= HasFieldRVA;
+      rva = new FieldRVA(this,val);
+    }
+
+    /// <summary>
+    /// Set the offset of the field.  Used for sequential or explicit classes.
+    /// (.field [offs])
+    /// </summary>
+    /// <param name="offs">field offset</param>
+    public void SetOffset(uint offs) {
+      layout = new FieldLayout(this,offs);
+    }
+
+    /// <summary>
+    /// Set the marshalling info for a field
+    /// </summary>
+    /// <param name="mInf"></param>
+    public void SetMarshalInfo(NativeType marshallType) {
+      flags |= HasFieldMarshal;
+      marshalInfo = new FieldMarshal(this,marshallType);
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      nameIx = md.AddToStringsHeap(name);
+      MemoryStream sig = new MemoryStream();
+      sig.WriteByte(FieldSig);
+      type.TypeSig(sig);
+      sigIx = md.AddToBlobHeap(sig.ToArray());
+      if (rva != null) {
+        md.AddToTable(MDTable.FieldRVA,rva);
+        rva.BuildTables(md);
+      } else if (constVal != null) {
+        md.AddToTable(MDTable.Constant,constVal);
+        constVal.BuildTables(md);
+      }
+      if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
+      if (marshalInfo != null) {
+        md.AddToTable(MDTable.FieldMarshal,marshalInfo);
+        marshalInfo.BuildTables(md);
+      }
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.StringsIndexSize() + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.StringsIndex(nameIx);
+      output.BlobIndex(sigIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasConst) : return 0; 
+        case (CIx.HasCustomAttr) : return 1; 
+        case (CIx.HasFieldMarshal) : return 0; 
+        case (CIx.MemberForwarded) : return 0; 
+      }
+      return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for layout information for a field
+        /// </summary>
+        
+        public class FieldLayout : MetaDataElement
+        {
+    Field field;
+    uint offset;
+
+    internal FieldLayout(Field field, uint offset)      {
+      this.field = field;
+      this.offset = offset;
+                        tabIx = MDTable.FieldLayout;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 4 + md.TableIndexSize(MDTable.Field);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(offset);
+      output.WriteIndex(MDTable.Field,field.Row);
+    }
+
+        }
+  /*****************************************************************************/  
+        /// <summary>
+        /// Marshalling information for a field or param
+        /// </summary>
+  public class FieldMarshal : MetaDataElement
+        {
+    MetaDataElement field;
+    NativeType nt;
+    uint ntIx;
+
+    internal FieldMarshal(MetaDataElement field, NativeType nType)      {
+      this.field = field;
+      this.nt = nType;
+                        tabIx = MDTable.FieldMarshal;
+                }
+
+    internal override uint SortKey() { 
+      return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
+              | field.GetCodedIx(CIx.HasFieldMarshal);
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      ntIx = md.AddToBlobHeap(nt.ToBlob());
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteCodedIndex(CIx.HasFieldMarshal,field);
+      output.BlobIndex(ntIx);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a field of a class defined in another assembly/module
+        /// </summary>
+  public class FieldRef : Field
+        {
+    MetaDataElement parent;
+
+                internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)   {       
+      parent = paren;
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      nameIx = md.AddToStringsHeap(name);
+      MemoryStream sig = new MemoryStream();
+      sig.WriteByte(FieldSig);
+      type.TypeSig(sig);
+      sigIx = md.AddToBlobHeap(sig.ToArray());
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteCodedIndex(CIx.MemberRefParent,parent);
+      output.StringsIndex(nameIx);
+      output.BlobIndex(sigIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) { return 6; }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for the address of a field's value in the PE file
+        /// </summary>
+  public class FieldRVA : MetaDataElement
+        {
+    Field field;
+    DataConstant data;
+
+    internal FieldRVA(Field field, DataConstant data)   {
+      this.field = field;
+      this.data = data;
+      tabIx = MDTable.FieldRVA;
+                }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      md.AddData(data);
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 4 + md.TableIndexSize(MDTable.Field);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteDataRVA(data.DataOffset);
+      output.WriteIndex(MDTable.Field,field.Row);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Image for a PEFile
+        /// File Structure
+  ///     DOS Header (128 bytes) 
+  ///     PE Signature ("PE\0\0") 
+  ///     PEFileHeader (20 bytes)
+  ///     PEOptionalHeader (224 bytes) 
+  ///     SectionHeaders (40 bytes * NumSections)
+  ///
+  ///     Sections .text (always present - contains metadata)
+  ///              .sdata (contains any initialised data in the file - may not be present)
+  ///                     (for ilams /debug this contains the Debug table)
+  ///              .reloc (always present - in pure CIL only has one fixup)
+  ///               others???  c# produces .rsrc section containing a Resource Table
+  ///
+  /// .text layout
+  ///     IAT (single entry 8 bytes for pure CIL)
+  ///     CLIHeader (72 bytes)
+  ///     CIL instructions for all methods (variable size)
+  ///     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)
+  ///    ImportTable (40 bytes)
+  ///    ImportLookupTable(8 bytes) (same as IAT for standard CIL files)
+  ///    Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)
+  ///    ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)
+  ///    Entry Point  (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)
+  ///
+  ///  #~ stream structure
+  ///    Header (24 bytes)
+  ///    Rows   (4 bytes * numTables)
+  ///    Tables
+  /// </summary>
+        internal class FileImage : BinaryWriter
+        {
+    internal readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};
+    internal readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00,
+                                                  0x0000000000FF0000, 0x00000000FF000000,
+                                                  0x000000FF00000000, 0x0000FF0000000000,
+                                                  0x00FF000000000000, 0xFF00000000000000 };
+    internal readonly static uint nibble0Mask = 0x0000000F;
+    internal readonly static uint nibble1Mask = 0x000000F0;
+
+    private static readonly byte[] DOSHeader = { 0x4d,0x5a,0x90,0x00,0x03,0x00,0x00,0x00,
+                                                 0x04,0x00,0x00,0x00,0xff,0xff,0x00,0x00,
+                                                 0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                                 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                                 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
+                                                 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,
+                                                 0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
+                                                 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,
+                                                 0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
+                                                 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,
+                                                 0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
+                                                 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,
+                                                 0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                                 0x50,0x45,0x00,0x00};
+    private static byte[] PEHeader = { 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                       0xE0, 0x00, 0x0E, 0x01, // PE Header Standard Fields
+                                       0x0B, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+                                     };
+
+    private static readonly uint minFileAlign = 0x200;
+    private static readonly uint maxFileAlign = 0x1000;
+    private static readonly uint fileHeaderSize = 0x178;
+    private static readonly uint sectionHeaderSize = 40;
+    private static readonly uint SectionAlignment = 0x2000;
+    private static readonly uint ImageBase = 0x400000;
+    private static readonly uint ImportTableSize = 40;
+    private static readonly uint IATSize = 8;
+    private static readonly uint CLIHeaderSize = 72;
+    private uint runtimeFlags = 0x01;  // COMIMAGE_FLAGS_ILONLY
+    // 32BITREQUIRED 0x02, STRONGNAMESIGNED 0x08, TRACKDEBUGDATA 0x10000
+    private static readonly uint StrongNameSignatureSize = 128;
+    private bool reserveStrongNameSignatureSpace = false;
+
+                private static readonly uint relocFlags = 0x42000040;
+                private static readonly ushort exeCharacteristics = 0x010E;
+                private static readonly ushort dllCharacteristics = 0x210E;
+    // section names are all 8 bytes
+    private static readonly string textName = ".text\0\0\0";
+    private static readonly string sdataName = ".sdata\0\0";
+    private static readonly string relocName = ".reloc\0\0";
+    private static readonly string rsrcName = ".rsrc\0\0\0";
+    private static readonly string exeHintNameTable = "\0\0_CorExeMain\0";
+    private static readonly string dllHintNameTable = "\0\0_CorDllMain\0";
+    private static readonly string runtimeEngineName = "mscoree.dll\0\0";
+
+                private Section text, sdata, rsrc;
+                ArrayList data;
+    BinaryWriter reloc = new BinaryWriter(new MemoryStream());
+    uint dateStamp = 0;
+    DateTime origin = new DateTime(1970,1,1);
+    uint numSections = 2; // always have .text  and .reloc sections
+    internal SubSystem subSys = SubSystem.Windows_CUI;  // default is Windows Console mode
+    internal uint fileAlign = minFileAlign;
+    uint entryPointOffset, entryPointPadding, imageSize, headerSize, headerPadding, entryPointToken = 0;
+    uint relocOffset, relocRVA, relocSize, relocPadding, relocTide, hintNameTableOffset;
+    uint metaDataOffset, runtimeEngineOffset, initDataSize = 0, importTablePadding;
+    uint resourcesSize, resourcesOffset;
+    uint strongNameSigOffset;
+    uint importTableOffset, importLookupTableOffset, totalImportTableSize;
+    MetaData metaData;
+    char[] runtimeEngine = runtimeEngineName.ToCharArray(), hintNameTable;
+                bool doDLL, largeStrings, largeGUID, largeUS, largeBlob;
+                ushort characteristics;
+
+    internal FileImage(bool makeDLL, string fileName) : base(new FileStream(fileName,FileMode.Create)) {
+      InitFileImage(makeDLL);
+      TimeSpan tmp = System.IO.File.GetCreationTime(fileName).Subtract(origin);
+      dateStamp = Convert.ToUInt32(tmp.TotalSeconds);
+    }
+
+    internal FileImage(bool makeDLL, Stream str) : base(str) {
+      InitFileImage(makeDLL);
+      TimeSpan tmp = DateTime.Now.Subtract(origin);
+      dateStamp = Convert.ToUInt32(tmp.TotalSeconds);
+    }
+
+    private void InitFileImage(bool makeDLL) {
+      doDLL = makeDLL;
+                        if (doDLL) {
+                                hintNameTable = dllHintNameTable.ToCharArray();
+                                characteristics = dllCharacteristics;
+                        } else {
+                                hintNameTable = exeHintNameTable.ToCharArray();
+                                characteristics = exeCharacteristics;
+                        }
+      text = new Section(textName,0x60000020);     // IMAGE_SCN_CNT  CODE, EXECUTE, READ
+//                      rsrc = new Section(rsrcName,0x40000040);     // IMAGE_SCN_CNT  INITIALIZED_DATA, READ
+      metaData = new MetaData(this);
+    }
+
+                internal MetaData GetMetaData() {
+                        return metaData;
+                }
+
+    private uint GetNextSectStart(uint rva, uint tide) {
+      if (tide < SectionAlignment) return rva + SectionAlignment;
+      return rva + ((tide / SectionAlignment) + 1) * SectionAlignment;
+    }
+
+    private void BuildTextSection() {
+      // .text layout
+      //    IAT (single entry 8 bytes for pure CIL)
+      //    CLIHeader (72 bytes)
+      //    CIL instructions for all methods (variable size)
+      //    MetaData 
+      //    ImportTable (40 bytes)
+      //    ImportLookupTable(8 bytes) (same as IAT for standard CIL files)
+      //    Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)
+      //    ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)
+      //    Entry Point  (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)
+      metaData.BuildMetaData(IATSize + CLIHeaderSize);
+      metaDataOffset = IATSize + CLIHeaderSize;
+      // Console.WriteLine("Code starts at " + metaDataOffset);
+      metaDataOffset += metaData.CodeSize();
+      // resourcesStart =
+      resourcesOffset = metaDataOffset + metaData.Size ();
+      resourcesSize = metaData.GetResourcesSize ();
+      if (reserveStrongNameSignatureSpace) {
+        strongNameSigOffset = resourcesOffset + resourcesSize;
+        // fixUps = RVA for vtable
+        importTableOffset = strongNameSigOffset + StrongNameSignatureSize;
+      } else {
+        strongNameSigOffset = 0;
+        // fixUps = RVA for vtable
+        importTableOffset = resourcesOffset + resourcesSize;
+      }
+      importTablePadding = NumToAlign(importTableOffset,16);
+      importTableOffset += importTablePadding;
+      importLookupTableOffset = importTableOffset + ImportTableSize;
+      hintNameTableOffset = importLookupTableOffset + IATSize;
+      runtimeEngineOffset = hintNameTableOffset + (uint)hintNameTable.Length;
+      entryPointOffset = runtimeEngineOffset + (uint)runtimeEngine.Length;
+      totalImportTableSize = entryPointOffset - importTableOffset;
+      // Console.WriteLine("total import table size = " + totalImportTableSize);
+      // Console.WriteLine("entrypoint offset = " + entryPointOffset);
+      entryPointPadding = NumToAlign(entryPointOffset,4) + 2;
+      entryPointOffset += entryPointPadding;
+      text.AddReloc(entryPointOffset+2);
+      text.IncTide(entryPointOffset + 6);
+      //if (text.Tide() < fileAlign) fileAlign = minFileAlign;
+                        text.SetSize(NumToAlign(text.Tide(),fileAlign));
+      // Console.WriteLine("text size = " + text.Size() + " text tide = " + text.Tide() + " text padding = " + text.Padding());
+                        // Console.WriteLine("metaDataOffset = " + Hex.Int(metaDataOffset));
+                        // Console.WriteLine("importTableOffset = " + Hex.Int(importTableOffset));
+                        // Console.WriteLine("importLookupTableOffset = " + Hex.Int(importLookupTableOffset));
+                        // Console.WriteLine("hintNameTableOffset = " + Hex.Int(hintNameTableOffset));
+                        // Console.WriteLine("runtimeEngineOffset = " + Hex.Int(runtimeEngineOffset));
+                        // Console.WriteLine("entryPointOffset = " + Hex.Int(entryPointOffset));
+                        // Console.WriteLine("entryPointPadding = " + Hex.Int(entryPointPadding));
+
+    }
+
+    internal void BuildRelocSection() {
+                        text.DoRelocs(reloc);
+                        if (sdata != null) sdata.DoRelocs(reloc);
+                        if (rsrc != null) rsrc.DoRelocs(reloc);
+      relocTide = (uint)reloc.Seek(0,SeekOrigin.Current);
+      relocPadding = NumToAlign(relocTide,fileAlign);
+      relocSize = relocTide + relocPadding;
+                        imageSize = relocRVA + SectionAlignment;
+      initDataSize += relocSize;
+    }
+
+    private void CalcOffsets() {
+if (sdata != null)
+        numSections++;
+if (rsrc != null)
+        numSections++;
+      headerSize = fileHeaderSize + (numSections * sectionHeaderSize);
+      headerPadding = NumToAlign(headerSize,fileAlign);
+      headerSize += headerPadding;
+      uint offset = headerSize;
+      uint rva = SectionAlignment;
+      text.SetOffset(offset);
+      text.SetRVA(rva);
+      offset += text.Size();
+      rva  = GetNextSectStart(rva,text.Tide());
+                        // Console.WriteLine("headerSize = " + headerSize);
+                        // Console.WriteLine("headerPadding = " + headerPadding);
+                        // Console.WriteLine("textOffset = " + Hex.Int(text.Offset()));
+                        if (sdata != null) { 
+                                sdata.SetSize(NumToAlign(sdata.Tide(),fileAlign));
+                                sdata.SetOffset(offset);
+        sdata.SetRVA(rva);
+        offset += sdata.Size();
+        rva = GetNextSectStart(rva,sdata.Tide());
+                                initDataSize += sdata.Size();
+      }
+      if (rsrc != null) { 
+                     rsrc.SetSize(NumToAlign(rsrc.Tide(),fileAlign));
+                                rsrc.SetOffset(offset);
+        rsrc.SetRVA(rva);
+        offset += rsrc.Size();
+        rva = GetNextSectStart(rva,rsrc.Tide());
+                                initDataSize += rsrc.Size();
+      }
+      relocOffset = offset;
+      relocRVA = rva;
+    }
+
+    internal void MakeFile() {
+      if (doDLL) hintNameTable = dllHintNameTable.ToCharArray();
+      else hintNameTable = exeHintNameTable.ToCharArray();
+      BuildTextSection();
+      CalcOffsets();
+      BuildRelocSection();
+      // now write it out
+      WriteHeader();
+      WriteSections();
+      Flush();
+      Close();
+    }
+
+    private void WriteHeader() {
+      Write(DOSHeader);
+                        // Console.WriteLine("Writing PEHeader at offset " + Seek(0,SeekOrigin.Current));
+                        WritePEHeader();
+                         // Console.WriteLine("Writing text section header at offset " + Hex.Long(Seek(0,SeekOrigin.Current)));
+                        text.WriteHeader(this,relocRVA);
+      if (sdata != null) sdata.WriteHeader(this,relocRVA);
+      if (rsrc != null) rsrc.WriteHeader(this,relocRVA);
+                        // Console.WriteLine("Writing reloc section header at offset " + Seek(0,SeekOrigin.Current));
+                        WriteRelocSectionHeader();
+                        // Console.WriteLine("Writing padding at offset " + Seek(0,SeekOrigin.Current));
+                        WriteZeros(headerPadding);
+    }
+
+    private void WriteSections() {
+                        // Console.WriteLine("Writing text section at offset " + Seek(0,SeekOrigin.Current));
+      WriteTextSection();
+      if (sdata != null) WriteSDataSection();
+      if (rsrc != null) WriteRsrcSection();
+      WriteRelocSection();
+    }
+
+     private void WriteIAT() {
+      Write(text.RVA() + hintNameTableOffset);
+      Write(0);
+    }
+
+                private void WriteImportTables() {
+                        // Import Table
+      WriteZeros(importTablePadding);
+      // Console.WriteLine("Writing import tables at offset " + Hex.Long(Seek(0,SeekOrigin.Current)));
+                        Write(importLookupTableOffset + text.RVA());
+                        WriteZeros(8); 
+                        Write(runtimeEngineOffset + text.RVA());
+                        Write(text.RVA());    // IAT is at the beginning of the text section
+                        WriteZeros(20);
+                        // Import Lookup Table
+                        WriteIAT();                // lookup table and IAT are the same
+                        // Hint/Name Table
+       // Console.WriteLine("Writing hintname table at " + Hex.Long(Seek(0,SeekOrigin.Current)));
+                        Write(hintNameTable);
+      Write(runtimeEngineName.ToCharArray());
+                }
+
+    private void WriteTextSection() {
+      WriteIAT();
+      WriteCLIHeader();
+      // Console.WriteLine("Writing code at " + Hex.Long(Seek(0,SeekOrigin.Current)));
+      metaData.WriteByteCodes(this);
+      // Console.WriteLine("Finished writing code at " + Hex.Long(Seek(0,SeekOrigin.Current)));
+      largeStrings = metaData.LargeStringsIndex();
+      largeGUID = metaData.LargeGUIDIndex();
+      largeUS = metaData.LargeUSIndex();
+      largeBlob = metaData.LargeBlobIndex();
+      metaData.WriteMetaData(this);
+      metaData.WriteResources (this);
+      if (reserveStrongNameSignatureSpace) {
+        WriteZeros(StrongNameSignatureSize);
+      }
+      WriteImportTables();
+                        WriteZeros(entryPointPadding);
+                        Write((ushort)0x25FF);
+                        Write(ImageBase + text.RVA());
+                        WriteZeros(text.Padding());
+    }
+
+    private void WriteCLIHeader() {
+      Write(CLIHeaderSize);       // Cb
+      Write((short)2);            // Major runtime version
+      Write((short)0);            // Minor runtime version
+      Write(text.RVA() + metaDataOffset);
+      Write(metaData.Size());
+      Write(runtimeFlags);
+      Write(entryPointToken);
+      if (resourcesSize > 0) {
+        Write (text.RVA () + resourcesOffset);
+        Write (resourcesSize);
+      } else {
+       WriteZeros (8);
+      }
+      // Strong Name Signature (RVA, size)
+      if (reserveStrongNameSignatureSpace) {
+        Write(text.RVA() + strongNameSigOffset); 
+        Write(StrongNameSignatureSize);
+      } else {
+        WriteZeros(8);
+      }
+      WriteZeros(8);                     // CodeManagerTable
+      WriteZeros(8);                     // VTableFixups NYI
+      WriteZeros(16);                    // ExportAddressTableJumps, ManagedNativeHeader
+     }
+
+    private void WriteSDataSection() {
+      long size = sdata.Size ();
+      long start = BaseStream.Position;
+      for (int i=0; i < data.Count; i++) {
+        ((DataConstant)data[i]).Write(this);
+      }
+      while (BaseStream.Position < (start + size))
+              Write ((byte) 0);
+    }
+
+                private void WriteRsrcSection() {
+                }
+
+    private void WriteRelocSection() {
+     // Console.WriteLine("Writing reloc section at " + Seek(0,SeekOrigin.Current) + " = " + relocOffset);
+      MemoryStream str = (MemoryStream)reloc.BaseStream;
+      Write(str.ToArray());
+      WriteZeros(NumToAlign((uint)str.Position,fileAlign));
+    }
+
+    internal void SetEntryPoint(uint entryPoint) {
+      entryPointToken = entryPoint;
+    }
+
+    internal void AddInitData(DataConstant cVal) {
+                        if (sdata == null) {                    
+                                sdata = new Section(sdataName,0xC0000040);   // IMAGE_SCN_CNT  INITIALIZED_DATA, READ, WRITE
+                                data = new ArrayList(); 
+                        }
+      data.Add(cVal);
+      cVal.DataOffset = sdata.Tide();
+      sdata.IncTide(cVal.GetSize());
+    }
+
+    internal void WriteZeros(uint numZeros) {
+      for (int i=0; i < numZeros; i++) {
+        Write((byte)0);
+      }
+    }
+
+    internal void WritePEHeader() {
+      Write((ushort)0x014C);  // Machine - always 0x14C for Managed PE Files (allow others??)
+      Write((ushort)numSections);
+      Write(dateStamp);
+      WriteZeros(8); // Pointer to Symbol Table and Number of Symbols (always zero for ECMA CLI files)
+      Write((ushort)0x00E0);  // Size of Optional Header
+      Write(characteristics);
+      // PE Optional Header
+      Write((ushort)0x010B);   // Magic
+      Write((byte)0x6);        // LMajor pure-IL = 6   C++ = 7
+      Write((byte)0x0);        // LMinor
+      Write(text.Size());
+      Write(initDataSize);
+      Write(0);                // Check other sections here!!
+      Write(text.RVA() + entryPointOffset);
+      Write(text.RVA());
+                        uint dataBase = 0;
+                        if (sdata != null) dataBase = sdata.RVA();
+                        else if (rsrc != null) dataBase = rsrc.RVA();
+      else dataBase = relocRVA;
+                        Write(dataBase);
+      Write(ImageBase);
+      Write(SectionAlignment);
+      Write(fileAlign);
+      Write((ushort)0x04);     // OS Major
+      WriteZeros(6);                  // OS Minor, User Major, User Minor
+      Write((ushort)0x04);     // SubSys Major
+      WriteZeros(6);           // SybSys Minor, Reserved
+      Write(imageSize);
+      Write(headerSize);
+      Write((int)0);           // File Checksum
+      Write((ushort)subSys);
+      Write((short)0);         // DLL Flags
+      Write((uint)0x100000);   // Stack Reserve Size
+      Write((uint)0x1000);     // Stack Commit Size
+      Write((uint)0x100000);   // Heap Reserve Size
+      Write((uint)0x1000);     // Heap Commit Size
+      Write(0);                // Loader Flags
+      Write(0x10);             // Number of Data Directories
+      WriteZeros(8);                  // Export Table
+      Write(importTableOffset + text.RVA());
+      Write(totalImportTableSize);
+      WriteZeros(24);            // Resource, Exception and Certificate Tables
+      Write(relocRVA);
+      Write(relocTide);
+      WriteZeros(48);            // Debug, Copyright, Global Ptr, TLS, Load Config and Bound Import Tables
+      Write(text.RVA());         // IATRVA - IAT is at start of .text Section
+      Write(IATSize);
+      WriteZeros(8);             // Delay Import Descriptor
+      Write(text.RVA()+IATSize); // CLIHeader immediately follows IAT
+      Write(CLIHeaderSize);    
+      WriteZeros(8);             // Reserved
+    }
+
+    internal void WriteRelocSectionHeader() {
+      Write(relocName.ToCharArray());
+      Write(relocTide);
+      Write(relocRVA);
+      Write(relocSize);
+      Write(relocOffset);
+      WriteZeros(12);
+      Write(relocFlags);
+    }
+
+    private void Align (MemoryStream str, int val) {
+      if ((str.Position % val) != 0) {
+        for (int i=val - (int)(str.Position % val); i > 0; i--) {
+          str.WriteByte(0);
+        }
+      }
+    }
+
+    private uint Align(uint val, uint alignVal) {
+      if ((val % alignVal) != 0) {
+        val += alignVal - (val % alignVal);
+      }
+      return val;
+    }
+
+    private uint NumToAlign(uint val, uint alignVal) {
+      if ((val % alignVal) == 0) return 0;
+      return alignVal - (val % alignVal);
+    }
+
+    internal void StringsIndex(uint ix) {
+      if (largeStrings) Write(ix);
+      else Write((ushort)ix);
+    }
+
+    internal void GUIDIndex(uint ix) {
+      if (largeGUID) Write(ix);
+      else Write((ushort)ix);
+    }
+
+    internal void USIndex(uint ix) {
+      if (largeUS) Write(ix);
+      else Write((ushort)ix);
+    }
+
+    internal void BlobIndex(uint ix) {
+      if (largeBlob) Write(ix);
+      else Write((ushort)ix);
+    }
+
+    internal void WriteIndex(MDTable tabIx,uint ix) {
+      if (metaData.LargeIx(tabIx)) Write(ix);
+      else Write((ushort)ix);
+    }
+
+    internal void WriteCodedIndex(CIx code, MetaDataElement elem) {
+      metaData.WriteCodedIndex(code,elem,this);
+    }
+    
+    internal void WriteCodeRVA(uint offs) {
+      Write(text.RVA() + offs);
+    }
+
+    internal void WriteDataRVA(uint offs) {
+      Write(sdata.RVA() + offs);
+    }
+
+    internal void Write3Bytes(uint val) {
+      byte b3 = (byte)((val & FileImage.iByteMask[2]) >> 16);
+      byte b2 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
+      byte b1 = (byte)(val & FileImage.iByteMask[0]);
+      Write(b1);
+      Write(b2);
+      Write(b3);
+    }
+
+    internal bool ReserveStrongNameSignatureSpace {
+      get { return reserveStrongNameSignatureSpace; }
+      set { reserveStrongNameSignatureSpace = value; }
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a file referenced in THIS assembly/module (.file)
+        /// </summary>
+        public class FileRef : MetaDataElement
+        {
+    private static readonly uint NoMetaData = 0x1;
+    uint nameIx = 0, hashIx = 0;
+    uint flags = 0;
+    protected string name;
+
+    internal FileRef(string name, byte[] hashBytes, bool metaData,
+                      bool entryPoint, MetaData md) {
+      if (!metaData) flags = NoMetaData;
+      if (entryPoint) md.SetEntryPoint(this);
+      this.name = name;
+      nameIx = md.AddToStringsHeap(name);
+      hashIx = md.AddToBlobHeap(hashBytes);
+      tabIx = MDTable.File;
+                }
+
+    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 uint Size(MetaData md) {
+      return 4 + md.StringsIndexSize() + md.BlobIndexSize();
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      md.AddToTable(MDTable.File,this);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.StringsIndex(nameIx);
+      output.BlobIndex(hashIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 16; 
+        case (CIx.Implementation) : return 0;
+      }
+      return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
+        /// </summary>
+        public class ImplMap : MetaDataElement
+        {
+    private static readonly ushort NoMangle = 0x01;
+    ushort flags;
+    Method meth;
+    string importName;
+    uint iNameIx;
+    ModuleRef importScope;
+
+                internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope) {
+      flags = flag;
+      meth = implMeth;
+      importName = iName;
+      importScope = mScope;
+      tabIx = MDTable.ImplMap;
+      if (iName == null) flags |= NoMangle;
+      //throw(new NotYetImplementedException("PInvoke "));
+                }
+
+    internal override uint SortKey() {
+      return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded]) 
+              | meth.GetCodedIx(CIx.MemberForwarded);
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      iNameIx = md.AddToStringsHeap(importName);
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2+ md.CodedIndexSize(CIx.MemberForwarded) + 
+        md.StringsIndexSize() +  md.TableIndexSize(MDTable.ModuleRef);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.WriteCodedIndex(CIx.MemberForwarded,meth);
+      output.StringsIndex(iNameIx);
+      output.WriteIndex(MDTable.ModuleRef,importScope.Row);
+    }
+
+        }
+
+  /**************************************************************************/  
+  /// <summary>
+  /// Descriptor for an IL instruction
+  /// </summary>
+  internal abstract class CILInstruction {
+    protected static readonly sbyte maxByteVal = 127;
+    protected static readonly sbyte minByteVal = -128;
+    protected static readonly byte leadByte = 0xFE;
+                protected static readonly uint USHeapIndex = 0x70000000;
+    protected static readonly int longInstrStart = (int)Op.arglist;
+    public bool twoByteInstr = false;
+    public uint size = 0;
+    public uint offset;
+
+    internal virtual bool Check(MetaData md) {
+      return false;
+    }
+
+                internal virtual void Write(FileImage output) { }
+
+  }
+
+  internal class CILByte : CILInstruction {
+    byte byteVal;
+
+    internal CILByte(byte bVal) {
+      byteVal = bVal;
+      size = 1;
+    }
+
+    internal override void Write(FileImage output) {
+      output.Write(byteVal);
+    }
+
+  }
+
+  
+  internal class Instr : CILInstruction {
+    protected int instr;
+
+    internal Instr(int inst) {
+      if (inst >= longInstrStart) {
+        instr = inst - longInstrStart;
+        twoByteInstr = true;
+        size = 2;
+      } else {
+        instr = inst;
+        size = 1;
+      }
+    }
+
+                internal override void Write(FileImage output) {
+      //Console.WriteLine("Writing instruction " + instr + " with size " + size);
+      if (twoByteInstr) output.Write(leadByte);
+      output.Write((byte)instr);
+                }
+
+  }
+
+  internal class IntInstr : Instr {
+    int val;
+    bool byteNum;
+
+    internal IntInstr(int inst, int num, bool byteSize) : base(inst) {
+      val = num;
+      byteNum = byteSize;
+      if (byteNum) size++;
+      else size += 4;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+      if (byteNum) 
+        output.Write((sbyte)val);
+      else 
+                                output.Write(val); 
+                }
+
+  }
+
+  internal class UIntInstr : Instr {
+    int val;
+    bool byteNum;
+
+                internal UIntInstr(int inst, int num, bool byteSize) : base(inst) {
+                        val = num;
+      byteNum = byteSize;
+      if (byteNum) size++;
+      else size += 2;
+                }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+      if (byteNum)
+                          output.Write((byte)val);
+      else
+                                output.Write((ushort)val); 
+                }
+        
+  }
+
+        internal class LongInstr : Instr {
+                long val;
+
+                internal LongInstr(int inst, long l) : base(inst) {
+                        val = l;
+                        size += 8;
+                }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(val);
+                }
+
+        }
+
+  internal class FloatInstr : Instr {
+    float fVal;
+
+    internal FloatInstr(int inst, float f) : base(inst) {
+      fVal = f;
+      size += 4;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(fVal);
+                }
+
+        }
+
+  internal class DoubleInstr : Instr {
+    double val;
+
+    internal DoubleInstr(int inst, double d) : base(inst) {
+      val = d;
+      size += 8;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(val);
+                }
+
+        }
+
+  internal class StringInstr : Instr {
+    string val;
+          byte[] bval;                                                  
+    uint strIndex;
+
+    internal StringInstr(int inst, string str) : base(inst) {
+      val = str;  
+      size += 4;
+    }
+
+          internal StringInstr (int inst, byte[] str) : base (inst) {
+                  bval = str;
+                  size += 4;
+          }
+                   
+    internal sealed override bool Check(MetaData md) {
+            if (val != null)
+                    strIndex = md.AddToUSHeap(val);
+            else
+                    strIndex = md.AddToUSHeap (bval);
+      return false;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(USHeapIndex  | strIndex);
+                }
+
+        }
+
+  internal class LabelInstr : CILInstruction {
+    CILLabel label;
+
+    internal LabelInstr(CILLabel lab) {
+      label = lab;
+      label.AddLabelInstr(this);
+    }
+  }
+
+  internal class FieldInstr : Instr {
+    Field field;
+
+    internal FieldInstr(int inst, Field f) : base(inst) {
+      field = f;
+      size += 4;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(field.Token());
+                }
+
+        }
+
+  internal class MethInstr : Instr {
+    Method meth;
+
+    internal MethInstr(int inst, Method m) : base(inst) {
+      meth = m;
+      size += 4;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(meth.Token());
+                }
+
+  }
+
+  internal class SigInstr : Instr {
+    CalliSig signature;
+
+    internal SigInstr(int inst, CalliSig sig) : base(inst) {
+      signature = sig;
+      size += 4;
+    }
+
+    internal sealed override bool Check(MetaData md) {
+      md.AddToTable(MDTable.StandAloneSig,signature);
+      signature.BuildTables(md);
+      return false;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(signature.Token());
+                }
+  }
+
+  internal class TypeInstr : Instr {
+    MetaDataElement theType;
+
+    internal TypeInstr(int inst, Type aType, MetaData md) : base(inst) {
+      theType = aType.GetTypeSpec(md);
+      size += 4;
+    }
+
+    internal sealed override void Write(FileImage output) {
+      base.Write(output);
+      output.Write(theType.Token());
+                }
+
+  }
+
+  internal class BranchInstr : Instr {
+    CILLabel dest;
+    private bool shortVer = true;
+    private static readonly byte longInstrOffset = 13;
+    private int target = 0;
+
+    internal BranchInstr(int inst, CILLabel dst) : base(inst) {
+      dest = dst;
+      dest.AddBranch(this);
+      size++;
+
+      if (inst >= (int) BranchOp.br && inst != (int) BranchOp.leave_s) {
+              shortVer = false;
+              size += 3;
+      }
+    }
+
+    internal sealed override bool Check(MetaData md) {
+      target = (int)dest.GetLabelOffset() - (int)(offset + size);
+      return false;
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        if (shortVer)
+                                output.Write((sbyte)target);
+                        else
+                                output.Write(target);
+                }
+
+  }
+
+  internal class SwitchInstr : Instr {
+    CILLabel[] cases;
+                uint numCases = 0;
+
+    internal SwitchInstr(int inst, CILLabel[] dsts) : base(inst) {
+      cases = dsts;
+                        if (cases != null) numCases = (uint)cases.Length;
+      size += 4 + (numCases * 4);
+      for (int i=0; i < numCases; i++) {
+        cases[i].AddBranch(this);
+      }
+    }
+
+                internal sealed override void Write(FileImage output) {
+                        base.Write(output);
+                        output.Write(numCases);
+                        for (int i=0; i < numCases; i++) {
+                                int target = (int)cases[i].GetLabelOffset() - (int)(offset + size);
+                                output.Write(target);
+                        }
+                }
+
+  }
+  /**************************************************************************/  
+
+        public class GenericParameter : MetaDataElement
+        {
+                MetaDataElement owner;
+                MetaData metadata;
+                string name;
+                uint nameIx;
+                short index;
+
+                internal GenericParameter (ClassDef owner, MetaData metadata,
+                                short index, string name) : this (owner, metadata, index, name, true)
+                {
+                }
+
+                internal GenericParameter (MethodDef owner, MetaData metadata,
+                                short index, string name) : this (owner, metadata, index, name, true)
+                {
+                }
+
+                private GenericParameter (MetaDataElement owner, MetaData metadata,
+                                short index, string name, bool nadda)
+                {
+                        this.owner = owner;
+                        this.metadata = metadata;
+                        this.index = index;
+                        tabIx = MDTable.GenericParam;
+                        this.name = name;
+                }
+
+    internal override uint SortKey() {
+      return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
+              | owner.GetCodedIx(CIx.TypeOrMethodDef);
+    }
+
+                public void AddConstraint  (Type constraint) {
+                        metadata.AddToTable (MDTable.GenericParamConstraint,
+                                        new GenericParamConstraint (this, constraint));
+                }
+
+                internal sealed override uint Size(MetaData md) {
+                        return (uint) (4 +
+                               md.CodedIndexSize(CIx.TypeOrMethodDef) + 
+                               4 +
+                               md.TableIndexSize(MDTable.TypeDef));
+                }
+
+                internal sealed override void BuildTables(MetaData md) {
+                        if (done) return;
+                        nameIx = md.AddToStringsHeap(name);
+                        done = true;
+                }
+
+                internal sealed override void Write(FileImage output) {
+                        output.Write ((short) index);
+                        output.Write ((short) 0);
+                        output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
+                        output.Write ((uint) nameIx);
+                        output.WriteIndex(MDTable.TypeDef,owner.Row);
+                }
+
+    
+        }
+
+        internal class GenericParamConstraint : MetaDataElement
+        {
+                GenericParameter param;
+                Type type;
+
+                public GenericParamConstraint (GenericParameter param, Type type) {
+                        this.param = param;
+                        this.type = type;
+                        tabIx = MDTable.GenericParamConstraint;
+                }
+
+                internal sealed override uint Size(MetaData md) {
+                        return (uint) (md.TableIndexSize(MDTable.GenericParam) +
+                                       md.CodedIndexSize(CIx.TypeDefOrRef));
+                }
+
+                internal sealed override void Write(FileImage output) {
+                        output.WriteIndex(MDTable.GenericParam, param.Row);
+                        output.WriteCodedIndex(CIx.TypeDefOrRef, type);
+                }
+
+
+        }
+
+        internal class MethodSpec : MetaDataElement
+        {
+                Method meth;
+                GenericMethodSig g_sig;
+                uint sidx;
+
+                internal MethodSpec (Method meth, GenericMethodSig g_sig) {
+                        this.meth = meth;
+                        this.g_sig = g_sig;
+                        tabIx = MDTable.MethodSpec;
+                }
+
+                internal sealed override void BuildTables (MetaData md) {
+                        if (done) return;
+                        sidx = g_sig.GetSigIx (md);
+                        done = true;
+                }
+
+                internal sealed override uint Size (MetaData md) {
+                        return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
+                                       md.BlobIndexSize ());
+                }
+
+                internal sealed override void Write (FileImage output) {
+                    output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
+                    output.BlobIndex (sidx);
+                }
+        }
+
+  /**************************************************************************/
+        /// <summary>
+        /// Descriptor for interface implemented by a class
+        /// </summary>
+        public class InterfaceImpl: MetaDataElement
+        { 
+    ClassDef theClass;
+    Class theInterface;
+
+                internal InterfaceImpl(ClassDef theClass, Class theInterface) {
+      this.theClass = theClass;
+      this.theInterface = theInterface;
+                        tabIx = MDTable.InterfaceImpl;
+                }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.TableIndexSize(MDTable.TypeDef) + 
+             md.CodedIndexSize(CIx.TypeDefOrRef);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteIndex(MDTable.TypeDef,theClass.Row);
+      output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) { return 5; }
+
+    internal override uint SortKey ()
+    {
+        return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
+                | theClass.GetCodedIx (CIx.TypeDefOrRef);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a local of a method
+        /// </summary>
+  public class Local
+        {
+    private static readonly byte Pinned = 0x45;
+    string name;
+    Type type;
+    bool pinned = false, byref = false;
+
+    /// <summary>
+    /// Create a new local variable 
+    /// </summary>
+    /// <param name="lName">name of the local variable</param>
+    /// <param name="lType">type of the local variable</param>
+    public Local(string lName, Type lType) {
+      name = lName;
+      type = lType;
+    }
+
+    /// <summary>
+    /// Create a new local variable that is byref and/or pinned
+    /// </summary>
+    /// <param name="lName">local name</param>
+    /// <param name="lType">local type</param>
+    /// <param name="byRef">is byref</param>
+    /// <param name="isPinned">has pinned attribute</param>
+                public Local(string lName, Type lType, bool byRef, bool isPinned)
+                {
+      name = lName;
+      type = lType;
+      byref = byRef;
+      pinned = isPinned;
+                }
+
+    internal void TypeSig(MemoryStream str) {
+      if (pinned) str.WriteByte(Pinned);
+      type.TypeSig(str);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for the locals for a method
+        /// </summary>
+
+  public class LocalSig : Signature
+        {
+                private static readonly byte LocalSigByte = 0x7;
+    Local[] locals;
+
+                public LocalSig(Local[] locals)         {
+      this.locals = locals;
+      tabIx = MDTable.StandAloneSig;
+                }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      MemoryStream sig = new MemoryStream();
+      sig.WriteByte(LocalSigByte);
+      MetaData.CompressNum((uint)locals.Length,sig);
+      for (int i=0; i < locals.Length; i++) {
+        ((Local)locals[i]).TypeSig(sig);
+      }
+      sigIx = md.AddToBlobHeap(sig.ToArray());
+      done = true;
+    }
+
+  }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for resources used in this PE file 
+        /// </summary>
+
+  public class ManifestResource : MetaDataElement
+        {
+    public static readonly uint PublicResource = 0x1;
+    public static readonly uint PrivateResource = 0x2;
+
+    string mrName;
+    MetaDataElement rRef;
+    uint fileOffset;
+    uint nameIx = 0;
+    uint flags = 0;
+    byte [] resourceBytes;
+
+    public ManifestResource (string name, byte[] resBytes, uint flags) {
+      InitResource (name, flags);
+      this.resourceBytes = resBytes;
+    }
+
+    public ManifestResource(string name, uint flags, FileRef fileRef) {
+      InitResource (name, flags);
+      rRef = fileRef;
+    }
+
+    public ManifestResource(string name, uint flags, FileRef fileRef, 
+                                                            uint fileIx) {
+      InitResource (name, flags);
+      rRef = fileRef;
+      fileOffset = fileIx;
+    }
+
+    public ManifestResource(string name, uint flags, AssemblyRef assemRef) {
+      InitResource (name, flags);
+      rRef = assemRef;
+    }
+
+    internal ManifestResource (ManifestResource mres) {
+      mrName = mres.mrName;
+      flags = mres.flags;
+      this.rRef = rRef;
+      this.fileOffset = fileOffset;
+      this.resourceBytes = resourceBytes;
+    }
+
+    private void InitResource (string name, uint flags) {
+      mrName = name;
+      this.flags = flags;
+      tabIx = MDTable.ManifestResource;
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      md.AddToTable (MDTable.ManifestResource, this);
+      nameIx = md.AddToStringsHeap(mrName);
+      if (resourceBytes != null) {
+        if (rRef != null)
+          throw new Exception("ERROR:  Manifest Resource has byte value and file reference");
+        fileOffset = md.AddResource(resourceBytes);
+      } else {
+        if (rRef == null)
+          throw new Exception("ERROR:  Manifest Resource has no implementation or value");
+       rRef.BuildTables (md);
+      }
+
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 8 + md.StringsIndexSize() + 
+                 md.CodedIndexSize(CIx.Implementation);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(fileOffset);
+      output.Write(flags);
+      output.StringsIndex(nameIx);
+      output.WriteCodedIndex(CIx.Implementation,rRef);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) { return 18; }
+    
+    public string Name {
+      get { return mrName; }
+      set { mrName = value; }
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for elements in the PropertyMap, EventMap and 
+        /// NestedClass MetaData tables
+        /// </summary>
+  public class MapElem : MetaDataElement
+        {
+    ClassDef parent;
+    uint elemIx;
+    MDTable elemTable;
+
+                internal MapElem(ClassDef par, uint elIx, MDTable elemTab) {
+      parent = par;
+      elemIx = elIx;
+      elemTable = elemTab;
+                }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteIndex(MDTable.TypeDef,parent.Row);
+      output.WriteIndex(elemTable,elemIx);
+    }
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for field/methods (member of a class)
+        /// </summary>
+        public abstract class Member : MetaDataElement
+        {
+    protected string name;
+    protected uint nameIx = 0, sigIx = 0;
+    
+                internal Member(string memName)
+                {
+      name = memName;
+                        tabIx = MDTable.MemberRef;
+                }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+  /// 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)
+  /// </summary>
+
+  public class MetaData 
+        {
+                internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
+                private static readonly byte StringsHeapMask = 0x1;
+                private static readonly byte GUIDHeapMask = 0x2;
+                private static readonly byte BlobHeapMask = 0x4;
+    private static readonly uint MetaDataSignature = 0x424A5342;
+    private static readonly uint maxSmlIxSize = 0xFFFF;
+    private static readonly uint max1BitSmlIx = 0x7FFF;
+    private static readonly uint max2BitSmlIx = 0x3FFF;
+    private static readonly uint max3BitSmlIx = 0x1FFF;
+    private static readonly uint max5BitSmlIx = 0x7FF;
+    // NOTE: version and stream name strings MUST always be quad padded
+    private static readonly string version = "v1.0.3705\0\0\0";
+    private static readonly char[] tildeName = {'#','~','\0','\0'};
+    private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
+    private static readonly char[] usName = {'#','U','S','\0'};
+    private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
+    private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
+                private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
+    private static readonly uint TildeHeaderSize = 24;
+    private static readonly uint StreamHeaderSize = 8;
+    private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
+    private static readonly uint tildeHeaderSize = 8 + (uint)tildeName.Length;
+
+    MetaDataStream strings, us, guid, blob;
+
+    MetaDataStream[] streams = new MetaDataStream[5];
+    uint numStreams = 5;
+    uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
+    uint numTables = 0, resourcesSize = 0;
+    ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
+    ArrayList byteCodes = new ArrayList();
+    uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
+                ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
+    bool[] largeIx = new bool[numMetaDataTables];
+    bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
+                bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
+                private FileImage file;
+    private byte heapSizes = 0;
+                MetaDataElement entryPoint;
+                BinaryWriter output;
+    public MSCorLib mscorlib;
+    private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
+    long mdStart;
+                private ArrayList cattr_list;
+    ArrayList resources;            
+                
+    internal MetaData(FileImage file) {
+      // tilde = new MetaDataStream(tildeName,false,0);
+      this.file = file;
+                        strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
+      us = new MetaDataStream(usName,new UnicodeEncoding(),true);
+      guid = new MetaDataStream(guidName,false);
+      blob = new MetaDataStream(blobName,true);
+      streams[1] = strings;
+      streams[2] = us;
+      streams[3] = guid;
+      streams[4] = blob;
+      for (int i=0; i < numMetaDataTables; i++) {
+        largeIx[i] = false;
+      }
+      for (int i=0; i < lgeCIx.Length; i++) {
+        lgeCIx[i] = false;
+      }
+      mscorlib = new MSCorLib(this);
+                }
+    internal TypeSpec GetPrimitiveTypeSpec(int ix) {
+      return systemTypeSpecs[ix];
+    }
+
+    internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec) {
+      systemTypeSpecs[ix] = typeSpec;
+    }
+
+    internal uint Size() {
+      return metaDataSize;
+    }
+
+    
+    private void CalcHeapSizes ()
+    {
+            if (strings.LargeIx()) {
+                    largeStrings = true;
+                    heapSizes |= StringsHeapMask;
+            }
+            if (guid.LargeIx()) {
+                    largeGUID = true;
+                    heapSizes |= GUIDHeapMask;
+            }
+            if (blob.LargeIx()) {
+                    largeBlob = true;
+                    heapSizes |= BlobHeapMask;
+            }
+
+            largeUS = us.LargeIx();
+   }
+
+                internal void StreamSize(byte mask) {
+                        heapSizes |= mask;
+                }
+
+    internal uint AddToUSHeap(string str) {
+      if (str == null) return 0;
+      return us.Add(str,true);
+   }
+
+                internal uint AddToUSHeap(byte[] str) {
+                        if (str == null) return 0;
+                        return us.Add (str, true);
+                }
+                                
+    internal uint AddToStringsHeap(string str) {
+      if ((str == null) || (str.CompareTo("") == 0)) return 0;
+      return strings.Add(str,false);
+    }
+
+    internal uint AddToGUIDHeap(Guid guidNum) {
+      return guid.Add(guidNum, false);
+    }
+
+    internal uint AddToBlobHeap(byte[] blobBytes) {
+      if (blobBytes == null) return 0;
+      return blob.Add(blobBytes, true);
+    }
+
+    internal uint AddToBlobHeap(byte val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(sbyte val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(ushort val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(short val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(uint val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(int val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(ulong val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(long val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(float val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(double val) {
+      return blob.Add(val, true);
+    }
+
+    internal uint AddToBlobHeap(string val) {
+      return blob.Add(val,true);
+    }
+
+                internal void AddCustomAttribute (CustomAttribute cattr)
+                {
+                        if (cattr_list == null)
+                                cattr_list = new ArrayList ();
+                        cattr_list.Add (cattr);
+                }
+
+    private ArrayList GetTable(MDTable tableIx) {
+      int tabIx = (int)tableIx;
+      if (metaDataTables[tabIx] == null) {
+        metaDataTables[tabIx] = new ArrayList();
+        valid |= ((ulong)0x1 << tabIx);
+        // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
+        numTables++;
+      }
+      return metaDataTables[tabIx];
+    }
+    internal void AddToTable(MDTable tableIx, MetaDataElement elem) {
+      if (elem.Row > 0) {
+        // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
+        return;
+      }
+      // updates Row field of the element
+      // Console.WriteLine("Adding element to table " + (uint)tableIx);
+      ArrayList table = GetTable(tableIx);
+      elem.Row = (uint)table.Count + 1;
+      table.Add(elem);
+    }
+
+    internal uint TableIndex(MDTable tableIx) {
+      if (metaDataTables[(int)tableIx] == null) return 1;
+      return (uint)metaDataTables[(int)tableIx].Count+1;
+    }
+
+    internal uint AddCode(CILInstructions byteCode) {
+      byteCodes.Add(byteCode);
+      uint offset = codeSize + codeStart;
+      codeSize += byteCode.GetCodeSize();
+      return offset;
+    }
+
+    internal void SetEntryPoint(MetaDataElement ep) {
+      entryPoint = ep;
+    }
+
+    internal uint AddResource(byte[] resBytes) {
+      if (resources == null) resources = new ArrayList ();
+      resources.Add (resBytes);
+      uint offset = resourcesSize;
+      resourcesSize += (uint)resBytes.Length + 4;
+      return offset;
+    }
+
+    internal void AddData(DataConstant cVal) {
+      file.AddInitData(cVal);
+    }
+
+                internal static void CompressNum(uint val, MemoryStream sig) {
+                        if (val < 0x7F) {
+                                sig.WriteByte((byte)val);
+                        } else if (val < 0x3FFF) {
+                                byte b1 = (byte)((val >> 8) | 0x80);
+                                byte b2 = (byte)(val & FileImage.iByteMask[0]);
+                                sig.WriteByte(b1);
+                                sig.WriteByte(b2);
+                        } else {
+                                byte b1 = (byte)((val >> 24) | 0xC0);
+                                byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
+                                byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
+                                byte b4 = (byte)(val & FileImage.iByteMask[0]);
+                                sig.WriteByte(b1);
+                                sig.WriteByte(b2);
+                                sig.WriteByte(b3);
+                                sig.WriteByte(b4);
+                        }
+                }
+
+    internal uint CodeSize() {
+      return codeSize + byteCodePadding;
+    }
+
+    internal uint GetResourcesSize() 
+    { 
+        return resourcesSize; 
+    }
+
+    internal uint StringsIndexSize() {
+      if (largeStrings) return 4;
+      return 2;
+    }
+
+    internal uint GUIDIndexSize() {
+      if (largeGUID) return 4;
+      return 2;
+    }
+
+    internal uint USIndexSize() {
+      if (largeUS) return 4;
+      return 2;
+    }
+
+    internal uint BlobIndexSize() {
+      if (largeBlob) return 4;
+      return 2;
+    }
+
+    internal uint CodedIndexSize(CIx code) {
+      if (lgeCIx[(uint)code]) return 4;
+      return 2;
+    }
+
+    internal uint TableIndexSize(MDTable tabIx) {
+      if (largeIx[(uint)tabIx]) return 4;
+      return 2;
+    }
+    
+    private void SetIndexSizes() {
+      for (int i=0; i < numMetaDataTables; i++) {
+          if (metaDataTables[i] == null)
+                  continue;
+
+          uint count = (uint)metaDataTables[i].Count;
+          if (count > maxSmlIxSize)
+                  largeIx[i] = true;
+
+            MDTable tabIx = (MDTable)i;
+            if (count > max5BitSmlIx) {
+              lgeCIx[(int)CIx.HasCustomAttr] = true;
+            }
+            if (count > max3BitSmlIx) {
+              if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field)) 
+                lgeCIx[(int)CIx.CustomAttributeType] = true;
+              if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef)) 
+                lgeCIx[(int)CIx.MemberRefParent] = true;
+            }
+            if (count > max2BitSmlIx) {
+              if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property)) 
+                lgeCIx[(int)CIx.HasConst] = true;
+              if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
+                lgeCIx[(int)CIx.TypeDefOrRef] = true;
+              if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
+                lgeCIx[(int)CIx.HasDeclSecurity] = true;
+              if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
+                lgeCIx[(int)CIx.Implementation] = true;
+              if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
+                lgeCIx[(int)CIx.ResolutionScope] = true;
+            }
+            if (count > max1BitSmlIx) {
+              if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param)) 
+                lgeCIx[(int)CIx.HasFieldMarshal] = true;
+              if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property)) 
+                lgeCIx[(int)CIx.HasSemantics] = true;
+              if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef)) 
+                lgeCIx[(int)CIx.MethodDefOrRef] = true;
+              if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method)) 
+                lgeCIx[(int)CIx.MemberForwarded] = true; 
+              if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method)) 
+                lgeCIx[(int)CIx.TypeOrMethodDef] = true; 
+            }
+      }
+    }
+
+    private void SetStreamOffsets() {
+      uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
+      for (int i=1; i < numStreams; i++) {
+        sizeOfHeaders += streams[i].headerSize();
+      }
+      metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
+      tildeStart = metaDataSize;
+      metaDataSize += tildeTide + tildePadding;
+      for (int i=1; i < numStreams; i++) {
+        streams[i].Start = metaDataSize;
+        metaDataSize += streams[i].Size();
+        streams[i].WriteDetails();
+      }
+    }
+
+    internal void CalcTildeStreamSize() {
+CalcHeapSizes ();
+      //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
+      tildeTide = TildeHeaderSize;
+      tildeTide += 4 * numTables;
+      //Console.WriteLine("Tilde header + sizes = " + tildeTide);
+      for (int i=0; i < numMetaDataTables; i++) {
+        if (metaDataTables[i] != null) {
+          ArrayList table = metaDataTables[i];
+          // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
+          tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
+          // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
+          // Console.WriteLine("tildeTide = " + tildeTide);
+        }
+      }
+      if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
+      //Console.WriteLine("tildePadding = " + tildePadding);
+    }
+
+    internal void WriteTildeStream(FileImage output) {
+      long startTilde = output.Seek(0,SeekOrigin.Current);
+                        output.Write((uint)0); // Reserved
+                        output.Write((byte)1); // MajorVersion
+                        output.Write((byte)0); // MinorVersion
+                        output.Write(heapSizes);
+                        output.Write((byte)1); // Reserved
+                        output.Write(valid);
+                        output.Write(sorted);
+                        for (int i=0; i < numMetaDataTables; i++) {
+                                if (metaDataTables[i] != null) {
+                                        uint count = (uint)metaDataTables[i].Count;
+                                        output.Write(count);
+                                }
+                        }
+      long tabStart = output.Seek(0,SeekOrigin.Current);
+      // Console.WriteLine("Starting metaData tables at " + tabStart);
+                        for (int i=0; i < numMetaDataTables; i++) {
+                                if (metaDataTables[i] != null) {
+          // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
+          ArrayList table = metaDataTables[i];
+                                        for (int j=0; j < table.Count; j++) {
+             ((MetaDataElement)table[j]).Write(output);
+                                        }
+                                }
+                        }
+      // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
+      for (int i=0; i < tildePadding; i++) output.Write((byte)0);
+                }
+
+    private void BuildTable(ArrayList table) {
+      if (table == null) return;
+      for (int j=0; j < table.Count; j++) {
+        ((MetaDataElement)table[j]).BuildTables(this);
+      }
+    }
+
+    private void SortTable (ArrayList mTable) {
+      if (mTable == null) return;
+      mTable.Sort();
+      for (int i=0; i < mTable.Count; i++) {
+        ((MetaDataElement)mTable[i]).Row = (uint)i+1;
+      }
+    }
+
+    internal void BuildMetaData(uint codeStartOffset) {
+      codeStart = codeStartOffset;
+      BuildTable(metaDataTables[(int)MDTable.TypeDef]);
+      BuildTable(metaDataTables[(int)MDTable.MemberRef]);
+      BuildTable(metaDataTables[(int)MDTable.GenericParam]);
+      BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
+      BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
+      BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
+
+      if (cattr_list != null) {
+              foreach (CustomAttribute cattr in cattr_list)
+                      cattr.BuildTables (this);
+      }
+
+/*      for (int i=0; i < metaDataTables.Length; i++) {
+        ArrayList table = metaDataTables[i];
+        if (table != null) {
+          for (int j=0; j < table.Count; j++) {
+            ((MetaDataElement)table[j]).BuildTables(this);
+          }
+        }
+      }
+      */
+
+                        SetIndexSizes();
+                        for (int i=1; i < numStreams; i++) {
+                                streams[i].EndStream();
+                        }
+                        CalcTildeStreamSize();
+                        SetStreamOffsets();
+      byteCodePadding = NumToAlign(codeSize,4);
+      if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
+      
+      // Check ordering of specific tables
+      // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
+      // ImplMap, GenericParam
+      // Need to load GenericParamConstraint AFTER GenericParam table in correct order
+      // The tables:
+      //   InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
+      // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
+      
+      SortTable(metaDataTables[(int)MDTable.Constant]);
+      SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
+      SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
+      SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
+      SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
+      SortTable(metaDataTables[(int)MDTable.ImplMap]);
+      if (metaDataTables[(int)MDTable.GenericParam] != null) {
+        SortTable(metaDataTables[(int)MDTable.GenericParam]);
+        // Now add GenericParamConstraints
+        /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
+          ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
+        }*/
+      }
+      SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
+      SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
+
+    }
+
+    internal void WriteByteCodes(FileImage output) {
+      for (int i=0; i < byteCodes.Count; i++) {
+        ((CILInstructions)byteCodes[i]).Write(output);
+      }
+      for (int i=0; i < byteCodePadding; i++) {
+        output.Write((byte)0);
+      }
+    }
+
+    internal void WriteResources (FileImage output) {
+      if (resources == null) return;
+      for (int i = 0; i < resources.Count; i ++) {
+        byte [] resBytes = (byte []) resources [i];
+        output.Write ((uint) resBytes.Length);
+        output.Write (resBytes);
+      } 
+    }
+
+    internal void WriteMetaData(FileImage output) {
+                        this.output = output;
+      mdStart = output.Seek(0,SeekOrigin.Current);
+      // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
+      output.Write(MetaDataSignature);
+      output.Write((short)1);  // Major Version
+      output.Write((short)1);  // Minor Version  ECMA = 0, PEFiles = 1
+      output.Write(0);         // Reserved
+      output.Write(version.Length);
+      output.Write(version.ToCharArray());   // version string is already zero padded
+      output.Write((short)0);
+      output.Write((ushort)numStreams);
+      // write tilde header
+      output.Write(tildeStart);
+      output.Write(tildeTide + tildePadding);
+      output.Write(tildeName);
+      for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
+      // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
+      WriteTildeStream(output);
+      for (int i=1; i < numStreams; i++) streams[i].Write(output);
+      // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
+    }
+
+                internal bool LargeStringsIndex() { return strings.LargeIx(); }
+                internal bool LargeGUIDIndex() { return guid.LargeIx(); }
+                internal bool LargeUSIndex() { return us.LargeIx(); }
+                internal bool LargeBlobIndex() { return blob.LargeIx(); }
+
+    internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
+
+
+                private uint NumToAlign(uint val, uint alignVal) {
+                        if ((val % alignVal) == 0) return 0;
+                        return alignVal - (val % alignVal);
+                }
+
+    internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output) {
+      uint ix = 0;
+      if (elem != null) { 
+        ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
+        // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
+      //} else {
+        // Console.WriteLine("elem for coded index is null");
+      }
+      if (lgeCIx[(uint)code]) 
+        output.Write(ix);
+      else
+        output.Write((ushort)ix);
+    }
+
+        }
+    /// <summary>
+    /// Error for invalid PE file
+    /// </summary>
+    public class PEFileException : System.Exception {
+      public PEFileException(string msg) : base("Error in PE File:  " + msg) { }
+    }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for all Meta Data table elements
+        /// </summary>
+
+  public abstract class MetaDataElement: IComparable
+        {
+
+    protected ArrayList customAttributes;
+    private uint row = 0;
+    protected bool done = false;
+                protected MDTable tabIx;
+    protected bool sortTable = false;
+
+    internal MetaDataElement() { }
+
+    public uint Row {
+      get {
+        return row;
+      }
+      set {
+        if (row == 0) row = value;
+      }
+    }
+
+    internal virtual uint GetCodedIx(CIx code) { return 0; }
+
+    /// <summary>
+    /// Add a custom attribute to this item
+    /// </summary>
+    /// <param name="ctorMeth">the constructor method for this attribute</param>
+    /// <param name="val">the byte value of the parameters</param>
+    public void AddCustomAttribute(Method ctorMeth, byte[] val) {
+      if (customAttributes == null) {
+        customAttributes = new ArrayList();
+      } 
+      customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
+    }
+
+    /// <summary>
+    /// Add a custom attribute to this item
+    /// </summary>
+    /// <param name="ctorMeth">the constructor method for this attribute</param>
+    /// <param name="val">the constant values of the parameters</param>
+    public void AddCustomAttribute(Method ctorMeth, Constant[] cVals) {
+      if (customAttributes == null) {
+        customAttributes = new ArrayList();
+      } 
+//      customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
+    }
+
+    internal uint Token() {
+      return (((uint)tabIx << 24) | row);
+    }
+
+    internal virtual void BuildTables(MetaData md) {
+      done = true;
+    }
+
+    internal virtual uint Size(MetaData md) { 
+      return 0;
+    }
+
+    internal virtual void Write(FileImage output) {   }
+
+    internal virtual uint SortKey() 
+    { 
+      throw new PEFileException("Trying to sort table of " + this);
+      //return 0; 
+    }
+
+    internal virtual uint SortKey2()
+    {
+      return 0;
+    }
+
+
+    public int CompareTo(object obj) 
+    {
+      uint otherKey = ((MetaDataElement)obj).SortKey();
+      uint thisKey = SortKey();
+
+      if (thisKey == otherKey) 
+      {
+        otherKey = ((MetaDataElement)obj).SortKey2();
+        thisKey = SortKey2();
+        if (thisKey == otherKey)
+          return 0;
+        if (thisKey < otherKey)
+          return -1;
+        return 1;
+      }
+      if (thisKey < otherKey) return -1;
+
+      return 1;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Stream in the Meta Data  (#Strings, #US, #Blob and #GUID)
+        /// </summary>
+
+  internal class MetaDataStream : BinaryWriter 
+        {
+                private static readonly uint StreamHeaderSize = 8;
+                private static uint maxSmlIxSize = 0xFFFF;
+                
+    private uint start = 0; 
+    uint size = 0, tide = 1;
+    bool largeIx = false;
+    uint sizeOfHeader;
+    char[] name;
+    Hashtable htable = new Hashtable();
+    Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
+
+    internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream()) {
+      if (addInitByte) { Write((byte)0); size = 1; }
+      this.name = name;
+      sizeOfHeader = StreamHeaderSize + (uint)name.Length;
+    }
+
+    internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc) {
+      if (addInitByte) { Write((byte)0); size = 1; }
+      this.name = name;
+      sizeOfHeader = StreamHeaderSize + (uint)name.Length;
+                }
+
+    public uint Start {
+      get {
+        return start;
+      }
+      set {
+        start = value;
+      }
+    }
+  
+    internal uint headerSize() {
+      // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
+      return sizeOfHeader;
+    }
+
+    internal void SetSize(uint siz) {
+      size = siz;
+    }
+
+    internal uint Size() {
+      return size;
+    }
+
+    internal bool LargeIx() {
+      return largeIx;
+    }
+
+    internal void WriteDetails() {
+      // Console.WriteLine(name + " - size = " + size);
+    }
+
+                internal uint Add(string str, bool prependSize) {
+      Object val = htable[str];
+      uint index = 0;
+      if (val == null) { 
+        index = size;
+        htable[str] = index;
+        char[] arr = str.ToCharArray();
+        if (prependSize) CompressNum((uint)arr.Length*2+1);
+        Write(arr);
+        Write((byte)0);
+        size = (uint)Seek(0,SeekOrigin.Current);
+      } else {
+        index = (uint)val;
+      }
+                        return index;
+                }
+                internal uint Add (byte[] str, bool prependSize) {
+                        Object val = btable [str];
+                        uint index = 0;
+                        if (val == null) {
+                                index = size;
+                                btable [str] = index;
+                                if (prependSize) CompressNum ((uint) str.Length);
+                                Write (str);
+                                size = (uint) Seek (0, SeekOrigin.Current);
+                        } else {
+                                index = (uint) val;
+                        }
+                        return index;
+                }
+
+                    
+                internal uint Add(Guid guid, bool prependSize) {
+                        byte [] b = guid.ToByteArray ();
+                        if (prependSize) CompressNum ((uint) b.Length);
+                        Write(guid.ToByteArray());
+                        size =(uint)Seek(0,SeekOrigin.Current);
+                        return tide++;
+                }
+
+                internal uint Add(byte[] blob) {
+                        uint ix = size;
+                        CompressNum((uint)blob.Length);
+                        Write(blob);
+                        size = (uint)Seek(0,SeekOrigin.Current);
+                        return ix;
+                }
+
+    internal uint Add(byte val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (1);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(sbyte val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (1);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(ushort val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (2);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(short val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (2);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(uint val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (4);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(int val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (4);
+      Write (val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(ulong val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (8);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(long val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (8);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(float val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (4);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+    internal uint Add(double val, bool prependSize) {
+      uint ix = size;
+      if (prependSize) CompressNum (8);
+      Write(val);
+      size = (uint)Seek(0,SeekOrigin.Current);
+      return ix;
+    }
+
+                private void CompressNum(uint val) {
+      if (val < 0x7F) {
+        Write((byte)val);
+      } else if (val < 0x3FFF) {
+        byte b1 = (byte)((val >> 8) | 0x80);
+        byte b2 = (byte)(val & FileImage.iByteMask[0]);
+        Write(b1);
+        Write(b2);
+      } else {
+        byte b1 = (byte)((val >> 24) | 0xC0);
+        byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
+        byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
+        byte b4 = (byte)(val & FileImage.iByteMask[0]);
+        Write(b1);
+        Write(b2);
+        Write(b3);
+        Write(b4);
+      }
+    }
+
+    private void QuadAlign() {
+      if ((size % 4) != 0) {
+        uint pad = 4 - (size % 4);
+        size += pad;
+        for (int i=0; i < pad; i++) {
+          Write((byte)0);
+        }
+      }
+    }
+
+                internal void EndStream() {
+                        QuadAlign();
+                        if (size > maxSmlIxSize) {
+                                largeIx = true;
+                        }
+                }
+
+    internal void WriteHeader(BinaryWriter output) {
+      output.Write(start);
+      output.Write(size);
+      output.Write(name);
+    }
+
+                internal virtual void Write(BinaryWriter output) {
+       // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
+      MemoryStream str = (MemoryStream)BaseStream;
+                        output.Write(str.ToArray());
+                }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for Method Descriptors
+        /// </summary>
+
+  public abstract class Method : Member
+        {
+    protected CallConv callConv = CallConv.Default;
+    protected Type retType;
+
+    internal Method(string methName, Type rType) : base(methName)
+                {
+      retType = rType;
+                }
+
+    /// <summary>
+    /// Add calling conventions to this method descriptor
+    /// </summary>
+    /// <param name="cconv"></param>
+    public void AddCallConv(CallConv cconv) {
+      callConv |= cconv;
+    }
+
+                internal abstract void TypeSig(MemoryStream sig);
+
+    internal uint GetSigIx(MetaData md) {
+      MemoryStream sig = new MemoryStream();
+                        TypeSig(sig);
+      return md.AddToBlobHeap(sig.ToArray());
+    }
+
+    internal Type GetRetType() {
+      return retType;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a method defined in THIS assembly/module
+        /// IL     .method
+        /// </summary>
+
+  public class MethodDef : Method
+        {
+    private static readonly ushort PInvokeImpl = 0x2000;
+    //private static readonly uint UnmanagedExport = 0x0008;
+   // private static readonly byte LocalSigByte = 0x7;
+    uint parIx = 0, textOffset = 0;
+
+    MetaData metaData;
+    CILInstructions code;
+    ArrayList securityActions = new ArrayList();
+                Param[] parList;
+    Local[] locals;
+    bool initLocals;
+    ushort methFlags = 0, implFlags = 0;
+    int maxStack = 0, numPars = 0;
+    bool entryPoint = false;
+    LocalSig localSig;
+                ArrayList varArgSigList;
+    ImplMap pinvokeImpl;
+
+
+                internal MethodDef(MetaData md, string name, Type retType, Param[] pars) : base(name,retType) {
+      metaData = md;
+                        parList = pars;
+                        if (parList != null) numPars = parList.Length;
+      tabIx = MDTable.Method;
+                }
+
+    internal MethodDef(MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, Type retType, Param[] pars) : base(name,retType) {
+      metaData = md;
+                        parList = pars;
+                        if (parList != null) numPars = parList.Length;
+      // Console.WriteLine("Creating method " + name + " with " + numPars + " parameters");
+                        methFlags = (ushort)mAttrSet;
+      implFlags = (ushort)iAttrSet;
+      tabIx = MDTable.Method;
+    }
+
+                internal Param[] GetPars() {
+                        return parList;
+                }
+
+    /// <summary>
+    /// Add some attributes to this method descriptor
+    /// </summary>
+    /// <param name="ma">the attributes to be added</param>
+    public void AddMethAttribute(MethAttr ma) {
+      methFlags |= (ushort)ma;
+    }
+
+    /// <summary>
+    /// Add some implementation attributes to this method descriptor
+    /// </summary>
+    /// <param name="ia">the attributes to be added</param>
+    public void AddImplAttribute(ImplAttr ia) {
+      implFlags |= (ushort)ia;
+    }
+
+    public void AddPInvokeInfo(ModuleRef scope, string methName,
+                               PInvokeAttr callAttr) {
+      pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
+      methFlags |= PInvokeImpl;
+    }
+
+    /// <summary>
+    ///  Add a named generic type parameter
+    /// </summary>
+    public GenericParameter AddGenericParameter (short index, string name) {
+            GenericParameter gp = new GenericParameter (this, metaData, index, name);
+            metaData.AddToTable (MDTable.GenericParam, gp);
+            return gp;
+    }
+
+    /// <summary>
+    /// Set the maximum stack height for this method
+    /// </summary>
+    /// <param name="maxStack">the maximum height of the stack</param>
+    public void SetMaxStack(int maxStack) {
+      this.maxStack = maxStack; 
+    }
+
+    /// <summary>
+    /// Add local variables to this method
+    /// </summary>
+    /// <param name="locals">the locals to be added</param>
+    /// <param name="initLocals">are locals initialised to default values</param>
+    public void AddLocals(Local[] locals, bool initLocals) {
+      this.locals = locals;
+      this.initLocals = initLocals;
+    }
+
+    /// <summary>
+    /// Mark this method as having an entry point
+    /// </summary>
+    public void DeclareEntryPoint() {
+      entryPoint = true;
+    }
+
+    /// <summary>
+    /// Create a code buffer for this method to add the IL instructions to
+    /// </summary>
+    /// <returns>a buffer for this method's IL instructions</returns>
+    public CILInstructions CreateCodeBuffer() {
+      code = new CILInstructions(metaData);
+      return code;
+    }
+
+    /// <summary>
+    /// Make a method reference descriptor for this method to be used 
+    /// as a callsite signature for this vararg method
+    /// </summary>
+    /// <param name="optPars">the optional pars for the vararg method call</param>
+    /// <returns></returns>
+    public MethodRef MakeVarArgSignature(Type[] optPars) {
+      Type[] pars = new Type[numPars];
+      MethodRef varArgSig;
+      for (int i=0; i < numPars; i++) {
+        pars[i] = parList[i].GetParType();
+      }
+      varArgSig = new MethodRef(this,name,retType,pars,true,optPars);
+
+      if (varArgSigList == null)
+              varArgSigList = new ArrayList ();
+      varArgSigList.Add (varArgSig);
+      return varArgSig;
+    }
+
+                internal sealed override void TypeSig(MemoryStream sig) {
+                        sig.WriteByte((byte)callConv);
+                        MetaData.CompressNum((uint)numPars,sig);
+                        retType.TypeSig(sig);
+                        for (ushort i=0; i < numPars; i++) {
+                                parList[i].seqNo = (ushort)(i+1);
+                                parList[i].TypeSig(sig);
+                        }
+                }
+
+    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);
+                        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 uint Size(MetaData md) {
+      return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      if (ZeroRva ()) output.Write(0);
+      else output.WriteCodeRVA(textOffset);
+      output.Write(implFlags);
+      output.Write(methFlags);
+      output.StringsIndex(nameIx);
+      output.BlobIndex(sigIx);
+      output.WriteIndex(MDTable.Param,parIx);
+    }
+
     internal bool ZeroRva () {
-       return ((methFlags & (ushort)MethAttr.Abstract) != 0);
-    }
-
-    internal sealed override uint GetCodedIx(CIx code) {\r
-                       switch (code) {\r
-                               case (CIx.HasCustomAttr) : return 0; \r
-                               case (CIx.HasDeclSecurity) : return 1; \r
-                               case (CIx.MemberRefParent) : return 3; \r
-                               case (CIx.MethodDefOrRef) : return 0; \r
-                               case (CIx.MemberForwarded) : return 1; \r
-                               case (CIx.CustomAttributeType) : return 2; \r
-                               case (CIx.TypeOrMethodDef) : return 1; \r
-                       }\r
-                       return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for an overriding method (.override)\r
-       /// </summary>\r
-  public class MethodImpl : MetaDataElement\r
-       {\r
-    ClassDef parent;\r
-    Method header, body;\r
-\r
-               internal MethodImpl(ClassDef par, Method decl, Method bod)      {\r
-      parent = par;\r
-      header = decl;\r
-      body = bod;\r
-                       tabIx = MDTable.MethodImpl;\r
-               }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteIndex(MDTable.TypeDef,parent.Row);\r
-      output.WriteCodedIndex(CIx.MethodDefOrRef,body);\r
-      output.WriteCodedIndex(CIx.MethodDefOrRef,header);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a method defined in another assembly/module\r
-       /// </summary>\r
-  public class MethodRef : Method\r
-  {\r
-    private static readonly byte Sentinel = 0x41;\r
-               Type[] parList, optParList;\r
-    MetaDataElement parent;\r
-    uint numPars = 0, numOptPars = 0;\r
-\r
-    internal MethodRef(MetaDataElement paren, string name, Type retType,\r
-        Type[] pars, bool varArgMeth, Type[] optPars) : base(name,retType) {\r
-      parent = paren;\r
-      parList = pars;\r
-      if (parList != null) numPars = (uint)parList.Length;\r
-      if (varArgMeth) {\r
-        optParList = optPars;\r
-        if (optParList != null) numOptPars = (uint)optParList.Length;\r
-        callConv = CallConv.Vararg;\r
-      }\r
-    }\r
-\r
-               internal sealed override void TypeSig(MemoryStream sig) {\r
-                       sig.WriteByte((byte)callConv);\r
-                       MetaData.CompressNum(numPars+numOptPars,sig);\r
-                       retType.TypeSig(sig);\r
-                       for (int i=0; i < numPars; i++) {\r
-                               parList[i].TypeSig(sig);\r
-                       }\r
-      if (numOptPars > 0) {\r
-        sig.WriteByte(Sentinel);\r
-        for (int i=0; i < numOptPars; i++) {\r
-          optParList[i].TypeSig(sig);\r
-        }\r
-      }\r
-               }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(name);\r
-      sigIx = GetSigIx(md);\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.WriteCodedIndex(CIx.MemberRefParent,parent);\r
-      output.StringsIndex(nameIx);\r
-      output.BlobIndex(sigIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 6; \r
-        case (CIx.MethodDefOrRef) : return 1; \r
-        case (CIx.CustomAttributeType) : return 3; \r
-      }\r
-                       return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for Property and Event methods\r
-       /// </summary>\r
-  public class MethodSemantics : MetaDataElement {\r
-\r
-    Feature.MethodType type;\r
-    MethodDef meth;\r
-    Feature eventOrProp;\r
-\r
-    internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature) {\r
-      type = mType;\r
-      meth = method;\r
-      eventOrProp = feature;\r
-                       tabIx = MDTable.MethodSemantics;\r
-               }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write((ushort)type);\r
-      output.WriteIndex(MDTable.Method,meth.Row);\r
-      output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a FunctionPointer type\r
-       /// </summary>\r
-       /// \r
-       public class MethPtrType : Type\r
-       {\r
-    // MethPtrType == FNPTR\r
-    Method method;\r
-    uint sigIx = 0;\r
-\r
-    /// <summary>\r
-    /// Create a new function pointer type\r
-    /// </summary>\r
-    /// <param name="meth">the function to be referenced</param>\r
-               public MethPtrType(Method meth) : base(0x1B)\r
-               {\r
-      method = meth;\r
-                       tabIx = MDTable.TypeSpec;\r
-               }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-      method.TypeSig(str);\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      MemoryStream sig = new MemoryStream();\r
-      TypeSig(sig);\r
-      sigIx = md.AddToBlobHeap(sig.ToArray());\r
-      done = true;\r
-    }\r
-\r
-               internal sealed override uint Size(MetaData md) {\r
-                       return md.BlobIndexSize();\r
-               }\r
-\r
-               internal sealed override void Write(FileImage output) {\r
-                       output.BlobIndex(sigIx);\r
-               }\r
-\r
-               internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for THIS module\r
-       /// </summary>\r
-  public class Module : ResolutionScope\r
-       {\r
-    Guid mvid;\r
-    uint mvidIx = 0;\r
-\r
-               internal Module(string name, MetaData md) : base(name,md)       {\r
-      mvid = Guid.NewGuid();\r
-      mvidIx = md.AddToGUIDHeap(mvid);\r
-      tabIx = MDTable.Module;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write((short)0);\r
-      output.StringsIndex(nameIx);\r
-      output.GUIDIndex(mvidIx);\r
-      output.GUIDIndex(0);\r
-      output.GUIDIndex(0);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-                       switch (code) {\r
-                               case (CIx.HasCustomAttr) : return 7; \r
-                               case (CIx.ResolutionScope) : return 0;\r
-                       }\r
-                       return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for another module in THIS assembly\r
-       /// </summary>\r
-  public class ModuleRef : ResolutionScope\r
-       {\r
-\r
-               internal ModuleRef(MetaData md, string name) : base(name,md) {\r
-      tabIx = MDTable.ModuleRef;\r
-               }\r
-\r
-    /// <summary>\r
-    /// Add a class to this external module.  This is a class declared in\r
-    /// another module of THIS assembly.\r
-    /// </summary>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns>a descriptor for this class in another module</returns>\r
-    public ClassRef AddClass(string nsName, string name, bool exportClass) {\r
-      ClassRef aClass = new ClassRef(nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeRef,aClass);\r
-      aClass.SetParent(this);\r
-      return aClass;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Make a file descriptor to correspond to this module.  The file\r
-    /// descriptor will have the same name as the module descriptor\r
-    /// </summary>\r
-    /// <param name="hashBytes">the hash of the file</param>\r
-    /// <param name="hasMetaData">the file contains metadata</param>\r
-    /// <param name="entryPoint">the program entry point is in this file</param>\r
-    /// <returns>a descriptor for the file which contains this module</returns>\r
-    public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint) {\r
-      FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);\r
-      metaData.AddToTable(MDTable.File,file);\r
-      return file;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a value class to this module.  This is a class declared in\r
-    /// another module of THIS assembly.\r
-    /// </summary>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns></returns>\r
-    public ClassRef AddValueClass(string nsName, string name) {\r
-      ClassRef aClass = new ClassRef(nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeRef,aClass);\r
-      aClass.SetParent(this);\r
-      aClass.MakeValueClass();\r
-      return aClass;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a class which is declared public in this external module of\r
-    /// THIS assembly.  This class will be exported from this assembly.\r
-    /// The ilasm syntax for this is .extern class\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes of the class to be exported</param>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">external class name</param>\r
-    /// <param name="declFile">the file where the class is declared</param>\r
-    /// <param name="isValueClass">is this class a value type?</param>\r
-    /// <returns>a descriptor for this external class</returns>\r
-    public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName, \r
-                                         string name, FileRef declFile, \r
-                                         bool isValueClass) {\r
-      ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);\r
-      metaData.AddToTable(MDTable.TypeRef,cRef);\r
-      cRef.SetParent(this);\r
-      if (isValueClass) cRef.MakeValueClass();\r
-      return cRef;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a "global" method in another module\r
-    /// </summary>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">method parameter types</param>\r
-    /// <returns>a descriptor for this method in anther module</returns>\r
-    public MethodRef AddMethod(string name, Type retType, Type[] pars) {\r
-      MethodRef meth = new MethodRef(this,name,retType,pars,false,null);\r
-      metaData.AddToTable(MDTable.MemberRef,meth);\r
-      return meth;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a vararg method to this class\r
-    /// </summary>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">parameter types</param>\r
-    /// <param name="optPars">optional param types for this vararg method</param>\r
-    /// <returns>a descriptor for this method</returns>\r
-    public MethodRef AddVarArgMethod(string name, Type retType, \r
-      Type[] pars, Type[] optPars) {\r
-      MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);\r
-      metaData.AddToTable(MDTable.MemberRef,meth);\r
-      return meth;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a field in another module\r
-    /// </summary>\r
-    /// <param name="name">field name</param>\r
-    /// <param name="fType">field type</param>\r
-    /// <returns>a descriptor for this field in another module</returns>\r
-    public FieldRef AddField(string name, Type fType) {\r
-      FieldRef field = new FieldRef(this,name,fType);\r
-      metaData.AddToTable(MDTable.MemberRef,field);\r
-      return field;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.StringsIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.StringsIndex(nameIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 12; \r
-        case (CIx.MemberRefParent) : return 2; \r
-        case (CIx.ResolutionScope) : return 1; \r
-      }\r
-                       return 0;\r
-    }\r
\r
-  }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptors for native types used for marshalling\r
-       /// </summary>\r
-  public class NativeType {\r
-    public static readonly NativeType Void = new NativeType(0x01);\r
-    public static readonly NativeType Boolean = new NativeType(0x02);\r
-    public static readonly NativeType Int8 = new NativeType(0x03);\r
-    public static readonly NativeType UInt8 = new NativeType(0x04);\r
-    public static readonly NativeType Int16 = new NativeType(0x05);\r
-    public static readonly NativeType UInt16 = new NativeType(0x06);\r
-    public static readonly NativeType Int32 = new NativeType(0x07);\r
-    public static readonly NativeType UInt32 = new NativeType(0x08);\r
-    public static readonly NativeType Int64 = new NativeType(0x09);\r
-    public static readonly NativeType UInt64 = new NativeType(0x0A);\r
-    public static readonly NativeType Float32 = new NativeType(0x0B);\r
-    public static readonly NativeType Float64 = new NativeType(0x0C);\r
-    public static readonly NativeType Currency = new NativeType(0x0F);\r
-    public static readonly NativeType BStr = new NativeType(0x13);\r
-    public static readonly NativeType LPStr = new NativeType(0x14);\r
-    public static readonly NativeType LPWStr = new NativeType(0x15);\r
-    public static readonly NativeType LPTStr = new NativeType(0x16);\r
-    public static readonly NativeType FixedSysString = new NativeType(0x17);\r
-    public static readonly NativeType IUnknown = new NativeType(0x19);\r
-    public static readonly NativeType IDispatch = new NativeType(0x1A);\r
-    public static readonly NativeType Struct = new NativeType(0x1B);\r
-    public static readonly NativeType Interface = new NativeType(0x1C);\r
-    public static readonly NativeType Int = new NativeType(0x1F);\r
-    public static readonly NativeType UInt = new NativeType(0x20);\r
-    public static readonly NativeType ByValStr = new NativeType(0x22);\r
-    public static readonly NativeType AnsiBStr = new NativeType(0x23);\r
-    public static readonly NativeType TBstr = new NativeType(0x24);\r
-    public static readonly NativeType VariantBool = new NativeType(0x25);\r
-    public static readonly NativeType FuncPtr = new NativeType(0x26);\r
-    public static readonly NativeType AsAny = new NativeType(0x28);\r
-\r
-    protected byte typeIndex;\r
-\r
-    internal NativeType(byte tyIx) { typeIndex = tyIx; }\r
-\r
-    internal byte GetTypeIndex() { return typeIndex; }\r
-\r
-    internal virtual byte[] ToBlob() {\r
-      byte[] bytes = new byte[1];\r
-      bytes[0] = GetTypeIndex();\r
-      return bytes;\r
-    }\r
-\r
-   }\r
-\r
-  public class NativeArray : NativeType \r
-  {\r
-    NativeType elemType;\r
-    uint len = 0, parNum = 0;\r
-\r
-    /*\r
-    public NativeArray(NativeType elemType) : base(0x2A) {\r
-      this.elemType = elemType;\r
-    }\r
-\r
-    public NativeArray(NativeType elemType, int len) : base(0x2A) {\r
-      this.elemType = elemType;\r
-      this.len = len;\r
-    }\r
-*/\r
-    public NativeArray(NativeType elemType, int numElem, int parNumForLen) : base(0x2A) {\r
-      this.elemType = elemType;\r
-      len = (uint)numElem;\r
-      parNum = (uint)parNumForLen;\r
-    }\r
-\r
-    internal override byte[] ToBlob() {\r
-      MemoryStream str = new MemoryStream();\r
-      str.WriteByte(GetTypeIndex());\r
-      if (elemType == null) str.WriteByte(0x50);  // no info (MAX)\r
-      else str.WriteByte(elemType.GetTypeIndex());\r
-      MetaData.CompressNum(parNum,str);\r
-      str.WriteByte(1);\r
-      MetaData.CompressNum(len,str);\r
-      return str.ToArray();\r
-    }\r
-\r
-  }\r
-\r
-  public class SafeArray : NativeType \r
-  {\r
-    SafeArrayType elemType;\r
-\r
-    public SafeArray(SafeArrayType elemType) : base(0x1D) {\r
-      this.elemType = elemType;\r
-    }\r
-\r
-    internal override byte[] ToBlob() {\r
-      byte[] bytes = new byte[2];\r
-      bytes[0] = GetTypeIndex();\r
-      bytes[1] = (byte)elemType;\r
-      return bytes;\r
-    }\r
-\r
-  }\r
-\r
-  public class FixedArray : NativeType \r
-  {\r
-    NativeType elemType;\r
-    uint numElem;\r
-\r
-    public FixedArray(NativeType elemType, int numElems) : base(0x1E) {\r
-      this.elemType = elemType;\r
-      numElem = (uint)numElems;\r
-    }\r
-\r
-    internal override byte[] ToBlob() {\r
-      MemoryStream str = new MemoryStream();\r
-      str.WriteByte(GetTypeIndex());\r
-      MetaData.CompressNum(numElem,str);\r
-      if (elemType == null) str.WriteByte(0x50);  // no info (MAX)\r
-      else str.WriteByte(elemType.GetTypeIndex());\r
-      return str.ToArray();\r
-    }\r
-\r
-  }\r
-\r
-  public class CustomMarshaller : NativeType \r
-  {\r
-    string typeName;\r
-    string marshallerName;\r
-    string cookie;\r
-\r
-    public CustomMarshaller(string typeNameOrGUID, string marshallerName, \r
-                string optCookie) : base(0x2C) {\r
-      typeName = typeNameOrGUID;\r
-      this.marshallerName = marshallerName;\r
-      cookie = optCookie;\r
-    }\r
-\r
-    internal override byte[] ToBlob() {\r
-      MemoryStream str = new MemoryStream();\r
-      BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());\r
-      bw.Write(GetTypeIndex());\r
-      bw.Write(typeName.ToCharArray());\r
-      bw.Write((byte)0);\r
-      bw.Write(marshallerName.ToCharArray());\r
-      bw.Write((byte)0);\r
-      if (cookie != null) bw.Write(cookie.ToCharArray());\r
-      bw.Write((byte)0);\r
-      bw.Flush();\r
-      return str.ToArray();\r
-    }\r
-  }\r
-\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a parameter of a method defined in this assembly/module\r
-       /// </summary>\r
-  public class Param : MetaDataElement\r
-       {\r
-    private static readonly ushort hasDefault = 0x1000;\r
-    private static readonly ushort hasFieldMarshal = 0x2000;\r
-\r
-    Type pType;\r
-    string pName;\r
-    internal ushort seqNo = 0;\r
-    ushort parMode;\r
-    ConstantElem defaultVal;\r
-    uint nameIx = 0;\r
-    FieldMarshal marshalInfo;\r
-\r
-    /// <summary>\r
-    /// Create a new parameter for a method\r
-    /// </summary>\r
-    /// <param name="mode">param mode (in, out, opt)</param>\r
-    /// <param name="parName">parameter name</param>\r
-    /// <param name="parType">parameter type</param>\r
-    public Param(ParamAttr mode, string parName, Type parType) {\r
-      pName = parName;\r
-      pType = parType;\r
-      parMode = (ushort)mode;\r
-                       tabIx = MDTable.Param;\r
-               }\r
-\r
-    /// <summary>\r
-    /// Add a default value to this parameter\r
-    /// </summary>\r
-    /// <param name="c">the default value for the parameter</param>\r
-    public void AddDefaultValue(Constant cVal) {\r
-      defaultVal = new ConstantElem(this,cVal);\r
-      parMode |= hasDefault;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add marshalling information about this parameter\r
-    /// </summary>\r
-    public void AddMarshallInfo(NativeType marshallType) {\r
-      parMode |= hasFieldMarshal;\r
-      marshalInfo = new FieldMarshal(this,marshallType);\r
-    }\r
-\r
-    internal Type GetParType() { return pType; }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(pName);\r
-      if (defaultVal != null) {\r
-        md.AddToTable(MDTable.Constant,defaultVal);\r
-        defaultVal.BuildTables(md);\r
-      }\r
-      if (marshalInfo != null) {\r
-        md.AddToTable(MDTable.FieldMarshal,marshalInfo);\r
-        marshalInfo.BuildTables(md);\r
-      }\r
-      done = true;\r
-    }\r
-\r
-    internal void TypeSig(MemoryStream str) {\r
-      pType.TypeSig(str);\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 4 + md.StringsIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(parMode);\r
-      output.Write(seqNo);\r
-      output.StringsIndex(nameIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.HasCustomAttr) : return 4; \r
-        case (CIx.HasConst) : return 1; \r
-        case (CIx.HasFieldMarshal) : return 1; \r
-      }\r
-                       return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for the PEFile (starting point)\r
-       /// </summary>\r
-  public class PEFile\r
-       {\r
-    private static readonly string mscorlibName = "mscorlib";\r
-    private Module thisMod;\r
-    private ClassDef moduleClass;\r
-    private ArrayList classRefList = new ArrayList();\r
-    private ArrayList classDefList = new ArrayList();\r
-    private Assembly thisAssembly;\r
-    private int corFlags = 1;\r
-    FileImage fileImage;\r
-               MetaData metaData;\r
-\r
-    /// <summary>\r
-    /// Create a new PEFile.  Each PEFile is a module.\r
-    /// </summary>\r
-    /// <param name="name">module name, also used for the file name</param>\r
-    /// <param name="isDLL">create a .dll or .exe file</param>\r
-    /// <param name="hasAssembly">this file is an assembly and \r
-    /// will contain the assembly manifest.  The assembly name is the \r
-    /// same as the module name</param>\r
-    public PEFile(string name, bool isDLL, bool hasAssembly) {\r
-      // Console.WriteLine(Hex.Byte(0x12));\r
-      // Console.WriteLine(Hex.Short(0x1234));\r
-      // Console.WriteLine(Hex.Int(0x12345678));\r
-      string fName = MakeFileName(null,name,isDLL);\r
-      fileImage = new FileImage(isDLL,fName);\r
-      InitPEFile(name, fName, hasAssembly);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new PEFile.  Each PEFile is a module.\r
-    /// </summary>\r
-    /// <param name="name">module name, also used for the file name</param>\r
-    /// <param name="isDLL">create a .dll or .exe file</param>\r
-    /// <param name="hasAssembly">this file is an assembly and \r
-    /// will contain the assembly manifest.  The assembly name is the \r
-    /// same as the module name</param>\r
-    /// <param name="outputDir">write the PEFile to this directory.  If this\r
-    /// string is null then the output will be to the current directory</param>\r
-    public PEFile(string name, bool isDLL, bool hasAssembly, string outputDir) {\r
-      // Console.WriteLine(Hex.Byte(0x12));\r
-      // Console.WriteLine(Hex.Short(0x1234));\r
-      // Console.WriteLine(Hex.Int(0x12345678));\r
-      string fName = MakeFileName(outputDir,name,isDLL);\r
-                       fileImage = new FileImage(isDLL,fName);\r
-      InitPEFile(name, fName, hasAssembly);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Create a new PEFile\r
-    /// </summary>\r
-    /// <param name="name">module name</param>\r
-    /// <param name="isDLL">create a .dll or .exe</param>\r
-    /// <param name="hasAssembly">this PEfile is an assembly and\r
-    /// will contain the assemly manifest.  The assembly name is the\r
-    /// same as the module name</param>\r
-    /// <param name="outStream">write the PEFile to this stream instead\r
-    /// of to a new file</param>\r
-    public PEFile(string name, bool isDLL, bool hasAssembly, Stream outStream) {\r
-      fileImage = new FileImage(isDLL,outStream);\r
-      InitPEFile(name, MakeFileName(null,name,isDLL), hasAssembly);\r
-    }\r
-\r
-    private void InitPEFile(string name, string fName, bool hasAssembly) {\r
-      metaData = fileImage.GetMetaData();\r
-      thisMod = new Module(fName,metaData);\r
-      if (hasAssembly) {\r
-        thisAssembly = new Assembly(name,metaData);\r
-        metaData.AddToTable(MDTable.Assembly,thisAssembly);      \r
-      }\r
-      moduleClass = AddClass(TypeAttr.Private,"","<Module>");\r
-      moduleClass.SpecialNoSuper();\r
-      metaData.AddToTable(MDTable.Module,thisMod);\r
-    }\r
\r
-    /// <summary>\r
-    /// Set the subsystem (.subsystem) (Default is Windows Console mode)\r
-    /// </summary>\r
-    /// <param name="subS">subsystem value</param>\r
-    public void SetSubSystem(SubSystem subS) {\r
-      fileImage.subSys = subS;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Set the flags (.corflags)\r
-    /// </summary>\r
-    /// <param name="flags">the flags value</param>\r
-    public void SetCorFlags(int flags) {\r
-      corFlags = flags;\r
-    }\r
-\r
-    private string MakeFileName(string dirName, string name, bool isDLL) {\r
-      string result = "";\r
-      if ((dirName != null) && (dirName.CompareTo("") != 0)) {\r
-        result = dirName;\r
-        if (!dirName.EndsWith("\\")) result += "\\";\r
-      }\r
-      result += name;\r
-       \r
-      // if (isDLL) result += ".dll";  else result += ".exe";\r
-      \r
-      return result;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an external assembly to this PEFile (.assembly extern)\r
-    /// </summary>\r
-    /// <param name="assemName">the external assembly name</param>\r
-    /// <returns>a descriptor for this external assembly</returns>\r
-    public AssemblyRef AddExternAssembly(string assemName) {\r
-      if (assemName.CompareTo(mscorlibName) == 0) return metaData.mscorlib;\r
-      AssemblyRef anAssem = new AssemblyRef(metaData,assemName);\r
-      metaData.AddToTable(MDTable.AssemblyRef,anAssem);\r
-      // Console.WriteLine("Adding assembly " + assemName);\r
-      return anAssem;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an external module to this PEFile (.module extern)\r
-    /// </summary>\r
-    /// <param name="name">the external module name</param>\r
-    /// <returns>a descriptor for this external module</returns>\r
-    public ModuleRef AddExternModule(string name) {\r
-      ModuleRef modRef = new ModuleRef(metaData,name);\r
-      metaData.AddToTable(MDTable.ModuleRef,modRef);\r
-      return modRef;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a "global" method to this module\r
-    /// </summary>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">method parameters</param>\r
-    /// <returns>a descriptor for this new "global" method</returns>\r
-    public MethodDef AddMethod(string name, Type retType, Param[] pars) {\r
-      return moduleClass.AddMethod(name,retType,pars);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a "global" method to this module\r
-    /// </summary>\r
-    /// <param name="mAtts">method attributes</param>\r
-    /// <param name="iAtts">method implementation attributes</param>\r
-    /// <param name="name">method name</param>\r
-    /// <param name="retType">return type</param>\r
-    /// <param name="pars">method parameters</param>\r
-    /// <returns>a descriptor for this new "global" method</returns>\r
-    public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, Type retType, Param[] pars) {\r
-      return moduleClass.AddMethod(mAtts,iAtts,name,retType,pars);\r
-    }\r
-\r
-    public MethodRef AddMethodToTypeSpec (Type item, string name, Type retType, Type[] pars) {\r
-            MethodRef meth = new MethodRef (item.GetTypeSpec (metaData), name, retType, pars, false, null);\r
-            metaData.AddToTable (MDTable.MemberRef,meth);\r
-            return meth;\r
-    }\r
-\r
-    public MethodRef AddVarArgMethodToTypeSpec (Type item, string name, Type retType,\r
-                    Type[] pars, Type[] optPars) {\r
-            MethodRef meth = new MethodRef(item.GetTypeSpec (metaData), name,retType,pars,true,optPars);\r
-            metaData.AddToTable(MDTable.MemberRef,meth);\r
-            return meth;\r
-    }\r
-\r
-    public FieldRef AddFieldToTypeSpec (Type item, string name, Type fType) {\r
-            FieldRef field = new FieldRef (item.GetTypeSpec (metaData), name,fType);\r
-            metaData.AddToTable (MDTable.MemberRef,field);\r
-            return field;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a "global" field to this module\r
-    /// </summary>\r
-    /// <param name="name">field name</param>\r
-    /// <param name="fType">field type</param>\r
-    /// <returns>a descriptor for this new "global" field</returns>\r
-    public FieldDef AddField(string name, Type fType) {\r
-      return moduleClass.AddField(name,fType);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a "global" field to this module\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes of this field</param>\r
-    /// <param name="name">field name</param>\r
-    /// <param name="fType">field type</param>\r
-    /// <returns>a descriptor for this new "global" field</returns>\r
-    public FieldDef AddField(FieldAttr attrSet, string name, Type fType) {\r
-      return moduleClass.AddField(attrSet,name,fType);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a class to this module\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes of this class</param>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns>a descriptor for this new class</returns>\r
-    public ClassDef AddClass(TypeAttr attrSet, string nsName, string name) {\r
-      ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);\r
-      metaData.AddToTable(MDTable.TypeDef,aClass);\r
-      return aClass;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a class which extends System.ValueType to this module\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes of this class</param>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <returns>a descriptor for this new class</returns>\r
-    public ClassDef AddValueClass(TypeAttr attrSet, string nsName, string name) {\r
-      ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);\r
-      aClass.MakeValueClass();\r
-      metaData.AddToTable(MDTable.TypeDef,aClass);\r
-      return aClass;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a class to this module\r
-    /// </summary>\r
-    /// <param name="attrSet">attributes of this class</param>\r
-    /// <param name="nsName">name space name</param>\r
-    /// <param name="name">class name</param>\r
-    /// <param name="superType">super type of this class (extends)</param>\r
-    /// <returns>a descriptor for this new class</returns>\r
-    public ClassDef AddClass(TypeAttr attrSet, string nsName, string name, Class superType) {\r
-      ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);\r
-      aClass.SetSuper(superType);\r
-      metaData.AddToTable(MDTable.TypeDef,aClass);\r
-      return aClass;\r
-    }\r
-\r
-    public FileRef AddFile(string fName, byte[] hashBytes, bool hasMetaData, bool entryPoint) {\r
-      FileRef file = new FileRef(fName,hashBytes,hasMetaData,entryPoint,metaData);\r
-      metaData.AddToTable(MDTable.File,file);\r
-      return file;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a manifest resource to this PEFile NOT YET IMPLEMENTED\r
-    /// </summary>\r
-    /// <param name="mr"></param>\r
-    public void AddManifestResource(ManifestResource mr) {\r
-      metaData.AddToTable(MDTable.ManifestResource,mr);\r
-      //mr.FixName(metaData);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Write out the PEFile (the "bake" function)\r
-    /// </summary>\r
-    public void WritePEFile() { /* the "bake" function */\r
-      fileImage.MakeFile();\r
-    }\r
-\r
-    /// <summary>\r
-    /// Get the descriptor of this module\r
-    /// </summary>\r
-    /// <returns>the descriptor for this module</returns>\r
-    public Module GetThisModule() {\r
-      return thisMod;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Get the descriptor for this assembly.  The PEFile must have been\r
-    /// created with hasAssembly = true\r
-    /// </summary>\r
-    /// <returns>the descriptor for this assembly</returns>\r
-    public Assembly GetThisAssembly() {\r
-      return thisAssembly;\r
-    }\r
-\r
-       }\r
-\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for the Primitive types defined in IL\r
-       /// </summary>\r
-  public class PrimitiveType : Type\r
-       {\r
-    private string name;\r
-    private int systemTypeIndex;\r
-    public static int NumSystemTypes = 18;\r
-\r
-    public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);\r
-    public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);\r
-    public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);\r
-    public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);\r
-    public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);\r
-    public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);\r
-    public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);\r
-    public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);\r
-    public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);\r
-    public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);\r
-    public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);\r
-    public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);\r
-    public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);\r
-    public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);\r
-               internal static readonly PrimitiveType Class = new PrimitiveType(0x12);\r
-    public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);\r
-    public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);\r
-    public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);\r
-    public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);\r
-    internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);\r
-    public static readonly PrimitiveType NativeInt = IntPtr;\r
-    public static readonly PrimitiveType NativeUInt = UIntPtr;\r
-\r
-    internal PrimitiveType(byte typeIx) : base(typeIx) { }\r
-\r
-               internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx) {\r
-      this.name = name;\r
-      this.systemTypeIndex = STIx;\r
-    }\r
-\r
-    internal string GetName() { return name; }\r
-\r
-    internal int GetSystemTypeIx() { return systemTypeIndex; }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-    }\r
-\r
-    internal override MetaDataElement GetTypeSpec(MetaData md) {\r
-      TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);\r
-      if (tS == null) {\r
-        tS = new TypeSpec(this,md);\r
-        md.SetPrimitiveTypeSpec(systemTypeIndex,tS);\r
-        md.AddToTable(MDTable.TypeSpec,tS);\r
-      }\r
-      return tS;\r
-    }\r
-\r
-       }\r
-\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for the Property of a class\r
-       /// </summary>\r
-  public class Property : Feature\r
-       {\r
-    private static readonly byte PropertyTag = 0x8;\r
-    MethodDef getterMeth;\r
-    ConstantElem constVal;\r
-    uint typeBlobIx = 0;\r
-    Type[] parList;\r
-    Type returnType;\r
-    uint numPars = 0;\r
-\r
-    internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent) {\r
-      returnType = retType;\r
-      parList = pars;\r
-      if (pars != null) numPars = (uint)pars.Length;\r
-                       tabIx = MDTable.Property;\r
-               }\r
-\r
-    /// <summary>\r
-    /// Add a set method to this property\r
-    /// </summary>\r
-    /// <param name="setter">the set method</param>\r
-    public void AddSetter(MethodDef setter) {\r
-      AddMethod(setter,MethodType.Setter);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add a get method to this property\r
-    /// </summary>\r
-    /// <param name="getter">the get method</param>\r
-    public void AddGetter(MethodDef getter) {\r
-      AddMethod(getter,MethodType.Getter);\r
-      getterMeth = getter;\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add another method to this property\r
-    /// </summary>\r
-    /// <param name="other">the method</param>\r
-    public void AddOther(MethodDef other) {\r
-      AddMethod(other,MethodType.Other);\r
-    }\r
-\r
-    /// <summary>\r
-    /// Add an initial value for this property\r
-    /// </summary>\r
-    /// <param name="constVal">the initial value for this property</param>\r
-    public void AddInitValue(Constant constVal) {\r
-      this.constVal = new ConstantElem(this,constVal);\r
-    }\r
-\r
-    internal sealed override void BuildTables(MetaData md) {\r
-      if (done) return;\r
-      nameIx = md.AddToStringsHeap(name);\r
-      MemoryStream sig = new MemoryStream();\r
-      sig.WriteByte(PropertyTag);\r
-      MetaData.CompressNum(numPars,sig);\r
-      returnType.TypeSig(sig);\r
-      for (int i=0; i < numPars; i++) {\r
-        parList[i].TypeSig(sig);\r
-      }\r
-      typeBlobIx = md.AddToBlobHeap(sig.ToArray());\r
-      for (int i=0; i < tide; i++) {\r
-        md.AddToTable(MDTable.MethodSemantics,methods[i]);\r
-      }\r
-      if (constVal != null) {\r
-        md.AddToTable(MDTable.Constant,constVal);\r
-        constVal.BuildTables(md);\r
-      }\r
-      done = true;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return 2 + md.StringsIndexSize() + md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.Write(flags);\r
-      output.StringsIndex(nameIx);\r
-      output.BlobIndex(typeBlobIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-                       switch (code) {\r
-                               case (CIx.HasCustomAttr) : return 9; \r
-                               case (CIx.HasConst) : return 2; \r
-                               case (CIx.HasSemantics) : return 1; \r
-                       }\r
-                       return 0;\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for an pointer (type * or type &)\r
-       /// </summary>\r
-  public abstract class PtrType : Type\r
-       {\r
-    Type baseType;\r
-\r
-               internal PtrType(Type bType, byte typeIx) : base(typeIx)\r
-               {\r
-      baseType = bType;\r
-      tabIx = MDTable.TypeSpec;\r
-               }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-      baseType.TypeSig(str);\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// Descriptor for a managed pointer (type &  or byref)\r
-  /// </summary>\r
-\r
-  public class ManagedPointer : PtrType  // <type> & (BYREF)  \r
-  {\r
-\r
-    /// <summary>\r
-    /// Create new managed pointer to baseType\r
-    /// </summary>\r
-    /// <param name="bType">the base type of the pointer</param>\r
-    public ManagedPointer(Type baseType) : base(baseType,0x10) { }\r
\r
-  }\r
-  /**************************************************************************/  \r
-  /// <summary>\r
-  /// Descriptor for an unmanaged pointer (type *)\r
-  /// </summary>\r
-  public class UnmanagedPointer : PtrType // PTR\r
-  {\r
-    /// <summary>\r
-    /// Create a new unmanaged pointer to baseType\r
-    /// </summary>\r
-    /// <param name="baseType">the base type of the pointer</param>\r
-    public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }\r
-\r
-  }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)\r
-       /// </summary>\r
-  public abstract class ResolutionScope : MetaDataElement\r
-       {\r
-    protected uint nameIx = 0;\r
-    protected MetaData metaData;\r
-    protected string name;\r
-\r
-               internal ResolutionScope(string name, MetaData md)\r
-               {\r
-      metaData = md;\r
-      this.name = name;\r
-      nameIx = md.AddToStringsHeap(name);\r
-               }\r
-\r
-    internal string GetName() { return name; }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a Section in a PEFile  eg .text, .sdata\r
-       /// </summary>\r
-  internal class Section {\r
-               private static readonly uint relocPageSize = 4096;  // 4K pages for fixups\r
-\r
-               char[] name; \r
-               uint offset = 0, tide = 0, size = 0, rva = 0, relocTide = 0;\r
-               //uint relocOff = 0;\r
-    uint flags = 0, padding = 0;\r
-               uint[] relocs; \r
-\r
-               internal Section(string sName, uint sFlags) {\r
-                       name = sName.ToCharArray();\r
-                       flags = sFlags;\r
-               }\r
-\r
-               internal uint Tide() { return tide; }\r
-\r
-               internal void IncTide(uint incVal) { tide += incVal; }\r
-\r
-               internal uint Padding() { return padding; }\r
-\r
-               internal uint Size() { return size; }\r
-\r
-               internal void SetSize(uint pad) {\r
-                       padding = pad;\r
-                       size = tide + padding;\r
-               }\r
-\r
-               internal uint RVA() { return rva; }\r
-\r
-               internal void SetRVA(uint rva) { this.rva = rva; }\r
-\r
-               internal uint Offset() { return offset; }\r
-\r
-               internal void SetOffset(uint offs) { offset = offs; }\r
-\r
-    internal void DoBlock(BinaryWriter reloc, uint page, int start, int end) {\r
-      //Console.WriteLine("rva = " + rva + "  page = " + page);\r
-      reloc.Write(rva + page);\r
-      reloc.Write((uint)(((end-start+1)*2) + 8));\r
-      for (int j=start; j < end; j++) {\r
-        //Console.WriteLine("reloc offset = " + relocs[j]);\r
-        reloc.Write((ushort)((0x3 << 12) | (relocs[j] - page)));\r
-      }\r
-      reloc.Write((ushort)0);\r
-    }\r
-\r
-               internal void DoRelocs(BinaryWriter reloc) {\r
-      if (relocTide > 0) {\r
-        //relocOff = (uint)reloc.Seek(0,SeekOrigin.Current);\r
-        uint block = (relocs[0]/relocPageSize + 1) * relocPageSize;\r
-        int start = 0;\r
-        for (int i=1; i < relocTide; i++) {\r
-          if (relocs[i] >= block) {\r
-            DoBlock(reloc,block-relocPageSize,start,i);\r
-            start = i;\r
-            block = (relocs[i]/relocPageSize + 1) * relocPageSize;\r
-          }\r
-        }\r
-        DoBlock(reloc,block-relocPageSize,start,(int)relocTide);\r
-      }\r
-               }\r
-\r
-               internal void AddReloc(uint offs) {\r
-                       int pos = 0;\r
-                       if (relocs == null) {\r
-                               relocs = new uint[5];\r
-                       } else {\r
-                               if (relocTide >= relocs.Length) {\r
-                                       uint[] tmp = relocs;\r
-                                       relocs = new uint[tmp.Length + 5];\r
-                                       for (int i=0; i < relocTide; i++) {\r
-                                               relocs[i] = tmp[i];\r
-                                       }\r
-                               }\r
-                               while ((pos < relocTide) && (relocs[pos] < offs)) pos++;\r
-                               for (int i=pos; i < relocTide; i++) {\r
-                                       relocs[i+1] = relocs[i];\r
-                               }\r
-                       }\r
-                       relocs[pos] = offs;\r
-                       relocTide++;    \r
-               }\r
-      \r
-               internal void WriteHeader(BinaryWriter output, uint relocRVA) {\r
-                       output.Write(name);\r
-                       output.Write(tide);\r
-                       output.Write(rva);\r
-                       output.Write(size);\r
-                       output.Write(offset);\r
-                       output.Write(0);\r
-                       //output.Write(relocRVA + relocOff);\r
-                       output.Write(0);\r
-      output.Write(0);\r
-                       //output.Write((ushort)relocTide);\r
-                       //output.Write((ushort)0);\r
-                       output.Write(flags);\r
-               }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-  public abstract class Signature : MetaDataElement \r
-  {\r
-    protected uint sigIx;\r
-\r
-    internal Signature() {\r
-      tabIx = MDTable.StandAloneSig;\r
-    }\r
-\r
-    internal sealed override uint Size(MetaData md) {\r
-      return md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      output.BlobIndex(sigIx);\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }\r
-\r
-  }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Descriptor for a class defined in System (mscorlib)\r
-       /// </summary>\r
-  internal class SystemClass : ClassRef\r
-       {\r
-    PrimitiveType elemType; \r
-\r
-               internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)\r
-                                    : base("System",eType.GetName(),md) {\r
-      elemType = eType;\r
-      parent = paren;\r
-               }\r
-\r
-    internal override sealed MetaDataElement GetTypeSpec(MetaData md) {\r
-      if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);\r
-      return typeSpec;\r
-    }\r
-\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-        str.WriteByte(elemType.GetTypeIndex());\r
-    }\r
-\r
-       }\r
-  /**************************************************************************/  \r
-       /// <summary>\r
-       /// Base class for all IL types\r
-       /// </summary>\r
-  public abstract class Type : MetaDataElement {\r
-    protected byte typeIndex;\r
-    protected TypeSpec typeSpec;\r
-\r
-    internal Type(byte tyIx) { typeIndex = tyIx; }\r
-\r
-    internal byte GetTypeIndex() { return typeIndex; }\r
-\r
-    internal virtual MetaDataElement GetTypeSpec(MetaData md) {\r
-      if (typeSpec == null) {\r
-        typeSpec = new TypeSpec(this,md);\r
-        md.AddToTable(MDTable.TypeSpec,typeSpec);\r
-      }\r
-      return typeSpec;\r
-    }\r
\r
-    internal virtual void TypeSig(MemoryStream str) {\r
-      throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +\r
-        " doesn't have a type signature!!"));   \r
-    }\r
-\r
-  }\r
-\r
-  /**************************************************************************/  \r
-\r
-  public class TypeSpec : MetaDataElement {\r
-    uint sigIx = 0;\r
-\r
-    internal TypeSpec(Type aType, MetaData md) {\r
-      MemoryStream sig = new MemoryStream();\r
-      aType.TypeSig(sig);\r
-      sigIx = md.AddToBlobHeap(sig.ToArray());\r
-      tabIx = MDTable.TypeSpec;\r
-    }\r
-\r
-    internal sealed override uint GetCodedIx(CIx code) {\r
-      switch (code) {\r
-        case (CIx.TypeDefOrRef) : return 2; \r
-        case (CIx.HasCustomAttr) : return 13; \r
-        case (CIx.MemberRefParent) : return 4; \r
-      }\r
-      return 0;\r
-    }\r
-\r
-    internal override uint Size(MetaData md) { \r
-      return md.BlobIndexSize();\r
-    }\r
-\r
-    internal sealed override void Write(FileImage output) {\r
-      //Console.WriteLine("Writing the blob index for a TypeSpec");\r
-      output.BlobIndex(sigIx);\r
-    }\r
-\r
-  }\r
-\r
-\r
-}\r
-\r
-\r
+        return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
+                        ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
+                        ((implFlags & (ushort)ImplAttr.InternalCall) != 0) || 
+                        (pinvokeImpl != null)); // TODO: Not entirely true but works for now
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+                        switch (code) {
+                                case (CIx.HasCustomAttr) : return 0; 
+                                case (CIx.HasDeclSecurity) : return 1; 
+                                case (CIx.MemberRefParent) : return 3; 
+                                case (CIx.MethodDefOrRef) : return 0; 
+                                case (CIx.MemberForwarded) : return 1; 
+                                case (CIx.CustomAttributeType) : return 2; 
+                                case (CIx.TypeOrMethodDef) : return 1; 
+                        }
+                        return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for an overriding method (.override)
+        /// </summary>
+  public class MethodImpl : MetaDataElement
+        {
+    ClassDef parent;
+    Method header, body;
+
+                internal MethodImpl(ClassDef par, Method decl, Method bod)      {
+      parent = par;
+      header = decl;
+      body = bod;
+                        tabIx = MDTable.MethodImpl;
+                }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteIndex(MDTable.TypeDef,parent.Row);
+      output.WriteCodedIndex(CIx.MethodDefOrRef,body);
+      output.WriteCodedIndex(CIx.MethodDefOrRef,header);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a method defined in another assembly/module
+        /// </summary>
+  public class MethodRef : Method
+  {
+    private static readonly byte Sentinel = 0x41;
+                Type[] parList, optParList;
+    MetaDataElement parent;
+    uint numPars = 0, numOptPars = 0;
+
+    internal MethodRef(MetaDataElement paren, string name, Type retType,
+        Type[] pars, bool varArgMeth, Type[] optPars) : base(name,retType) {
+      parent = paren;
+      parList = pars;
+      if (parList != null) numPars = (uint)parList.Length;
+      if (varArgMeth) {
+        optParList = optPars;
+        if (optParList != null) numOptPars = (uint)optParList.Length;
+        callConv = CallConv.Vararg;
+      }
+    }
+
+                internal sealed override void TypeSig(MemoryStream sig) {
+                        sig.WriteByte((byte)callConv);
+                        MetaData.CompressNum(numPars+numOptPars,sig);
+                        retType.TypeSig(sig);
+                        for (int i=0; i < numPars; i++) {
+                                parList[i].TypeSig(sig);
+                        }
+      if (numOptPars > 0) {
+        sig.WriteByte(Sentinel);
+        for (int i=0; i < numOptPars; i++) {
+          optParList[i].TypeSig(sig);
+        }
+      }
+                }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      nameIx = md.AddToStringsHeap(name);
+      sigIx = GetSigIx(md);
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.WriteCodedIndex(CIx.MemberRefParent,parent);
+      output.StringsIndex(nameIx);
+      output.BlobIndex(sigIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 6; 
+        case (CIx.MethodDefOrRef) : return 1; 
+        case (CIx.CustomAttributeType) : return 3; 
+      }
+                        return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for Property and Event methods
+        /// </summary>
+  public class MethodSemantics : MetaDataElement {
+
+    Feature.MethodType type;
+    MethodDef meth;
+    Feature eventOrProp;
+
+    internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature) {
+      type = mType;
+      meth = method;
+      eventOrProp = feature;
+                        tabIx = MDTable.MethodSemantics;
+                }
+
+    internal override uint SortKey() {
+      return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
+              | eventOrProp.GetCodedIx (CIx.HasSemantics);
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write((ushort)type);
+      output.WriteIndex(MDTable.Method,meth.Row);
+      output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a FunctionPointer type
+        /// </summary>
+        /// 
+        public class MethPtrType : Type
+        {
+                bool varArgMeth;
+                Type retType;
+                Type [] parList;
+                Type [] optParList;
+                CallConv callConv;
+                uint numPars;
+                uint numOptPars;
+                uint sigIx = 0;
+
+    /// <summary>
+    /// Create a new function pointer type
+    /// </summary>
+    /// <param name="meth">the function to be referenced</param>
+    public MethPtrType (CallConv callconv, Type retType, Type[] pars,
+                    bool varArgMeth, Type[] optPars) : base(0x1B) {
+      this.retType = retType;
+      callConv = callconv;
+      parList = pars;
+      this.varArgMeth = varArgMeth;
+      if (parList != null) numPars = (uint)parList.Length;
+      if (varArgMeth) {
+        optParList = optPars;
+        if (optParList != null) numOptPars = (uint)optParList.Length;
+        callConv |= CallConv.Vararg;
+      }
+      tabIx = MDTable.TypeSpec;
+    }
+  
+    internal sealed override void TypeSig(MemoryStream sig) {
+      sig.WriteByte(typeIndex);
+      // Bootlegged from method ref
+      sig.WriteByte((byte)callConv);
+      MetaData.CompressNum (numPars + numOptPars, sig);
+      retType.TypeSig (sig);
+      for (int i=0; i < numPars; i++) {
+              parList[i].TypeSig (sig);
+      }
+      if (varArgMeth) {
+              sig.WriteByte (0x41); // Write the sentinel
+        for (int i=0; i < numOptPars; i++) {
+          optParList[i].TypeSig (sig);
+        }
+      }
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      MemoryStream sig = new MemoryStream();
+      TypeSig(sig);
+      sigIx = md.AddToBlobHeap(sig.ToArray());
+      done = true;
+    }
+
+                internal sealed override uint Size(MetaData md) {
+                        return md.BlobIndexSize();
+                }
+
+                internal sealed override void Write(FileImage output) {
+                        output.BlobIndex(sigIx);
+                }
+
+                internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for THIS module
+        /// </summary>
+  public class Module : ResolutionScope
+        {
+    Guid mvid;
+    uint mvidIx = 0;
+
+                internal Module(string name, MetaData md) : base(name,md)       {
+      mvid = Guid.NewGuid();
+      mvidIx = md.AddToGUIDHeap(mvid);
+      tabIx = MDTable.Module;
+    }
+
+    public Guid Guid {
+      get { return mvid; }
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write((short)0);
+      output.StringsIndex(nameIx);
+      output.GUIDIndex(mvidIx);
+      output.GUIDIndex(0);
+      output.GUIDIndex(0);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+                        switch (code) {
+                                case (CIx.HasCustomAttr) : return 7; 
+                                case (CIx.ResolutionScope) : return 0;
+                        }
+                        return 0;
+    }
+  }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for another module in THIS assembly
+        /// </summary>
+        public class ModuleRef : ResolutionScope, IExternRef
+        {
+
+                internal ModuleRef(MetaData md, string name) : base(name,md) {
+      tabIx = MDTable.ModuleRef;
+                }
+
+    /// <summary>
+    /// Add a class to this external module.  This is a class declared in
+    /// another module of THIS assembly.
+    /// </summary>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns>a descriptor for this class in another module</returns>
+    public ClassRef AddClass(string nsName, string name) {
+      ClassRef aClass = new ClassRef(nsName,name,metaData);
+      metaData.AddToTable(MDTable.TypeRef,aClass);
+      aClass.SetParent(this);
+      return aClass;
+    }
+
+    /// <summary>
+    /// Make a file descriptor to correspond to this module.  The file
+    /// descriptor will have the same name as the module descriptor
+    /// </summary>
+    /// <param name="hashBytes">the hash of the file</param>
+    /// <param name="hasMetaData">the file contains metadata</param>
+    /// <param name="entryPoint">the program entry point is in this file</param>
+    /// <returns>a descriptor for the file which contains this module</returns>
+    public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint) {
+      FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
+      metaData.AddToTable(MDTable.File,file);
+      return file;
+    }
+
+    /// <summary>
+    /// Add a value class to this module.  This is a class declared in
+    /// another module of THIS assembly.
+    /// </summary>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns></returns>
+    public ClassRef AddValueClass(string nsName, string name) {
+      ClassRef aClass = new ClassRef(nsName,name,metaData);
+      metaData.AddToTable(MDTable.TypeRef,aClass);
+      aClass.SetParent(this);
+      aClass.MakeValueClass(ValueClass.ValueType);
+      return aClass;
+    }
+
+    /// <summary>
+    /// Add a class which is declared public in this external module of
+    /// THIS assembly.  This class will be exported from this assembly.
+    /// The ilasm syntax for this is .extern class
+    /// </summary>
+    /// <param name="attrSet">attributes of the class to be exported</param>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">external class name</param>
+    /// <param name="declFile">the file where the class is declared</param>
+    /// <param name="isValueClass">is this class a value type?</param>
+    /// <returns>a descriptor for this external class</returns>
+    public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName, 
+                                         string name, FileRef declFile, 
+                                         bool isValueClass) {
+      ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
+      metaData.AddToTable(MDTable.TypeRef,cRef);
+      cRef.SetParent(this);
+      if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
+      return cRef;
+    }
+
+    /// <summary>
+    /// Add a "global" method in another module
+    /// </summary>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">method parameter types</param>
+    /// <returns>a descriptor for this method in anther module</returns>
+    public MethodRef AddMethod(string name, Type retType, Type[] pars) {
+      MethodRef meth = new MethodRef(this,name,retType,pars,false,null);
+      metaData.AddToTable(MDTable.MemberRef,meth);
+      return meth;
+    }
+
+    /// <summary>
+    /// Add a vararg method to this class
+    /// </summary>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">parameter types</param>
+    /// <param name="optPars">optional param types for this vararg method</param>
+    /// <returns>a descriptor for this method</returns>
+    public MethodRef AddVarArgMethod(string name, Type retType, 
+      Type[] pars, Type[] optPars) {
+      MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);
+      metaData.AddToTable(MDTable.MemberRef,meth);
+      return meth;
+    }
+
+    /// <summary>
+    /// Add a field in another module
+    /// </summary>
+    /// <param name="name">field name</param>
+    /// <param name="fType">field type</param>
+    /// <returns>a descriptor for this field in another module</returns>
+    public FieldRef AddField(string name, Type fType) {
+      FieldRef field = new FieldRef(this,name,fType);
+      metaData.AddToTable(MDTable.MemberRef,field);
+      return field;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.StringsIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.StringsIndex(nameIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 12; 
+        case (CIx.MemberRefParent) : return 2; 
+        case (CIx.ResolutionScope) : return 1; 
+      }
+                        return 0;
+    }
+  }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptors for native types used for marshalling
+        /// </summary>
+  public class NativeType {
+    public static readonly NativeType Void = new NativeType(0x01);
+    public static readonly NativeType Boolean = new NativeType(0x02);
+    public static readonly NativeType Int8 = new NativeType(0x03);
+    public static readonly NativeType UInt8 = new NativeType(0x04);
+    public static readonly NativeType Int16 = new NativeType(0x05);
+    public static readonly NativeType UInt16 = new NativeType(0x06);
+    public static readonly NativeType Int32 = new NativeType(0x07);
+    public static readonly NativeType UInt32 = new NativeType(0x08);
+    public static readonly NativeType Int64 = new NativeType(0x09);
+    public static readonly NativeType UInt64 = new NativeType(0x0A);
+    public static readonly NativeType Float32 = new NativeType(0x0B);
+    public static readonly NativeType Float64 = new NativeType(0x0C);
+    public static readonly NativeType Currency = new NativeType(0x0F);
+    public static readonly NativeType BStr = new NativeType(0x13);
+    public static readonly NativeType LPStr = new NativeType(0x14);
+    public static readonly NativeType LPWStr = new NativeType(0x15);
+    public static readonly NativeType LPTStr = new NativeType(0x16);
+    public static readonly NativeType FixedSysString = new NativeType(0x17);
+    public static readonly NativeType IUnknown = new NativeType(0x19);
+    public static readonly NativeType IDispatch = new NativeType(0x1A);
+    public static readonly NativeType Struct = new NativeType(0x1B);
+    public static readonly NativeType Interface = new NativeType(0x1C);
+    public static readonly NativeType Int = new NativeType(0x1F);
+    public static readonly NativeType UInt = new NativeType(0x20);
+    public static readonly NativeType ByValStr = new NativeType(0x22);
+    public static readonly NativeType AnsiBStr = new NativeType(0x23);
+    public static readonly NativeType TBstr = new NativeType(0x24);
+    public static readonly NativeType VariantBool = new NativeType(0x25);
+    public static readonly NativeType FuncPtr = new NativeType(0x26);
+    public static readonly NativeType AsAny = new NativeType(0x28);
+
+    protected byte typeIndex;
+
+    internal NativeType(byte tyIx) { typeIndex = tyIx; }
+
+    internal byte GetTypeIndex() { return typeIndex; }
+
+    internal virtual byte[] ToBlob() {
+      byte[] bytes = new byte[1];
+      bytes[0] = GetTypeIndex();
+      return bytes;
+    }
+
+   }
+
+  public class NativeArray : NativeType 
+  {
+    NativeType elemType;
+    uint len = 0, parNum = 0;
+
+    /*
+    public NativeArray(NativeType elemType) : base(0x2A) {
+      this.elemType = elemType;
+    }
+
+    public NativeArray(NativeType elemType, int len) : base(0x2A) {
+      this.elemType = elemType;
+      this.len = len;
+    }
+*/
+    public NativeArray(NativeType elemType, int numElem, int parNumForLen) : base(0x2A) {
+      this.elemType = elemType;
+      len = (uint)numElem;
+      parNum = (uint)parNumForLen;
+    }
+
+    internal override byte[] ToBlob() {
+      MemoryStream str = new MemoryStream();
+      str.WriteByte(GetTypeIndex());
+      if (elemType == null) str.WriteByte(0x50);  // no info (MAX)
+      else str.WriteByte(elemType.GetTypeIndex());
+      MetaData.CompressNum(parNum,str);
+      str.WriteByte(1);
+      MetaData.CompressNum(len,str);
+      return str.ToArray();
+    }
+
+  }
+
+  public class SafeArray : NativeType 
+  {
+    SafeArrayType elemType;
+
+    public SafeArray(SafeArrayType elemType) : base(0x1D) {
+      this.elemType = elemType;
+    }
+
+    internal override byte[] ToBlob() {
+      byte[] bytes = new byte[2];
+      bytes[0] = GetTypeIndex();
+      bytes[1] = (byte)elemType;
+      return bytes;
+    }
+
+  }
+
+  public class FixedArray : NativeType 
+  {
+    NativeType elemType;
+    uint numElem;
+
+    public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
+      this.elemType = elemType;
+      numElem = (uint)numElems;
+    }
+
+    internal override byte[] ToBlob() {
+      MemoryStream str = new MemoryStream();
+      str.WriteByte(GetTypeIndex());
+      MetaData.CompressNum(numElem,str);
+      if (elemType == null) str.WriteByte(0x50);  // no info (MAX)
+      else str.WriteByte(elemType.GetTypeIndex());
+      return str.ToArray();
+    }
+
+  }
+
+  public class CustomMarshaller : NativeType 
+  {
+    string typeName;
+    string marshallerName;
+    string cookie;
+
+    public CustomMarshaller(string typeNameOrGUID, string marshallerName, 
+                string optCookie) : base(0x2C) {
+      typeName = typeNameOrGUID;
+      this.marshallerName = marshallerName;
+      cookie = optCookie;
+    }
+
+    internal override byte[] ToBlob() {
+      MemoryStream str = new MemoryStream();
+      BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
+      bw.Write(GetTypeIndex());
+      bw.Write(typeName.ToCharArray());
+      bw.Write((byte)0);
+      bw.Write(marshallerName.ToCharArray());
+      bw.Write((byte)0);
+      if (cookie != null) bw.Write(cookie.ToCharArray());
+      bw.Write((byte)0);
+      bw.Flush();
+      return str.ToArray();
+    }
+  }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a parameter of a method defined in this assembly/module
+        /// </summary>
+  public class Param : MetaDataElement
+        {
+    private static readonly ushort hasDefault = 0x1000;
+    private static readonly ushort hasFieldMarshal = 0x2000;
+
+    Type pType;
+    string pName;
+    internal ushort seqNo = 0;
+    ushort parMode;
+    ConstantElem defaultVal;
+    uint nameIx = 0;
+    FieldMarshal marshalInfo;
+
+    /// <summary>
+    /// Create a new parameter for a method
+    /// </summary>
+    /// <param name="mode">param mode (in, out, opt)</param>
+    /// <param name="parName">parameter name</param>
+    /// <param name="parType">parameter type</param>
+    public Param(ParamAttr mode, string parName, Type parType) {
+      pName = parName;
+      pType = parType;
+      parMode = (ushort)mode;
+                        tabIx = MDTable.Param;
+                }
+
+    /// <summary>
+    /// Add a default value to this parameter
+    /// </summary>
+    /// <param name="c">the default value for the parameter</param>
+    public void AddDefaultValue(Constant cVal) {
+      defaultVal = new ConstantElem(this,cVal);
+      parMode |= hasDefault;
+    }
+
+    /// <summary>
+    /// Add marshalling information about this parameter
+    /// </summary>
+    public void AddMarshallInfo(NativeType marshallType) {
+      parMode |= hasFieldMarshal;
+      marshalInfo = new FieldMarshal(this,marshallType);
+    }
+
+    internal Type GetParType() { return pType; }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      nameIx = md.AddToStringsHeap(pName);
+      if (defaultVal != null) {
+        md.AddToTable(MDTable.Constant,defaultVal);
+        defaultVal.BuildTables(md);
+      }
+      if (marshalInfo != null) {
+        md.AddToTable(MDTable.FieldMarshal,marshalInfo);
+        marshalInfo.BuildTables(md);
+      }
+      done = true;
+    }
+
+    internal void TypeSig(MemoryStream str) {
+      pType.TypeSig(str);
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 4 + md.StringsIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(parMode);
+      output.Write(seqNo);
+      output.StringsIndex(nameIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.HasCustomAttr) : return 4; 
+        case (CIx.HasConst) : return 1; 
+        case (CIx.HasFieldMarshal) : return 1; 
+      }
+                        return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for the PEFile (starting point)
+        /// </summary>
+  public class PEFile
+        {
+    private static readonly string mscorlibName = "mscorlib";
+    private Module thisMod;
+    private ClassDef moduleClass;
+    private ArrayList classRefList = new ArrayList();
+    private ArrayList classDefList = new ArrayList();
+    private ArrayList resources = new ArrayList ();
+    private Assembly thisAssembly;
+    private int corFlags = 1;
+    FileImage fileImage;
+                MetaData metaData;
+
+    /// <summary>
+    /// Create a new PEFile.  Each PEFile is a module.
+    /// </summary>
+    /// <param name="name">module name, also used for the file name</param>
+    /// <param name="isDLL">create a .dll or .exe file</param>
+    /// <param name="hasAssembly">this file is an assembly and 
+    /// will contain the assembly manifest.  The assembly name is the 
+    /// same as the module name</param>
+    public PEFile(string name, bool isDLL, bool hasAssembly) {
+      // Console.WriteLine(Hex.Byte(0x12));
+      // Console.WriteLine(Hex.Short(0x1234));
+      // Console.WriteLine(Hex.Int(0x12345678));
+      string fName = MakeFileName(null,name,isDLL);
+      fileImage = new FileImage(isDLL,fName);
+      InitPEFile(name, fName, hasAssembly);
+    }
+
+    /// <summary>
+    /// Create a new PEFile.  Each PEFile is a module.
+    /// </summary>
+    /// <param name="name">module name, also used for the file name</param>
+    /// <param name="isDLL">create a .dll or .exe file</param>
+    /// <param name="hasAssembly">this file is an assembly and 
+    /// will contain the assembly manifest.  The assembly name is the 
+    /// same as the module name</param>
+    /// <param name="outputDir">write the PEFile to this directory.  If this
+    /// string is null then the output will be to the current directory</param>
+    public PEFile(string name, bool isDLL, bool hasAssembly, string outputDir) {
+      // Console.WriteLine(Hex.Byte(0x12));
+      // Console.WriteLine(Hex.Short(0x1234));
+      // Console.WriteLine(Hex.Int(0x12345678));
+      string fName = MakeFileName(outputDir,name,isDLL);
+                        fileImage = new FileImage(isDLL,fName);
+      InitPEFile(name, fName, hasAssembly);
+    }
+
+    /// <summary>
+    /// Create a new PEFile
+    /// </summary>
+    /// <param name="name">module name</param>
+    /// <param name="isDLL">create a .dll or .exe</param>
+    /// <param name="hasAssembly">this PEfile is an assembly and
+    /// will contain the assemly manifest.  The assembly name is the
+    /// same as the module name</param>
+    /// <param name="outStream">write the PEFile to this stream instead
+    /// of to a new file</param>
+    public PEFile(string name, bool isDLL, bool hasAssembly, Stream outStream) {
+      fileImage = new FileImage(isDLL,outStream);
+      InitPEFile(name, MakeFileName(null,name,isDLL), hasAssembly);
+    }
+
+    public PEFile(string name, string module_name, bool isDLL, bool hasAssembly, Stream outStream) {
+      fileImage = new FileImage(isDLL,outStream);
+      InitPEFile(name, (module_name == null ? MakeFileName(null,name,isDLL) : module_name), hasAssembly);
+    }
+
+    private void InitPEFile(string name, string fName, bool hasAssembly) {
+      metaData = fileImage.GetMetaData();
+      thisMod = new Module(fName,metaData);
+      if (hasAssembly) {
+        thisAssembly = new Assembly(name,metaData);
+        metaData.AddToTable(MDTable.Assembly,thisAssembly);      
+      }
+      moduleClass = AddClass(TypeAttr.Private,"","<Module>");
+      moduleClass.SpecialNoSuper();
+      metaData.AddToTable(MDTable.Module,thisMod);
+    }
+
+    public ClassDef ModuleClass {
+            get { return moduleClass; }
+    }
+
+    /// <summary>
+    /// Set the subsystem (.subsystem) (Default is Windows Console mode)
+    /// </summary>
+    /// <param name="subS">subsystem value</param>
+    public void SetSubSystem(SubSystem subS) {
+      fileImage.subSys = subS;
+    }
+
+    /// <summary>
+    /// Set the flags (.corflags)
+    /// </summary>
+    /// <param name="flags">the flags value</param>
+    public void SetCorFlags(int flags) {
+      corFlags = flags;
+    }
+
+    private string MakeFileName(string dirName, string name, bool isDLL) {
+      string result = "";
+      if ((dirName != null) && (dirName.CompareTo("") != 0)) {
+        result = dirName;
+        if (!dirName.EndsWith("\\")) result += "\\";
+      }
+      result += name;
+       
+      // if (isDLL) result += ".dll";  else result += ".exe";
+      
+      return result;
+    }
+
+    /// <summary>
+    /// Add an external assembly to this PEFile (.assembly extern)
+    /// </summary>
+    /// <param name="assemName">the external assembly name</param>
+    /// <returns>a descriptor for this external assembly</returns>
+    public AssemblyRef AddExternAssembly(string assemName) {
+      if (assemName.CompareTo(mscorlibName) == 0) return metaData.mscorlib;
+      AssemblyRef anAssem = new AssemblyRef(metaData,assemName);
+      metaData.AddToTable(MDTable.AssemblyRef,anAssem);
+      // Console.WriteLine("Adding assembly " + assemName);
+      return anAssem;
+    }
+
+    /// <summary>
+    /// Add an external module to this PEFile (.module extern)
+    /// </summary>
+    /// <param name="name">the external module name</param>
+    /// <returns>a descriptor for this external module</returns>
+    public ModuleRef AddExternModule(string name) {
+      ModuleRef modRef = new ModuleRef(metaData,name);
+      metaData.AddToTable(MDTable.ModuleRef,modRef);
+      return modRef;
+    }
+
+    /// <summary>
+    /// Add a "global" method to this module
+    /// </summary>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">method parameters</param>
+    /// <returns>a descriptor for this new "global" method</returns>
+    public MethodDef AddMethod(string name, Type retType, Param[] pars) {
+      return moduleClass.AddMethod(name,retType,pars);
+    }
+
+    /// <summary>
+    /// Add a "global" method to this module
+    /// </summary>
+    /// <param name="mAtts">method attributes</param>
+    /// <param name="iAtts">method implementation attributes</param>
+    /// <param name="name">method name</param>
+    /// <param name="retType">return type</param>
+    /// <param name="pars">method parameters</param>
+    /// <returns>a descriptor for this new "global" method</returns>
+    public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, Type retType, Param[] pars) {
+      return moduleClass.AddMethod(mAtts,iAtts,name,retType,pars);
+    }
+
+    public MethodRef AddMethodToTypeSpec (Type item, string name, Type retType, Type[] pars) {
+            MethodRef meth = new MethodRef (item.GetTypeSpec (metaData), name, retType, pars, false, null);
+            metaData.AddToTable (MDTable.MemberRef,meth);
+            return meth;
+    }
+
+    public MethodRef AddVarArgMethodToTypeSpec (Type item, string name, Type retType,
+                    Type[] pars, Type[] optPars) {
+            MethodRef meth = new MethodRef(item.GetTypeSpec (metaData), name,retType,pars,true,optPars);
+            metaData.AddToTable(MDTable.MemberRef,meth);
+            return meth;
+    }
+
+    public FieldRef AddFieldToTypeSpec (Type item, string name, Type fType) {
+            FieldRef field = new FieldRef (item.GetTypeSpec (metaData), name,fType);
+            metaData.AddToTable (MDTable.MemberRef,field);
+            return field;
+    }
+
+    public void AddMethodSpec (Method m, GenericMethodSig g_sig)
+    {
+            MethodSpec ms = new MethodSpec (m, g_sig);
+            metaData.AddToTable (MDTable.MethodSpec, ms);
+    }
+
+    /// <summary>
+    /// Add a "global" field to this module
+    /// </summary>
+    /// <param name="name">field name</param>
+    /// <param name="fType">field type</param>
+    /// <returns>a descriptor for this new "global" field</returns>
+    public FieldDef AddField(string name, Type fType) {
+      return moduleClass.AddField(name,fType);
+    }
+
+    /// <summary>
+    /// Add a "global" field to this module
+    /// </summary>
+    /// <param name="attrSet">attributes of this field</param>
+    /// <param name="name">field name</param>
+    /// <param name="fType">field type</param>
+    /// <returns>a descriptor for this new "global" field</returns>
+    public FieldDef AddField(FieldAttr attrSet, string name, Type fType) {
+      return moduleClass.AddField(attrSet,name,fType);
+    }
+
+    /// <summary>
+    /// Add a class to this module
+    /// </summary>
+    /// <param name="attrSet">attributes of this class</param>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns>a descriptor for this new class</returns>
+    public ClassDef AddClass(TypeAttr attrSet, string nsName, string name) {
+      ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);
+      metaData.AddToTable(MDTable.TypeDef,aClass);
+      return aClass;
+    }
+
+    /// <summary>
+    /// Add a class which extends System.ValueType to this module
+    /// </summary>
+    /// <param name="attrSet">attributes of this class</param>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <returns>a descriptor for this new class</returns>
+    public ClassDef AddValueClass(TypeAttr attrSet, string nsName, string name, ValueClass vClass) {
+      ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);
+      aClass.MakeValueClass(vClass);
+      aClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
+      metaData.AddToTable(MDTable.TypeDef,aClass);
+      return aClass;
+    }
+
+    /// <summary>
+    /// Add a class to this module
+    /// </summary>
+    /// <param name="attrSet">attributes of this class</param>
+    /// <param name="nsName">name space name</param>
+    /// <param name="name">class name</param>
+    /// <param name="superType">super type of this class (extends)</param>
+    /// <returns>a descriptor for this new class</returns>
+    public ClassDef AddClass(TypeAttr attrSet, string nsName, string name, Class superType) {
+      ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);
+      aClass.SetSuper(superType);
+      metaData.AddToTable(MDTable.TypeDef,aClass);
+      return aClass;
+    }
+
+    public FileRef AddFile(string fName, byte[] hashBytes, bool hasMetaData, bool entryPoint) {
+      FileRef file = new FileRef(fName,hashBytes,hasMetaData,entryPoint,metaData);
+      metaData.AddToTable(MDTable.File,file);
+      return file;
+    }
+
+    /// <summary>
+    /// Add a manifest resource to this PEFile NOT YET IMPLEMENTED
+    /// </summary>
+    /// <param name="mr"></param>
+    public void AddManifestResource(ManifestResource mr) {
+      metaData.AddToTable(MDTable.ManifestResource,mr);
+      resources.Add (mr);
+      //mr.FixName(metaData);
+    }
+
+    public void AddCustomAttribute (Method meth, byte [] data, MetaDataElement element)
+    {
+            metaData.AddCustomAttribute (new CustomAttribute (element, meth, data));
+    }
+
+    /// <summary>
+    /// Add a managed resource from another assembly.
+    /// </summary>
+    /// <param name="resName">The name of the resource</param>
+    /// <param name="assem">The assembly where the resource is</param>
+    /// <param name="isPublic">Access for the resource</param>
+    public void AddExternalManagedResource (string resName, AssemblyRef assem, uint flags) {
+      resources.Add (new ManifestResource (resName, flags, assem));
+    }
+
+    /// <summary>
+    /// Add a managed resource from another assembly.
+    /// </summary>
+    /// <param name="mr"></param>
+    /// <param name="isPublic"></param>
+    public void AddExternalManagedResource (ManifestResource mr) {
+      resources.Add (new ManifestResource (mr));
+    }
+    /// <summary>
+    /// Find a resource
+    /// </summary>
+    /// <param name="name">The name of the resource</param>
+    /// <returns>The resource with the name "name" or null </returns>
+    public ManifestResource GetResource (string name) {
+      for (int i = 0; i < resources.Count; i ++) {
+        if (((ManifestResource) resources [i]).Name == name)
+          return (ManifestResource) resources [i];
+      }
+      return null;
+    }
+
+    public ManifestResource [] GetResources() {
+      return (ManifestResource []) resources.ToArray (typeof (ManifestResource));
+    }
+
+    /// <summary>
+    /// Write out the PEFile (the "bake" function)
+    /// </summary>
+    public void WritePEFile() { /* the "bake" function */
+      fileImage.ReserveStrongNameSignatureSpace = thisAssembly.HasPublicKey;
+      fileImage.MakeFile();
+    }
+
+    /// <summary>
+    /// Get the descriptor of this module
+    /// </summary>
+    /// <returns>the descriptor for this module</returns>
+    public Module GetThisModule() {
+      return thisMod;
+    }
+
+    /// <summary>
+    /// Get the descriptor for this assembly.  The PEFile must have been
+    /// created with hasAssembly = true
+    /// </summary>
+    /// <returns>the descriptor for this assembly</returns>
+    public Assembly GetThisAssembly() {
+      return thisAssembly;
+    }
+
+        }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for the Primitive types defined in IL
+        /// </summary>
+  public class PrimitiveType : Type
+        {
+    private string name;
+    private int systemTypeIndex;
+    public static int NumSystemTypes = 18;
+
+    public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
+    public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
+    public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
+    public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
+    public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
+    public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
+    public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
+    public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
+    public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
+    public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
+    public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
+    public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
+    public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
+    public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
+                internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
+    public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
+    public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
+    public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
+    public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
+    internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
+    internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
+    internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
+    public static readonly PrimitiveType NativeInt = IntPtr;
+    public static readonly PrimitiveType NativeUInt = UIntPtr;
+
+    internal PrimitiveType(byte typeIx) : base(typeIx) { }
+
+                internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx) {
+      this.name = name;
+      this.systemTypeIndex = STIx;
+    }
+
+    internal string GetName() { return name; }
+
+    internal int GetSystemTypeIx() { return systemTypeIndex; }
+
+    internal sealed override void TypeSig(MemoryStream str) {
+      str.WriteByte(typeIndex);
+    }
+
+    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;
+    }
+
+        }
+
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for the Property of a class
+        /// </summary>
+  public class Property : Feature
+        {
+    private static readonly byte PropertyTag = 0x8;
+    MethodDef getterMeth;
+    ConstantElem constVal;
+    uint typeBlobIx = 0;
+    Type[] parList;
+    Type returnType;
+    uint numPars = 0;
+
+    internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent) {
+      returnType = retType;
+      parList = pars;
+      if (pars != null) numPars = (uint)pars.Length;
+                        tabIx = MDTable.Property;
+                }
+
+    /// <summary>
+    /// Add a set method to this property
+    /// </summary>
+    /// <param name="setter">the set method</param>
+    public void AddSetter(MethodDef setter) {
+      AddMethod(setter,MethodType.Setter);
+    }
+
+    /// <summary>
+    /// Add a get method to this property
+    /// </summary>
+    /// <param name="getter">the get method</param>
+    public void AddGetter(MethodDef getter) {
+      AddMethod(getter,MethodType.Getter);
+      getterMeth = getter;
+    }
+
+    /// <summary>
+    /// Add another method to this property
+    /// </summary>
+    /// <param name="other">the method</param>
+    public void AddOther(MethodDef other) {
+      AddMethod(other,MethodType.Other);
+    }
+
+    /// <summary>
+    /// Add an initial value for this property
+    /// </summary>
+    /// <param name="constVal">the initial value for this property</param>
+    public void AddInitValue(Constant constVal) {
+      this.constVal = new ConstantElem(this,constVal);
+    }
+
+    internal sealed override void BuildTables(MetaData md) {
+      if (done) return;
+      nameIx = md.AddToStringsHeap(name);
+      MemoryStream sig = new MemoryStream();
+      sig.WriteByte(PropertyTag);
+      MetaData.CompressNum(numPars,sig);
+      returnType.TypeSig(sig);
+      for (int i=0; i < numPars; i++) {
+        parList[i].TypeSig(sig);
+      }
+      typeBlobIx = md.AddToBlobHeap(sig.ToArray());
+      for (int i=0; i < tide; i++) {
+        md.AddToTable(MDTable.MethodSemantics,methods[i]);
+      }
+      if (constVal != null) {
+        md.AddToTable(MDTable.Constant,constVal);
+        constVal.BuildTables(md);
+      }
+      done = true;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return 2 + md.StringsIndexSize() + md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.Write(flags);
+      output.StringsIndex(nameIx);
+      output.BlobIndex(typeBlobIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+                        switch (code) {
+                                case (CIx.HasCustomAttr) : return 9; 
+                                case (CIx.HasConst) : return 2; 
+                                case (CIx.HasSemantics) : return 1; 
+                        }
+                        return 0;
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for an pointer (type * or type &)
+        /// </summary>
+  public abstract class PtrType : Type
+        {
+    Type baseType;
+
+                internal PtrType(Type bType, byte typeIx) : base(typeIx)
+                {
+      baseType = bType;
+      tabIx = MDTable.TypeSpec;
+                }
+
+    internal sealed override void TypeSig(MemoryStream str) {
+      str.WriteByte(typeIndex);
+      baseType.TypeSig(str);
+    }
+
+        }
+  /**************************************************************************/  
+  /// <summary>
+  /// Descriptor for a managed pointer (type &  or byref)
+  /// </summary>
+
+  public class ManagedPointer : PtrType  // <type> & (BYREF)  
+  {
+
+    /// <summary>
+    /// Create new managed pointer to baseType
+    /// </summary>
+    /// <param name="bType">the base type of the pointer</param>
+    public ManagedPointer(Type baseType) : base(baseType,0x10) { }
+  }
+  /**************************************************************************/  
+  /// <summary>
+  /// Descriptor for an unmanaged pointer (type *)
+  /// </summary>
+  public class UnmanagedPointer : PtrType // PTR
+  {
+    /// <summary>
+    /// Create a new unmanaged pointer to baseType
+    /// </summary>
+    /// <param name="baseType">the base type of the pointer</param>
+    public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
+
+  }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
+        /// </summary>
+  public abstract class ResolutionScope : MetaDataElement
+        {
+    protected uint nameIx = 0;
+    protected MetaData metaData;
+    protected string name;
+
+                internal ResolutionScope(string name, MetaData md)
+                {
+      metaData = md;
+      this.name = name;
+      nameIx = md.AddToStringsHeap(name);
+                }
+
+    internal string GetName() { return name; }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a Section in a PEFile  eg .text, .sdata
+        /// </summary>
+  internal class Section {
+                private static readonly uint relocPageSize = 4096;  // 4K pages for fixups
+
+                char[] name; 
+                uint offset = 0, tide = 0, size = 0, rva = 0, relocTide = 0;
+                //uint relocOff = 0;
+    uint flags = 0, padding = 0;
+                uint[] relocs; 
+
+                internal Section(string sName, uint sFlags) {
+                  name = sName.ToCharArray();
+                  flags = sFlags;
+                }
+
+                internal uint Tide() { return tide; }
+
+                internal void IncTide(uint incVal) { tide += incVal; }
+
+                internal uint Padding() { return padding; }
+
+                internal uint Size() { return size; }
+
+                internal void SetSize(uint pad) {
+                        padding = pad;
+                        size = tide + padding;
+                }
+
+                internal uint RVA() { return rva; }
+
+                internal void SetRVA(uint rva) { this.rva = rva; }
+
+                internal uint Offset() { return offset; }
+
+                internal void SetOffset(uint offs) { offset = offs; }
+
+    internal void DoBlock(BinaryWriter reloc, uint page, int start, int end) {
+      //Console.WriteLine("rva = " + rva + "  page = " + page);
+      reloc.Write(rva + page);
+      reloc.Write((uint)(((end-start+1)*2) + 8));
+      for (int j=start; j < end; j++) {
+        //Console.WriteLine("reloc offset = " + relocs[j]);
+        reloc.Write((ushort)((0x3 << 12) | (relocs[j] - page)));
+      }
+      reloc.Write((ushort)0);
+    }
+
+                internal void DoRelocs(BinaryWriter reloc) {
+      if (relocTide > 0) {
+        //relocOff = (uint)reloc.Seek(0,SeekOrigin.Current);
+        uint block = (relocs[0]/relocPageSize + 1) * relocPageSize;
+        int start = 0;
+        for (int i=1; i < relocTide; i++) {
+          if (relocs[i] >= block) {
+            DoBlock(reloc,block-relocPageSize,start,i);
+            start = i;
+            block = (relocs[i]/relocPageSize + 1) * relocPageSize;
+          }
+        }
+        DoBlock(reloc,block-relocPageSize,start,(int)relocTide);
+      }
+                }
+
+                internal void AddReloc(uint offs) {
+                        int pos = 0;
+                        if (relocs == null) {
+                                relocs = new uint[5];
+                        } else {
+                                if (relocTide >= relocs.Length) {
+                                        uint[] tmp = relocs;
+                                        relocs = new uint[tmp.Length + 5];
+                                        for (int i=0; i < relocTide; i++) {
+                                                relocs[i] = tmp[i];
+                                        }
+                                }
+                                while ((pos < relocTide) && (relocs[pos] < offs)) pos++;
+                                for (int i=pos; i < relocTide; i++) {
+                                        relocs[i+1] = relocs[i];
+                                }
+                        }
+                        relocs[pos] = offs;
+                        relocTide++;    
+                }
+      
+                internal void WriteHeader(BinaryWriter output, uint relocRVA) {
+                        output.Write(name);
+                        output.Write(tide);
+                        output.Write(rva);
+                        output.Write(size);
+                        output.Write(offset);
+                        output.Write(0);
+                        //output.Write(relocRVA + relocOff);
+                        output.Write(0);
+      output.Write(0);
+                        //output.Write((ushort)relocTide);
+                        //output.Write((ushort)0);
+                        output.Write(flags);
+                }
+
+        }
+  /**************************************************************************/  
+  public abstract class Signature : MetaDataElement 
+  {
+    protected uint sigIx;
+
+    internal Signature() {
+      tabIx = MDTable.StandAloneSig;
+    }
+
+    internal sealed override uint Size(MetaData md) {
+      return md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      output.BlobIndex(sigIx);
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
+
+  }
+  /**************************************************************************/  
+        /// <summary>
+        /// Descriptor for a class defined in System (mscorlib)
+        /// </summary>
+  internal class SystemClass : ClassRef
+        {
+    PrimitiveType elemType; 
+
+                internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
+                                    : base("System",eType.GetName(),md) {
+      elemType = eType;
+      parent = paren;
+                }
+
+    internal override sealed MetaDataElement GetTypeSpec(MetaData md) {
+      if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
+      return typeSpec;
+    }
+
+
+    internal sealed override void TypeSig(MemoryStream str) {
+        str.WriteByte(elemType.GetTypeIndex());
+    }
+
+        }
+  /**************************************************************************/  
+        /// <summary>
+        /// Base class for all IL types
+        /// </summary>
+  public abstract class Type : MetaDataElement {
+    protected byte typeIndex;
+    protected TypeSpec typeSpec;
+
+    internal Type(byte tyIx) { typeIndex = tyIx; }
+
+    internal byte GetTypeIndex() { return typeIndex; }
+    internal void SetTypeIndex (byte b) { typeIndex = b; }
+          
+    internal virtual MetaDataElement GetTypeSpec(MetaData md) {
+      if (typeSpec == null) {
+        typeSpec = new TypeSpec(this,md);
+        md.AddToTable(MDTable.TypeSpec,typeSpec);
+      }
+      return typeSpec;
+    }
+    internal virtual void TypeSig(MemoryStream str) {
+      throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
+        " doesn't have a type signature!!"));   
+    }
+
+  }
+
+  /**************************************************************************/  
+
+  public class TypeSpec : MetaDataElement {
+    uint sigIx = 0;
+
+    internal TypeSpec(Type aType, MetaData md) {
+      MemoryStream sig = new MemoryStream();
+      aType.TypeSig(sig);
+      sigIx = md.AddToBlobHeap(sig.ToArray());
+      tabIx = MDTable.TypeSpec;
+    }
+
+    internal sealed override uint GetCodedIx(CIx code) {
+      switch (code) {
+        case (CIx.TypeDefOrRef) : return 2; 
+        case (CIx.HasCustomAttr) : return 13; 
+        case (CIx.MemberRefParent) : return 4; 
+      }
+      return 0;
+    }
+
+    internal override uint Size(MetaData md) { 
+      return md.BlobIndexSize();
+    }
+
+    internal sealed override void Write(FileImage output) {
+      //Console.WriteLine("Writing the blob index for a TypeSpec");
+      output.BlobIndex(sigIx);
+    }
+
+  }
+
+          class ByteArrayComparer : IComparer {
+
+                public int Compare (object x, object y)
+                {
+                        byte [] a = (byte []) x;
+                        byte [] b = (byte []) y;
+                        int len = a.Length;
+
+                        if (b.Length != len)
+                                return 1;
+
+                        for (int i = 0; i < len; ++i)
+                                if (a [i] != b [i])
+                                        return 1;
+                        return 0;
+                }
+        }
+
+        class ByteArrayHashCodeProvider : IHashCodeProvider {
+
+               public int GetHashCode (Object key)
+               {
+                       byte [] arr = (byte []) key;
+                        int len = arr.Length;
+                       int h = 0;
+
+                       for (int i = 0; i < len; ++i)
+                               h = (h << 5) - h + arr [i];
+
+                       return h;
+               }
+
+       }
+}
+
+