Merge pull request #487 from mayerwin/patch-1
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / MethodBuilderTest.cs
index 3f1b82fc38e0e1a59ed3436c03661853df29ed16..60ae8016cad1f36e6ad040ae78433926fd42d762 100644 (file)
@@ -22,756 +22,1159 @@ using NUnit.Framework;
 
 namespace MonoTests.System.Reflection.Emit
 {
+       [TestFixture]
+       public class MethodBuilderTest
+       {
+               private TypeBuilder genClass;
+               private ModuleBuilder module;
 
-[TestFixture]
-public class MethodBuilderTest : Assertion
-{      
-    private TypeBuilder genClass;
+               [SetUp]
+               protected void SetUp ()
+               {
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "MonoTests.System.Reflection.Emit.MethodBuilderTest";
 
-       private ModuleBuilder module;
+                       AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
+                               assemblyName, AssemblyBuilderAccess.Run);
+                       module = assembly.DefineDynamicModule ("module1");
+                       genClass = module.DefineType (genTypeName (), TypeAttributes.Public);
+               }
 
-       [SetUp]
-       protected void SetUp () {
-               AssemblyName assemblyName = new AssemblyName();
-               assemblyName.Name = "MonoTests.System.Reflection.Emit.MethodBuilderTest";
+               static int methodIndexer = 0;
+               static int typeIndexer = 0;
 
-               AssemblyBuilder assembly 
-                       = Thread.GetDomain().DefineDynamicAssembly(
-                               assemblyName, AssemblyBuilderAccess.Run);
+               // Return a unique method name
+               private string genMethodName ()
+               {
+                       return "m" + (methodIndexer++);
+               }
 
-               module = assembly.DefineDynamicModule("module1");
-               
-               genClass = module.DefineType(genTypeName (), 
-                                                                        TypeAttributes.Public);
-       }
+               // Return a unique type name
+               private string genTypeName ()
+               {
+                       return "class" + (typeIndexer++);
+               }
 
-       static int methodIndexer = 0;
+               [Test]
+               public void TestAttributes ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), MethodAttributes.Public, typeof (void), new Type [0]);
+                       Assert.AreEqual (MethodAttributes.Public, mb.Attributes);
+               }
 
-       static int typeIndexer = 0;
+               [Test]
+               public void TestCallingConvention ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+                       Assert.AreEqual (CallingConventions.Standard | CallingConventions.HasThis,
+                               mb.CallingConvention, "CallingConvetion defaults to Standard+HasThis");
+
+                       MethodBuilder mb3 = genClass.DefineMethod (
+                               genMethodName (), 0, CallingConventions.VarArgs, typeof (void), new Type [0]);
+                       Assert.AreEqual (CallingConventions.VarArgs | CallingConventions.HasThis,
+                               mb3.CallingConvention, "CallingConvetion works");
+
+                       MethodBuilder mb4 = genClass.DefineMethod (
+                               genMethodName (), MethodAttributes.Static, CallingConventions.Standard,
+                               typeof (void), new Type [0]);
+                       Assert.AreEqual (CallingConventions.Standard, mb4.CallingConvention,
+                               "Static implies !HasThis");
+               }
 
-       // Return a unique method name
-       private string genMethodName () {
-               return "m" + (methodIndexer ++);
-       }
+               [Test]
+               public void TestDeclaringType ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
 
-       // Return a unique type name
-       private string genTypeName () {
-               return "class" + (typeIndexer ++);
-       }
+                       Assert.AreEqual (genClass, mb.DeclaringType, "DeclaringType works");
+               }
 
-       [Test]
-       public void TestAttributes () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), MethodAttributes.Public, typeof (void), new Type [0]);
+               [Test]
+               public void TestInitLocals ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
 
-               AssertEquals ("Attributes works", 
-                                         MethodAttributes.Public, mb.Attributes);
-       }
+                       Assert.IsTrue (mb.InitLocals, "#1");
+                       mb.InitLocals = false;
+                       Assert.IsFalse (mb.InitLocals, "#2");
+               }
 
-       [Test]
-       public void TestCallingConvention () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type[0]);
-               AssertEquals ("CallingConvetion defaults to Standard+HasThis",
-                                         CallingConventions.Standard | CallingConventions.HasThis,
-                                         mb.CallingConvention);
-
-               MethodBuilder mb3 = genClass.DefineMethod (
-                       genMethodName (), 0, CallingConventions.VarArgs, typeof (void), new Type[0]);
-               AssertEquals ("CallingConvetion works",
-                                         CallingConventions.VarArgs | CallingConventions.HasThis,
-                                         mb3.CallingConvention);
-
-               MethodBuilder mb4 = genClass.DefineMethod (
-                       genMethodName (), MethodAttributes.Static, CallingConventions.Standard,
-                       typeof (void), new Type [0]);
-               AssertEquals ("Static implies !HasThis",
-                                         CallingConventions.Standard,
-                                         mb4.CallingConvention);
-       }
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void TestMethodHandleIncomplete ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
 
-       [Test]
-       public void TestDeclaringType () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type[0]);
+                       RuntimeMethodHandle handle = mb.MethodHandle;
+               }
 
-               AssertEquals ("DeclaringType works",
-                                         genClass, mb.DeclaringType);
-       }
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void TestMethodHandleComplete ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+                       mb.CreateMethodBody (new byte [2], 1);
+                       genClass.CreateType ();
 
-       [Test]
-       public void TestInitLocals () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type[0]);
+                       RuntimeMethodHandle handle = mb.MethodHandle;
+               }
 
-               Assert ("InitLocals defaults to true", mb.InitLocals);
-               mb.InitLocals = false;
-               Assert ("InitLocals is settable", !mb.InitLocals);
-       }
-       
-       [Test]
-       [ExpectedException (typeof(NotSupportedException))]
-       public void TestMethodHandleIncomplete () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
+               [Test]
+               public void TestName ()
+               {
+                       string name = genMethodName ();
+                       MethodBuilder mb = genClass.DefineMethod (
+                               name, 0, typeof (void), new Type [0]);
 
-               RuntimeMethodHandle handle = mb.MethodHandle;
-       }
+                       Assert.AreEqual (name, mb.Name);
+               }
 
-       [Test]
-       [ExpectedException (typeof(NotSupportedException))]
-       public void TestMethodHandleComplete () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
-               mb.CreateMethodBody (new byte[2], 1);
-               genClass.CreateType ();
+               [Test]
+               public void TestReflectedType ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
 
-               RuntimeMethodHandle handle = mb.MethodHandle;
-       }
+                       Assert.AreEqual (genClass, mb.ReflectedType);
+               }
 
-       [Test]
-       public void TestName () {
-               string name = genMethodName ();
-               MethodBuilder mb = genClass.DefineMethod (
-                       name, 0, typeof (void), new Type [0]);
+               [Test]
+               public void TestReturnType ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (Console), new Type [0]);
+                       Assert.AreEqual (typeof (Console), mb.ReturnType, "#1");
 
-               AssertEquals ("Name works", name, mb.Name);
-       }
+                       MethodBuilder mb2 = genClass.DefineMethod (
+                               genMethodName (), 0, null, new Type [0]);
+                       Assert.IsTrue (mb2.ReturnType == null || mb2.ReturnType == typeof (void), "#2");
+               }
 
-       [Test]
-       public void TestReflectedType () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
+               [Test]
+               public void TestReturnTypeCustomAttributes ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (Console), new Type [0]);
+                       Assert.IsNull (mb.ReturnTypeCustomAttributes);
+               }
 
-               AssertEquals ("ReflectedType works", 
-                                         genClass, mb.ReflectedType);
-       }
+               /*
+               public void TestSignature () {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               "m91", 0, typeof (Console), new Type [1] { typeof (Console) });
 
-       [Test]
-       public void TestReturnType () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (Console), new Type [0]);
+                       Console.WriteLine (mb.Signature);
+               }
+               */
 
-               AssertEquals ("ReturnType works", typeof (Console),
-                                         mb.ReturnType);
+               [Test]
+               public void TestCreateMethodBody ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
 
-               
-               MethodBuilder mb2 = genClass.DefineMethod (
-                       genMethodName (), 0, null, new Type [0]);
+                       // Clear body
+                       mb.CreateMethodBody (null, 999);
 
-               Assert ("void ReturnType works", (mb2.ReturnType == null) || (mb2.ReturnType == typeof (void)));
-       }
+                       // Check arguments 1.
+                       try {
+                               mb.CreateMethodBody (new byte [1], -1);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentOutOfRangeException) {
+                       }
 
-       [Test]
-       public void TestReturnTypeCustomAttributes () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (Console), new Type [0]);
+                       // Check arguments 2.
+                       try {
+                               mb.CreateMethodBody (new byte [1], 2);
+                               Assert.Fail ("#2");
+                       } catch (ArgumentOutOfRangeException) {
+                       }
 
-               AssertEquals ("ReturnTypeCustomAttributes must be null", null,
-                                         mb.ReturnTypeCustomAttributes);
-       }
+                       mb.CreateMethodBody (new byte [2], 1);
 
-       /*
-       public void TestSignature () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       "m91", 0, typeof (Console), new Type [1] { typeof (Console) });
+                       // Could only be called once
+                       try {
+                               mb.CreateMethodBody (new byte [2], 1);
+                               Assert.Fail ("#3");
+                       } catch (InvalidOperationException) {
+                       }
 
-               Console.WriteLine (mb.Signature);
-       }
-       */
+                       // Can not be called on a created type
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb2 = tb.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+                       ILGenerator ilgen = mb2.GetILGenerator ();
+                       ilgen.Emit (OpCodes.Ret);
+                       tb.CreateType ();
+
+                       try {
+                               mb2.CreateMethodBody (new byte [2], 1);
+                               Assert.Fail ("#4");
+                       } catch (InvalidOperationException) {
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void TestDefineParameterInvalidIndexComplete ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (genMethodName (), 0, typeof (void),
+                               new Type [2] { typeof(int), typeof(int) });
+                       mb.CreateMethodBody (new byte [2], 1);
+                       tb.CreateType ();
+                       mb.DefineParameter (-5, ParameterAttributes.None, "param1");
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void TestDefineParameterValidIndexComplete ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (genMethodName (), 0, typeof (void),
+                               new Type [2] { typeof(int), typeof(int) });
+                       mb.CreateMethodBody (new byte [2], 1);
+                       tb.CreateType ();
+                       mb.DefineParameter (1, ParameterAttributes.None, "param1");
+               }
+
+               [Test]
+               public void TestDefineParameter ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [2] { typeof (int), typeof (int) });
+
+                       // index out of range
+
+                       // This fails on mono because the mono version accepts a 0 index
+                       /*
+                       try {
+                               mb.DefineParameter (0, 0, "param1");
+                               Fail ();
+                       } catch (ArgumentOutOfRangeException) {
+                       }
+                       */
+
+                       try {
+                               mb.DefineParameter (3, 0, "param1");
+                               Assert.Fail ("#1");
+                       } catch (ArgumentOutOfRangeException) {
+                       }
 
-       [Test]
-       public void TestCreateMethodBody () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
+                       // Normal usage
+                       mb.DefineParameter (1, 0, "param1");
+                       mb.DefineParameter (1, 0, "param1");
+                       mb.DefineParameter (2, 0, null);
 
-               // Clear body
-               mb.CreateMethodBody (null, 999);
+                       mb.CreateMethodBody (new byte [2], 1);
+                       tb.CreateType ();
+                       try {
+                               mb.DefineParameter (1, 0, "param1");
+                               Assert.Fail ("#2");
+                       } catch (InvalidOperationException) {
+                       }
+               }
 
-               // Check arguments 1.
-               try {
-                       mb.CreateMethodBody (new byte[1], -1);
-                       Fail ();
-               } catch (ArgumentOutOfRangeException) {
+               [Test]
+#if NET_2_0
+               // MS.NET 2.x no longer allows a zero length method body
+               // to be emitted
+               [ExpectedException (typeof (InvalidOperationException))]
+#endif
+               public void ZeroLengthBodyTest1 ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [2] { typeof (int), typeof (int) });
+                       mb.CreateMethodBody (new byte [2], 0);
+                       genClass.CreateType ();
                }
 
-               // Check arguments 2.
-               try {
-                       mb.CreateMethodBody (new byte[1], 2);
-                       Fail ();
-               } catch (ArgumentOutOfRangeException) {
+               // A zero length method body can be created
+               [Test]
+               public void ZeroLengthBodyTest2 ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [2] { typeof (int), typeof (int) });
+                       mb.CreateMethodBody (new byte [2], 0);
                }
 
-               mb.CreateMethodBody (new byte[2], 1);
+               [Test]
+               public void TestHashCode ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       string methodName = genMethodName ();
+                       MethodBuilder mb = tb.DefineMethod (methodName, 0, typeof (void),
+                               new Type [2] { typeof(int), typeof(int) });
+                       Assert.AreEqual (methodName.GetHashCode (), mb.GetHashCode ());
+               }
 
-               // Could only be called once
-               try {
-                       mb.CreateMethodBody (new byte[2], 1);
-                       Fail ();
-               } catch (InvalidOperationException) {
+               [Test]
+               public void TestGetBaseDefinition ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+                       Assert.AreEqual (mb.GetBaseDefinition (), mb);
                }
 
-               // Can not be called on a created type
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb2 = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
-               ILGenerator ilgen = mb2.GetILGenerator ();
-               ilgen.Emit (OpCodes.Ret);
-               tb.CreateType ();
+               [Test]
+               public void TestGetILGenerator ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+
+                       // The same instance is returned on the second call
+                       ILGenerator ilgen1 = mb.GetILGenerator ();
+                       ILGenerator ilgen2 = mb.GetILGenerator ();
 
-               try {
-                       mb2.CreateMethodBody (new byte[2], 1);
-                       Fail ();
-               } catch (InvalidOperationException) {
+                       Assert.AreEqual (ilgen1, ilgen2, "#1");
+
+                       // Does not work on unmanaged code
+                       MethodBuilder mb2 = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+                       try {
+                               mb2.SetImplementationFlags (MethodImplAttributes.Unmanaged);
+                               mb2.GetILGenerator ();
+                               Assert.Fail ("#2");
+                       } catch (InvalidOperationException) {
+                       }
+                       try {
+                               mb2.SetImplementationFlags (MethodImplAttributes.Native);
+                               mb2.GetILGenerator ();
+                               Assert.Fail ("#3");
+                       } catch (InvalidOperationException) {
+                       }
                }
-       }
 
-       [Test]
-       [ExpectedException (typeof(InvalidOperationException))]
-       public void TestDefineParameterInvalidIndexComplete ()
-       {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void),
-                       new Type[2] {
-                       typeof(int), typeof(int)
-               });
-               mb.CreateMethodBody (new byte[2], 1);
-               tb.CreateType ();
-               mb.DefineParameter (-5, ParameterAttributes.None, "param1");
-       }
+               [Test]
+               public void TestMethodImplementationFlags ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
 
-       [Test]
-       [ExpectedException (typeof(InvalidOperationException))]
-       public void TestDefineParameterValidIndexComplete ()
-       {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void),
-                       new Type[2] {
-                       typeof(int), typeof(int)
-               });
-               mb.CreateMethodBody (new byte[2], 1);
-               tb.CreateType ();
-               mb.DefineParameter (1, ParameterAttributes.None, "param1");
-       }
+                       Assert.AreEqual (MethodImplAttributes.Managed | MethodImplAttributes.IL,
+                               mb.GetMethodImplementationFlags (), "#1");
 
-       [Test]
-       public void TestDefineParameter () {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void), 
-                       new Type [2] { typeof(int), typeof(int) });
+                       mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
 
-               // index out of range
+                       Assert.AreEqual (MethodImplAttributes.OPTIL, mb.GetMethodImplementationFlags (), "#2");
 
-               // This fails on mono because the mono version accepts a 0 index
-               /*
-               try {
-                       mb.DefineParameter (0, 0, "param1");
-                       Fail ();
-               } catch (ArgumentOutOfRangeException) {
+                       mb.CreateMethodBody (new byte [2], 1);
+                       mb.SetImplementationFlags (MethodImplAttributes.Managed);
+                       tb.CreateType ();
+                       try {
+                               mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
+                               Assert.Fail ("#3");
+                       } catch (InvalidOperationException) {
+                       }
                }
-               */
 
-               try {
-                       mb.DefineParameter (3, 0, "param1");
-                       Fail ();
-               } catch (ArgumentOutOfRangeException) {
+               [Test]
+               public void TestGetModule ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [0]);
+                       Assert.AreEqual (module, mb.GetModule ());
                }
 
-               // Normal usage
-               mb.DefineParameter (1, 0, "param1");
-               mb.DefineParameter (1, 0, "param1");
-               mb.DefineParameter (2, 0, null);
+               [Test]
+               public void TestGetParameters ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (genMethodName (), 0, typeof (void),
+                               new Type [1] { typeof (void) });
+
+                       /*
+                        * According to the MSDN docs, this method should fail with a
+                        * NotSupportedException. In reality, it throws an 
+                        * InvalidOperationException under MS .NET, and returns the 
+                        * requested data under mono.
+                        */
+                       /*
+                       try {
+                               mb.GetParameters ();
+                               Fail ("#161");
+                       } catch (InvalidOperationException ex) {
+                               Console.WriteLine (ex);
+                       }
+                       */
+               }
 
-               mb.CreateMethodBody (new byte[2], 1);
-               tb.CreateType ();
-               try {
-                       mb.DefineParameter (1, 0, "param1");
-                       Fail ();
+               [Test]
+               public void TestGetToken ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               genMethodName (), 0, typeof (void), new Type [1] { typeof (void) });
+                       mb.GetToken ();
                }
-               catch (InvalidOperationException) {
+
+               [Test]
+               public void TestInvoke ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [1] { typeof (int) });
+
+                       try {
+                               mb.Invoke (null, new object [1] { 42 });
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException) {
+                       }
+
+                       try {
+                               mb.Invoke (null, 0, null, new object [1] { 42 }, null);
+                               Assert.Fail ("#2");
+                       } catch (NotSupportedException) {
+                       }
                }
-       }
 
-       [Test]
-#if NET_2_0
-       // MS.NET 2.x no longer allows a zero length method body
-       // to be emitted
-       [ExpectedException (typeof (InvalidOperationException))]
-#endif
-       public void ZeroLengthBodyTest1 ()
-       {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), 
-                       new Type [2] { typeof(int), typeof(int) });
-               mb.CreateMethodBody (new byte[2], 0);
-               genClass.CreateType ();
-       }
+               [Test]
+               [ExpectedException (typeof (NotSupportedException))]
+               public void TestIsDefined ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [1] { typeof (int) });
+                       mb.IsDefined (null, true);
+               }
 
-       // A zero length method body can be created
-       [Test]
-       public void ZeroLengthBodyTest2 ()
-       {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), 
-                       new Type [2] { typeof(int), typeof(int) });
-               mb.CreateMethodBody (new byte[2], 0);
-       }
+               [Test]
+               public void TestGetCustomAttributes_Incomplete ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [1] { typeof (int) });
 
-       [Test]
-       public void TestHashCode ()
-       {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               string methodName = genMethodName ();
-               MethodBuilder mb = tb.DefineMethod (
-                       methodName, 0, typeof (void),
-                       new Type[2] {
-                       typeof(int), typeof(int)
-               });
-               AssertEquals ("Hashcode of method should be equal to hashcode of method name",
-                       methodName.GetHashCode (), mb.GetHashCode ());
-       }
+                       try {
+                               mb.GetCustomAttributes (true);
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException) {
+                       }
+
+                       try {
+                               mb.GetCustomAttributes (null, true);
+                               Assert.Fail ("#2");
+                       } catch (NotSupportedException) {
+                       }
+               }
 
-       [Test]
-       public void TestGetBaseDefinition () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
+               [Test]
+               [Category ("NotWorking")]
+               public void TestGetCustomAttributes_Complete ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), 0, typeof (void),
+                               new Type [1] { typeof (int) });
+                       mb.GetILGenerator ().Emit (OpCodes.Ret);
+                       genClass.CreateType ();
 
-               AssertEquals ("GetBaseDefinition works",
-                                         mb.GetBaseDefinition (), mb);
-       }
+                       try {
+                               mb.GetCustomAttributes (true);
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException) {
+                       }
 
-       [Test]
-       public void TestGetILGenerator () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
-
-               // The same instance is returned on the second call
-               ILGenerator ilgen1 = mb.GetILGenerator ();
-               ILGenerator ilgen2 = mb.GetILGenerator ();
-
-               AssertEquals ("The same ilgen is returned on the second call",
-                                         ilgen1, ilgen2);
-
-               // Does not work on unmanaged code
-               MethodBuilder mb2 = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);              
-               try {
-                       mb2.SetImplementationFlags (MethodImplAttributes.Unmanaged);
-                       mb2.GetILGenerator ();
-                       Fail ();
-               } catch (InvalidOperationException) {
-               }
-               try {
-                       mb2.SetImplementationFlags (MethodImplAttributes.Native);
-                       mb2.GetILGenerator ();
-                       Fail ();
-               } catch (InvalidOperationException) {
+                       try {
+                               mb.GetCustomAttributes (null, true);
+                               Assert.Fail ("#2");
+                       } catch (NotSupportedException) {
+                       }
                }
-       }
 
-       [Test]
-       public void TestMethodImplementationFlags () {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
+               [Test]
+               public void TestSetCustomAttribute ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       string name = genMethodName ();
+                       MethodBuilder mb = tb.DefineMethod (
+                               name, MethodAttributes.Public, typeof (void),
+                               new Type [1] { typeof (int) });
 
-               AssertEquals ("MethodImplementationFlags defaults to Managed+IL",
-                                         MethodImplAttributes.Managed | MethodImplAttributes.IL,
-                                         mb.GetMethodImplementationFlags ());
+                       // Null argument
+                       try {
+                               mb.SetCustomAttribute (null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException) {
+                       }
 
-               mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
+                       byte [] custAttrData = { 1, 0, 0, 0, 0 };
+                       Type attrType = Type.GetType
+                               ("System.Reflection.AssemblyKeyNameAttribute");
+                       Type [] paramTypes = new Type [1];
+                       paramTypes [0] = typeof (String);
+                       ConstructorInfo ctorInfo =
+                               attrType.GetConstructor (paramTypes);
 
-               AssertEquals ("SetImplementationFlags works",
-                                         MethodImplAttributes.OPTIL, 
-                                         mb.GetMethodImplementationFlags ());
+                       mb.SetCustomAttribute (ctorInfo, custAttrData);
 
-               mb.CreateMethodBody (new byte[2], 1);
-               mb.SetImplementationFlags (MethodImplAttributes.Managed);
-               tb.CreateType ();
-               try {
-                       mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
-                       Fail ();
+                       // Test MethodImplAttribute
+                       mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (MethodImplAttribute).GetConstructor (new Type [1] { typeof (short) }), new object [1] { (short) MethodImplAttributes.Synchronized }));
+                       mb.GetILGenerator ().Emit (OpCodes.Ret);
+
+                       Type t = tb.CreateType ();
+
+                       Assert.AreEqual (t.GetMethod (name).GetMethodImplementationFlags (),
+                               MethodImplAttributes.Synchronized, "#2");
+
+                       // Null arguments again
+                       try {
+                               mb.SetCustomAttribute (null, new byte [2]);
+                               Assert.Fail ("#3");
+                       } catch (ArgumentNullException) {
+                       }
+
+                       try {
+                               mb.SetCustomAttribute (ctorInfo, null);
+                               Assert.Fail ("#4");
+                       } catch (ArgumentNullException) {
+                       }
                }
-               catch (InvalidOperationException) {
+
+               [Test]
+               public void SetCustomAttribute_DllImport_DllName_Empty ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (genMethodName (),
+                               MethodAttributes.Public, typeof (void),
+                               new Type [1] { typeof (int) });
+
+                       ConstructorInfo ctorInfo = typeof (DllImportAttribute).GetConstructor (
+                               new Type [] { typeof (string) });
+                       try {
+                               mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo,
+                                       new object [] { string.Empty }));
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNull (ex.ParamName, "#5");
+                       }
                }
-       }
 
-       [Test]
-       public void TestGetModule () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [0]);
+               [Test]
+               public void SetCustomAttribute_DllImport_DllName_Null ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (genMethodName (),
+                               MethodAttributes.Public, typeof (void),
+                               new Type [1] { typeof (int) });
 
-               AssertEquals ("GetMethod works", module, 
-                                         mb.GetModule ());
-       }
+                       ConstructorInfo ctorInfo = typeof (DllImportAttribute).GetConstructor (
+                               new Type [] { typeof (string) });
+                       try {
+                               mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo,
+                                       new object [] { null }));
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNull (ex.ParamName, "#5");
+                       }
+               }
 
-       [Test]
-       public void TestGetParameters () {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [1] {typeof(void)});
+               [Test]
+               public void SetCustomAttribute_SuppressUnmanagedCodeSecurity ()
+               {
+                       string mname = genMethodName ();
+
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (mname, MethodAttributes.Public,
+                               typeof (void), new Type [] { typeof (int), typeof (string) });
+                       ConstructorInfo attrCtor = typeof (SuppressUnmanagedCodeSecurityAttribute).
+                               GetConstructor (new Type [0]);
+                       CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (
+                               attrCtor, new object [0]);
+                       Assert.IsTrue ((mb.Attributes & MethodAttributes.HasSecurity) == 0, "#1");
+                       mb.SetCustomAttribute (caBuilder);
+                       //Assert.IsTrue ((mb.Attributes & MethodAttributes.HasSecurity) == 0, "#2");
+                       mb.GetILGenerator ().Emit (OpCodes.Ret);
+                       Type emittedType = tb.CreateType ();
+                       MethodInfo emittedMethod = emittedType.GetMethod (mname);
+                       Assert.AreEqual (MethodAttributes.HasSecurity, emittedMethod.Attributes & MethodAttributes.HasSecurity, "#3");
+                       //Assert.IsTrue ((mb.Attributes & MethodAttributes.HasSecurity) == 0, "#4");
+                       object [] emittedAttrs = emittedMethod.GetCustomAttributes (typeof (SuppressUnmanagedCodeSecurityAttribute), true);
+                       Assert.AreEqual (1, emittedAttrs.Length, "#5");
+               }
 
-               /*
-                * According to the MSDN docs, this method should fail with a
-                * NotSupportedException. In reality, it throws an 
-                * InvalidOperationException under MS .NET, and returns the 
-                * requested data under mono.
-                */
-               /*
-               try {
-                       mb.GetParameters ();
-                       Fail ("#161");
-               } catch (InvalidOperationException ex) {
-                       Console.WriteLine (ex);
+               [AttributeUsage (AttributeTargets.Parameter)]
+               class PrivateAttribute : Attribute
+               {
+
+                       public PrivateAttribute ()
+                       {
+                       }
                }
-               */
-       }
 
-       [Test]
-       public void TestGetToken () {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       genMethodName (), 0, typeof (void), new Type [1] {typeof(void)});
+               [Test]
+               public void GetCustomAttributes ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public,
+                                                                                               typeof (void),
+                                                                                               new Type [1] { typeof (int) });
+                       mb.GetILGenerator ().Emit (OpCodes.Ret);
 
-               mb.GetToken ();
-       }
+                       Type attrType = typeof (ObsoleteAttribute);
+                       ConstructorInfo ctorInfo =
+                               attrType.GetConstructor (new Type [] { typeof (String) });
+
+                       mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
+
+                       // Check that attributes not accessible are not returned
+                       mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (PrivateAttribute).GetConstructor (new Type [0]), new object [] { }));
 
-       [Test]
-       public void TestInvoke () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), 
-                       new Type [1] {typeof(int)});
+                       Type t = tb.CreateType ();
 
-               try {
-                       mb.Invoke (null, new object [1] { 42 });
-                       Fail ();
-               } catch (NotSupportedException) {
+                       // Try the created type
+                       {
+                               MethodInfo mi = t.GetMethod ("foo");
+                               object [] attrs = mi.GetCustomAttributes (true);
+
+                               Assert.AreEqual (1, attrs.Length, "#A1");
+                               Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#A2");
+                               Assert.AreEqual ("FOO", ((ObsoleteAttribute) attrs [0]).Message, "#A3");
+                       }
+
+                       // Try the type builder
+                       {
+                               MethodInfo mi = tb.GetMethod ("foo");
+                               object [] attrs = mi.GetCustomAttributes (true);
+
+                               Assert.AreEqual (1, attrs.Length, "#B1");
+                               Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#B2");
+                               Assert.AreEqual ("FOO", ((ObsoleteAttribute) attrs [0]).Message, "#B3");
+                       }
+               }
+#if !NET_2_1
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void TestAddDeclarativeSecurityAlreadyCreated ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), MethodAttributes.Public, typeof (void),
+                               new Type [0]);
+                       ILGenerator ilgen = mb.GetILGenerator ();
+                       ilgen.Emit (OpCodes.Ret);
+                       genClass.CreateType ();
+
+                       PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+                       mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
                }
 
-               try {
-                       mb.Invoke (null, 0, null, new object [1] { 42 }, null);
-                       Fail ();
-               } catch (NotSupportedException) {
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddDeclarativeSecurityNullPermissionSet ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), MethodAttributes.Public, typeof (void),
+                               new Type [0]);
+                       mb.AddDeclarativeSecurity (SecurityAction.Demand, null);
                }
-       }
 
-       [Test]
-       [ExpectedException (typeof (NotSupportedException))]
-       public void TestIsDefined () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), 
-                       new Type [1] {typeof(int)});
-               mb.IsDefined (null, true);
-       }
+               [Test]
+               public void TestAddDeclarativeSecurityInvalidAction ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), MethodAttributes.Public, typeof (void),
+                               new Type [0]);
 
-       [Test]
-       public void TestGetCustomAttributes () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), 0, typeof (void), 
-                       new Type [1] {typeof(int)});
-               
-               try {
-                       mb.GetCustomAttributes (true);
-                       Fail ();
-               } catch (NotSupportedException) {
+                       SecurityAction [] actions = new SecurityAction [] { 
+                       SecurityAction.RequestMinimum,
+                       SecurityAction.RequestOptional,
+                       SecurityAction.RequestRefuse };
+                       PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+
+                       foreach (SecurityAction action in actions) {
+                               try {
+                                       mb.AddDeclarativeSecurity (action, set);
+                                       Assert.Fail ();
+                               } catch (ArgumentOutOfRangeException) {
+                               }
+                       }
                }
 
-               try {
-                       mb.GetCustomAttributes (null, true);
-                       Fail ();
-               } catch (NotSupportedException) {
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void TestAddDeclarativeSecurityDuplicateAction ()
+               {
+                       MethodBuilder mb = genClass.DefineMethod (
+                               genMethodName (), MethodAttributes.Public, typeof (void),
+                               new Type [0]);
+                       PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+                       mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+                       mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+               }
+#endif
+               [AttributeUsage (AttributeTargets.Parameter)]
+               class ParamAttribute : Attribute
+               {
+
+                       public ParamAttribute ()
+                       {
+                       }
+               }
+
+               [Test]
+               public void TestDynamicParams ()
+               {
+                       string mname = genMethodName ();
+
+                       MethodBuilder mb = genClass.DefineMethod (
+                               mname, MethodAttributes.Public, typeof (void),
+                               new Type [] { typeof (int), typeof (string) });
+                       ParameterBuilder pb = mb.DefineParameter (1, ParameterAttributes.In, "foo");
+                       pb.SetConstant (52);
+                       pb.SetCustomAttribute (new CustomAttributeBuilder (typeof (ParamAttribute).GetConstructors () [0], new object [] { }));
+                       ParameterBuilder pb2 = mb.DefineParameter (2, 0, "bar");
+                       pb2.SetConstant ("foo");
+                       mb.GetILGenerator ().Emit (OpCodes.Ret);
+
+                       Type t = genClass.CreateType ();
+                       MethodInfo m = t.GetMethod (mname);
+                       ParameterInfo [] pi = m.GetParameters ();
+
+                       Assert.AreEqual ("foo", pi [0].Name, "#A1");
+                       Assert.IsTrue (pi [0].IsIn, "#A2");
+                       Assert.AreEqual (52, pi [0].DefaultValue, "#A3");
+                       object [] cattrs = pi [0].GetCustomAttributes (true);
+#if NET_2_0
+                       Assert.AreEqual (1, cattrs.Length, "#A4");
+                       Assert.AreEqual (typeof (InAttribute), cattrs [0].GetType (), "#A5");
+#else
+                       Assert.AreEqual (0, cattrs.Length, "#A4");
+#endif
+
+                       cattrs = pi [1].GetCustomAttributes (true);
+                       Assert.AreEqual ("foo", pi [1].DefaultValue, "#B1");
                }
-       }
 
-       [Test]
-       public void TestSetCustomAttribute () {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               string name = genMethodName ();
-               MethodBuilder mb = tb.DefineMethod (
-                       name, MethodAttributes.Public, typeof (void), 
-                       new Type [1] {typeof(int)});
+               [Test]
+               public void SetCustomAttribute_DllImport1 ()
+               {
+                       string mname = genMethodName ();
+
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               mname, MethodAttributes.Public, typeof (void), 
+                               new Type [] { typeof (int), typeof (string) });
+
+                       // Create an attribute with default values
+                       mb.SetCustomAttribute (new CustomAttributeBuilder(typeof(DllImportAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "kernel32" }));
+
+                       Type t = tb.CreateType ();
+
+                       DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
 
-               // Null argument
-               try {
-                       mb.SetCustomAttribute (null);
-                       Fail ();
-               } catch (ArgumentNullException) {
+                       Assert.AreEqual (CallingConvention.Winapi, attr.CallingConvention, "#1");
+                       Assert.AreEqual (mname, attr.EntryPoint, "#2");
+                       Assert.AreEqual ("kernel32", attr.Value, "#3");
+                       Assert.IsFalse (attr.ExactSpelling, "#4");
+                       Assert.IsTrue (attr.PreserveSig, "#5");
+                       Assert.IsFalse (attr.SetLastError, "#6");
+                       Assert.IsFalse (attr.BestFitMapping, "#7");
+                       Assert.IsFalse (attr.ThrowOnUnmappableChar, "#8");
                }
 
-               byte[] custAttrData = { 1, 0, 0, 0, 0};
-               Type attrType = Type.GetType
-                       ("System.Reflection.AssemblyKeyNameAttribute");
-               Type[] paramTypes = new Type[1];
-               paramTypes[0] = typeof(String);
-               ConstructorInfo ctorInfo =
-                       attrType.GetConstructor(paramTypes);
+               [Test]
+               public void SetCustomAttribute_DllImport2 () {
+                       string mname = genMethodName ();
 
-               mb.SetCustomAttribute (ctorInfo, custAttrData);
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               mname, MethodAttributes.Public, typeof (void), 
+                               new Type [] { typeof (int), typeof (string) });
 
-               // Test MethodImplAttribute
-               mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (MethodImplAttribute).GetConstructor (new Type[1] { typeof (short) }), new object[1] {(short)MethodImplAttributes.Synchronized}));
-               mb.GetILGenerator ().Emit (OpCodes.Ret);
+                       CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] {typeof (DllImportAttribute).GetField ("EntryPoint"), typeof (DllImportAttribute).GetField ("CallingConvention"), typeof (DllImportAttribute).GetField ("CharSet"), typeof (DllImportAttribute).GetField ("ExactSpelling"), typeof (DllImportAttribute).GetField ("PreserveSig")}, new object [] { "bar", CallingConvention.StdCall, CharSet.Unicode, true, false });
+                       mb.SetCustomAttribute (cb);
 
-               Type t = tb.CreateType ();
+                       Type t = tb.CreateType ();
 
-               AssertEquals ("Setting MethodImplAttributes works",
-                                         t.GetMethod (name).GetMethodImplementationFlags (),
-                                         MethodImplAttributes.Synchronized);
+                       DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
 
-               // Null arguments again
-               try {
-                       mb.SetCustomAttribute (null, new byte[2]);
-                       Fail ();
-               } catch (ArgumentNullException) {
+                       Assert.AreEqual (CallingConvention.StdCall, attr.CallingConvention, "#1");
+                       Assert.AreEqual (CharSet.Unicode, attr.CharSet, "#2");
+                       Assert.AreEqual ("bar", attr.EntryPoint, "#3");
+                       Assert.AreEqual ("foo", attr.Value, "#4");
+                       Assert.IsTrue (attr.ExactSpelling, "#5");
+                       Assert.IsFalse (attr.PreserveSig, "#6");
+                       Assert.IsFalse (attr.SetLastError, "#7");
+                       Assert.IsFalse (attr.BestFitMapping, "#8");
+                       Assert.IsFalse (attr.ThrowOnUnmappableChar, "#9");
                }
 
-               try {
-                       mb.SetCustomAttribute (ctorInfo, null);
-                       Fail ();
-               } catch (ArgumentNullException) {
+               [Test]
+               public void SetCustomAttribute_DllImport3 () {
+                       string mname = genMethodName ();
+
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               mname, MethodAttributes.Public, typeof (void), 
+                               new Type [] { typeof (int), typeof (string) });
+
+                       // Test attributes with three values (on/off/missing)
+                       CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { false, false });
+                       mb.SetCustomAttribute (cb);
+
+                       Type t = tb.CreateType ();
+
+                       DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+
+                       Assert.IsFalse (attr.BestFitMapping, "#1");
+                       Assert.IsFalse (attr.ThrowOnUnmappableChar, "#2");
                }
-       }
 
-       [AttributeUsage (AttributeTargets.Parameter)]
-       class PrivateAttribute : Attribute {
+               [Test]
+               public void SetCustomAttribute_DllImport4 ()
+               {
+                       string mname = genMethodName ();
+
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod (
+                               mname, MethodAttributes.Public, typeof (void), 
+                               new Type [] { typeof (int), typeof (string) });
+
+                       CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("SetLastError"), typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { true, true, true });
+                       mb.SetCustomAttribute (cb);
+
+                       Type t = tb.CreateType ();
 
-               public PrivateAttribute () {
+                       DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+
+                       Assert.IsTrue (attr.SetLastError, "#1");
+                       Assert.IsTrue (attr.BestFitMapping, "#2");
+                       Assert.IsTrue (attr.ThrowOnUnmappableChar, "#3");
+               }
+
+               public class GenericFoo <T> {
+                       public static T field;
                }
-       }
 
-       [Test]
-       public void GetCustomAttributes () {
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public, 
-                                                                                       typeof (void),
-                                                                                       new Type [1] {typeof(int)});
-               mb.GetILGenerator ().Emit (OpCodes.Ret);
+               [Test]
+               public void ILGen_GenericTypeParameterBuilder ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod ("box_int", 
+                                                                                               MethodAttributes.Public|MethodAttributes.Static, typeof (object), new Type [] { typeof (int) });
+
+                       GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters (new string [] { "foo" });
+
+                       ILGenerator ilgen = mb.GetILGenerator ();
+                       ilgen.Emit (OpCodes.Ldarg_0);
+                       ilgen.Emit (OpCodes.Box, pars [0]);
+                       ilgen.Emit (OpCodes.Ret);
+
+                       Type t = tb.CreateType ();
+                       MethodInfo mi = t.GetMethod ("box_int");
+                       MethodInfo mi2 = mi.MakeGenericMethod (new Type [] { typeof (int) });
+                       Assert.AreEqual (1, mi2.Invoke (null, new object [] { 1 }));
+               }
 
-               Type attrType = typeof (ObsoleteAttribute);
-               ConstructorInfo ctorInfo =
-                       attrType.GetConstructor (new Type [] { typeof (String) });
+               public void ILGen_InstantiatedGenericType ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod ("return_type", 
+                                                                                               MethodAttributes.Public|MethodAttributes.Static, typeof (object), new Type [] { });
+
+                       GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters (new string [] { "foo" });
 
-               mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
+                       ILGenerator ilgen = mb.GetILGenerator ();
 
-               // Check that attributes not accessible are not returned
-               mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (PrivateAttribute).GetConstructor (new Type [0]), new object [] { }));
+                       Type genericFoo = typeof (GenericFoo<int>).GetGenericTypeDefinition ().MakeGenericType (new Type [] { pars [0] });
 
-               Type t = tb.CreateType ();
+                       ilgen.Emit (OpCodes.Ldtoken, genericFoo);
+                       ilgen.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
+                       ilgen.Emit (OpCodes.Ret);
 
-               // Try the created type
+                       Type t = tb.CreateType ();
+                       MethodInfo mi = t.GetMethod ("box_int");
+                       MethodInfo mi2 = mi.MakeGenericMethod (new Type [] { typeof (int) });
+                       Assert.AreEqual (typeof (GenericFoo<int>), mi2.Invoke (null, new object [] { 1 }));
+               }
+
+               public void ILGen_InstantiatedTypeBuilder ()
                {
-                       MethodInfo mi = t.GetMethod ("foo");
-                       object[] attrs = mi.GetCustomAttributes (true);
+                       TypeBuilder genericTb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       genericTb.DefineGenericParameters (new string [] { "foo" });
+                       Type generatedGenericType = genericTb.CreateType ();
+
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod ("return_type", 
+                                                                                               MethodAttributes.Public|MethodAttributes.Static, typeof (object), new Type [] { });
 
-                       AssertEquals (1, attrs.Length);
-                       Assert (attrs [0] is ObsoleteAttribute);
-                       AssertEquals ("FOO", ((ObsoleteAttribute)attrs [0]).Message);
+                       GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters (new string [] { "foo" });
+
+                       ILGenerator ilgen = mb.GetILGenerator ();
+
+                       ilgen.Emit (OpCodes.Ldtoken, genericTb.MakeGenericType (new Type [] { pars [0] }));
+                       ilgen.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
+                       ilgen.Emit (OpCodes.Ret);
+
+                       Type t = tb.CreateType ();
+                       MethodInfo mi = t.GetMethod ("return_type");
+                       MethodInfo mi2 = mi.MakeGenericMethod (new Type [] { typeof (int) });
+                       Assert.AreEqual (generatedGenericType.MakeGenericType (new Type [] { typeof (int) }), mi2.Invoke (null, new object [] { 1 }));
+               }
+
+               [Test]
+               public void Bug354757 ()
+               {
+                       TypeBuilder gtb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       gtb.DefineGenericParameters ("T");
+                       MethodBuilder mb = gtb.DefineMethod ("foo", MethodAttributes.Public);
+                       mb.DefineGenericParameters ("S");
+                       Assert.IsTrue (mb.IsGenericMethodDefinition);
+
+                       Type gt = gtb.MakeGenericType (typeof (object));
+                       MethodInfo m = TypeBuilder.GetMethod (gt, mb);
+                       Assert.IsTrue (m.IsGenericMethodDefinition);
+
+                       MethodInfo mopen = m.MakeGenericMethod (m.GetGenericArguments ());
+                       Assert.IsFalse (mopen.IsGenericMethodDefinition);
                }
 
-               // Try the type builder
+               [Test]
+               public void DefineGenericParameters_Names_Empty ()
                {
-                       MethodInfo mi = tb.GetMethod ("foo");
-                       object[] attrs = mi.GetCustomAttributes (true);
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public);
 
-                       AssertEquals (1, attrs.Length);
-                       Assert (attrs [0] is ObsoleteAttribute);
-                       AssertEquals ("FOO", ((ObsoleteAttribute)attrs [0]).Message);
+                       try {
+                               mb.DefineGenericParameters (new string [0]);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               // Value does not fall within the expected range
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNull (ex.ParamName, "#5");
+                       }
                }
-       }
 
-       [Test]
-       [ExpectedException (typeof (InvalidOperationException))]
-       public void TestAddDeclarativeSecurityAlreadyCreated () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), MethodAttributes.Public, typeof (void),
-                       new Type [0]);
-               ILGenerator ilgen = mb.GetILGenerator ();
-               ilgen.Emit (OpCodes.Ret);
-               genClass.CreateType ();
-
-               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
-       }
 
-       [Test]
-       [ExpectedException (typeof (ArgumentNullException))]
-       public void TestAddDeclarativeSecurityNullPermissionSet () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), MethodAttributes.Public, typeof (void), 
-                       new Type [0]);
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, null);
-       }
 
-       [Test]
-       public void TestAddDeclarativeSecurityInvalidAction () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), MethodAttributes.Public, typeof (void), 
-                       new Type [0]);
+               [Test]
+               public void DefineGenericParameters_Names_Null ()
+               {
+                       TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
+                       MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public);
 
-               SecurityAction[] actions = new SecurityAction [] { 
-                       SecurityAction.RequestMinimum,
-                       SecurityAction.RequestOptional,
-                       SecurityAction.RequestRefuse };
-               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
+                       try {
+                               mb.DefineGenericParameters ((string []) null);
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.AreEqual ("names", ex.ParamName, "#A5");
+                       }
 
-               foreach (SecurityAction action in actions) {
                        try {
-                               mb.AddDeclarativeSecurity (action, set);
-                               Fail ();
-                       } catch (ArgumentOutOfRangeException) {
+                               mb.DefineGenericParameters ("K", null, "V");
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.AreEqual ("names", ex.ParamName, "#B5");
                        }
                }
-       }
 
-       [Test]
-       [ExpectedException (typeof (InvalidOperationException))]
-       public void TestAddDeclarativeSecurityDuplicateAction () {
-               MethodBuilder mb = genClass.DefineMethod (
-                       genMethodName (), MethodAttributes.Public, typeof (void), 
-                       new Type [0]);
-               PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
-               mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
-       }
 
-       [AttributeUsage (AttributeTargets.Parameter)]
-       class ParamAttribute : Attribute {
+               public static int Foo<T> (T a, T b) {
+                       return 99;
+               }
+
+               [Test]//bug #591226
+               public void GenericMethodIsProperlyInflated ()
+               {
+                       var tb = module.DefineType ("foo");
+                       var met = typeof (MethodBuilderTest).GetMethod ("Foo");
+
+                       var mb = tb.DefineMethod ("myFunc", MethodAttributes.Public | MethodAttributes.Static, typeof (int), Type.EmptyTypes);
+                       var garg = mb.DefineGenericParameters ("a") [0];
+                       mb.SetParameters (garg, garg);
 
-               public ParamAttribute () {
+                       var ilgen = mb.GetILGenerator ();
+                       ilgen.Emit (OpCodes.Ldarg_0);
+                       ilgen.Emit (OpCodes.Ldarg_1);
+                       ilgen.Emit (OpCodes.Call, met.MakeGenericMethod (garg));
+                       ilgen.Emit (OpCodes.Ret);
+
+                       var res = tb.CreateType ();
+                       var mm = res.GetMethod ("myFunc").MakeGenericMethod (typeof (int));
+
+                       var rt = mm.Invoke (null, new object[] { 10, 20 });
+                       Assert.AreEqual (99, rt, "#1");
                }
-       }
 
-       [Test]
-       public void TestDynamicParams () {
-               string mname = genMethodName ();
-
-               MethodBuilder mb = genClass.DefineMethod (
-                       mname, MethodAttributes.Public, typeof (void), 
-                       new Type [] { typeof (int), typeof (string) });
-               ParameterBuilder pb = mb.DefineParameter (1, ParameterAttributes.In, "foo");
-               pb.SetConstant (52);
-               pb.SetCustomAttribute (new CustomAttributeBuilder (typeof (ParamAttribute).GetConstructors () [0], new object [] { }));
-               ParameterBuilder pb2 = mb.DefineParameter (2, 0, "bar");
-               pb2.SetConstant ("foo");
-               mb.GetILGenerator ().Emit (OpCodes.Ret);
-
-               Type t = genClass.CreateType ();
-               MethodInfo m = t.GetMethod (mname);
-               ParameterInfo[] pi = m.GetParameters ();
-
-               AssertEquals ("foo", pi [0].Name);
-               AssertEquals (true, pi [0].IsIn);
-               AssertEquals (52, pi [0].DefaultValue);
-               object[] cattrs = pi [0].GetCustomAttributes (true);
-
-               AssertEquals ("foo", pi [1].DefaultValue);
-               
-
-               /* This test does not run under MS.NET: */
-               /*
-                 AssertEquals (1, cattrs.Length);
-                 AssertEquals (typeof (ParamAttribute), cattrs [0].GetType ());
-               */
-       }
+           public static void VarargMethod (string headline, __arglist) {
+               ArgIterator ai = new ArgIterator (__arglist);
+       
+               Console.Write (headline);
+               while (ai.GetRemainingCount () > 0)
+                   Console.Write (TypedReference.ToObject (ai.GetNextArg ()));
+               Console.WriteLine ();
+           }
+
+               [Test]//bug #626441
+               public void CanCallVarargMethods ()
+               {
+                       var tb = module.DefineType ("foo");
+                       MethodBuilder mb = tb.DefineMethod ("CallVarargMethod", 
+                               MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard,
+                               typeof (void), Type.EmptyTypes);
+
+                       ILGenerator il = mb.GetILGenerator ();
+                       MethodInfo miVarargMethod = typeof (MethodBuilderTest).GetMethod ("VarargMethod");
+                       
+                       il.Emit (OpCodes.Ldstr, "Hello world from ");
+                       il.Emit (OpCodes.Call, typeof(Assembly).GetMethod ("GetExecutingAssembly"));
+                       il.EmitCall (OpCodes.Call, miVarargMethod, new Type[] { typeof(Assembly) });
+                       
+                       il.Emit (OpCodes.Ldstr, "Current time: ");
+                       il.Emit (OpCodes.Call, typeof(DateTime).GetMethod("get_Now"));
+                       il.Emit (OpCodes.Ldstr, " (UTC ");
+                       il.Emit (OpCodes.Call, typeof(DateTime).GetMethod("get_UtcNow"));
+                       il.Emit (OpCodes.Ldstr, ")");
+                       il.EmitCall (OpCodes.Call, miVarargMethod, new Type[] { typeof (DateTime), typeof (string), typeof (DateTime), typeof (string) });
+                       il.Emit (OpCodes.Ret);
+
+                       Type type = tb.CreateType ();
+                       type.GetMethod ("CallVarargMethod").Invoke (null, null);
+               }
 
-#if NET_2_0
-       [Test]
-       public void SetCustomAttribute_DllImport1 () {
-               string mname = genMethodName ();
-
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       mname, MethodAttributes.Public, typeof (void), 
-                       new Type [] { typeof (int), typeof (string) });
-
-               // Create an attribute with default values
-               mb.SetCustomAttribute (new CustomAttributeBuilder(typeof(DllImportAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "kernel32" }));
-
-               Type t = tb.CreateType ();
-
-               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
-
-               AssertEquals (CallingConvention.Winapi, attr.CallingConvention);
-               AssertEquals (mname, attr.EntryPoint);
-               AssertEquals ("kernel32", attr.Value);
-               AssertEquals (false, attr.ExactSpelling);
-               AssertEquals (true, attr.PreserveSig);
-               AssertEquals (false, attr.SetLastError);
-               AssertEquals (false, attr.BestFitMapping);
-               AssertEquals (false, attr.ThrowOnUnmappableChar);
-       }
+               public static string GenericMethodWithOneArg<T> (T t)
+               {
+                       return t.ToString ();
+               }
 
-       [Test]
-       public void SetCustomAttribute_DllImport2 () {
-               string mname = genMethodName ();
+               [Test]
+               public void ParamerersOfGenericArgumentsAreProperlyEncoded ()
+               {
+                       var type = module.DefineType (
+                               "Bar",
+                               TypeAttributes.Public
+                               | TypeAttributes.Abstract
+                               | TypeAttributes.Sealed,
+                               typeof (object));
 
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       mname, MethodAttributes.Public, typeof (void), 
-                       new Type [] { typeof (int), typeof (string) });
+                       var foo_method = typeof (MethodBuilderTest).GetMethod ("GenericMethodWithOneArg");
 
-               CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] {typeof (DllImportAttribute).GetField ("EntryPoint"), typeof (DllImportAttribute).GetField ("CallingConvention"), typeof (DllImportAttribute).GetField ("CharSet"), typeof (DllImportAttribute).GetField ("ExactSpelling"), typeof (DllImportAttribute).GetField ("PreserveSig")}, new object [] { "bar", CallingConvention.StdCall, CharSet.Unicode, true, false });
-               mb.SetCustomAttribute (cb);
+                       var method = type.DefineMethod (
+                               "ReFoo",
+                               MethodAttributes.Static | MethodAttributes.Public,
+                               typeof (string),
+                               new [] { foo_method.GetGenericArguments () [0] });
+                       method.DefineGenericParameters ("K");
 
-               Type t = tb.CreateType ();
+                       var il = method.GetILGenerator ();
+                       il.Emit (OpCodes.Ldarga, 0);
+                       il.Emit (OpCodes.Constrained, method.GetGenericArguments () [0]);
+                       il.Emit (OpCodes.Callvirt, typeof (object).GetMethod ("ToString"));
+                       il.Emit (OpCodes.Ret);
 
-               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+                       type.CreateType ();
 
-               AssertEquals (CallingConvention.StdCall, attr.CallingConvention);
-               AssertEquals (CharSet.Unicode, attr.CharSet);
-               AssertEquals ("bar", attr.EntryPoint);
-               AssertEquals ("foo", attr.Value);
-               AssertEquals (true, attr.ExactSpelling);
-               AssertEquals (false, attr.PreserveSig);
-               AssertEquals (false, attr.SetLastError);
-               AssertEquals (false, attr.BestFitMapping);
-               AssertEquals (false, attr.ThrowOnUnmappableChar);
-       }
+                       var re_foo_open = module.GetType ("Bar").GetMethod ("ReFoo");
 
-       [Test]
-       public void SetCustomAttribute_DllImport3 () {
-               string mname = genMethodName ();
+                       Assert.AreEqual (re_foo_open.GetGenericArguments ()[0], re_foo_open.GetParameters () [0].ParameterType, "#1");
+               }
 
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       mname, MethodAttributes.Public, typeof (void), 
-                       new Type [] { typeof (int), typeof (string) });
+               [Test] // #628660
+               public void CanCallGetMethodBodyOnDynamicImageMethod ()
+               {
+                       var type = module.DefineType (
+                               "CanCallGetMethodBodyOnDynamicImageMethod",
+                               TypeAttributes.Public,
+                               typeof (object));
 
-               // Test attributes with three values (on/off/missing)
-               CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { false, false });
-               mb.SetCustomAttribute (cb);
+                       var baz = type.DefineMethod ("Foo", MethodAttributes.Public | MethodAttributes.Static, typeof (object), Type.EmptyTypes);
 
-               Type t = tb.CreateType ();
+                       var il = baz.GetILGenerator ();
+                       var temp = il.DeclareLocal (typeof (object));
+                       il.Emit (OpCodes.Ldnull);
+                       il.Emit (OpCodes.Stloc, temp);
+                       il.Emit (OpCodes.Ldloc, temp);
+                       il.Emit (OpCodes.Ret);
 
-               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+                       var body = type.CreateType ().GetMethod ("Foo").GetMethodBody ();
 
-               AssertEquals (false, attr.BestFitMapping);
-               AssertEquals (false, attr.ThrowOnUnmappableChar);
-       }
+                       Assert.IsNotNull (body);
+                       Assert.AreEqual (1, body.LocalVariables.Count);
+                       Assert.AreEqual (typeof (object), body.LocalVariables [0].LocalType);
+               }
+
+
+               [Test] //#384127
+               public void GetGenericArgumentsReturnsNullForNonGenericMethod ()
+               {
+                       var tb = module.DefineType ("Base");
+       
+                       var mb = tb.DefineMethod ("foo", MethodAttributes.Public, typeof (void), Type.EmptyTypes);
+       
+                       Assert.IsNull (mb.GetGenericArguments ());
+
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void SetConstantIllegalType ()
+               {
+                       var tb = module.DefineType ("Base");
+       
+                       var mb = tb.DefineMethod ("foo", MethodAttributes.Public, typeof (void), new Type [] { typeof (decimal) });
+                       ParameterBuilder pb = mb.DefineParameter (1, ParameterAttributes.In, "foo");
+                       pb.SetConstant (5m);
+               }
 
-       [Test]
-       public void SetCustomAttribute_DllImport4 () {
-               string mname = genMethodName ();
+               public interface ITest
+               {
+                       T[] Method<T>(T[] value);
+               }
 
-               TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
-               MethodBuilder mb = tb.DefineMethod (
-                       mname, MethodAttributes.Public, typeof (void), 
-                       new Type [] { typeof (int), typeof (string) });
+               [Test]
+               // #7964
+               public void ArrayOfGenericParam ()
+               {
+                       var tb = module.DefineType ("Base");
 
-               CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("SetLastError"), typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { true, true, true });
-               mb.SetCustomAttribute (cb);
+            tb.AddInterfaceImplementation (typeof (ITest));
 
-               Type t = tb.CreateType ();
+            var testMethod = tb.DefineMethod ("Method", MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis);
 
-               DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
+            var testParameters = Array.ConvertAll (testMethod.DefineGenericParameters("T"), b => (Type)b);
 
-               AssertEquals (true, attr.SetLastError);
-               AssertEquals (true, attr.BestFitMapping);
-               AssertEquals (true, attr.ThrowOnUnmappableChar);
+            var returnType = testParameters[0].MakeArrayType();
+
+            testMethod.SetParameters (testParameters[0].MakeArrayType());
+            testMethod.SetReturnType (returnType);
+
+            var testIl = testMethod.GetILGenerator ();
+                       testIl.Emit (OpCodes.Ldarg_1);
+                       testIl.Emit (OpCodes.Castclass, returnType);
+                       testIl.Emit (OpCodes.Ret);
+
+            var t = tb.CreateType ();
+
+            var test = (ITest) Activator.CreateInstance (t);
+
+                       var o = new int[0];
+            var returnValue = test.Method (o);
+
+                       Assert.AreEqual (o, returnValue);
+               }
        }
-#endif
-}
 }