2007-11-16 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mcs / class / corlib / Test / System / TypeTest.cs
index 13e2bf91948ffa3663e46aaef5feb99543d647c7..f5bcd0dcb99b0f74e91518f4481e5ab6cff93e9d 100644 (file)
 using NUnit.Framework;
 using System;
 using System.Collections;
+#if NET_2_0
+using System.Collections.Generic;
+#endif
 using System.IO;
 using System.Reflection;
+using System.Reflection.Emit;
 using System.Runtime.InteropServices;
+using System.Text;
+using System.Globalization;
 
 class NoNamespaceClass {
 }
 
 namespace MonoTests.System
 {
-       class Super : ICloneable {
-               public virtual object Clone () {
+       class Super : ICloneable
+       {
+               public virtual object Clone ()
+               {
                        return null;
                }
        }
-       class Duper: Super {
+
+       class Duper: Super
+       {
        }
 
-       interface IFace1 {
+       interface IFace1
+       {
                void foo ();
        }
 
-       interface IFace2 : IFace1 {
+       interface IFace2 : IFace1
+       {
                void bar ();
        }
 
-       interface IFace3 : IFace2 {
+       interface IFace3 : IFace2
+       {
        }
 
-       enum TheEnum { A, B, C };
+       enum TheEnum
+       {
+               A,
+               B,
+               C
+       };
 
-       abstract class Base {
+       abstract class Base
+       {
                public int level;
 
-               public abstract int this [byte i] { get; }
-               public abstract int this [int i] { get; }
-               public abstract void TestVoid();
-               public abstract void TestInt(int i);
+               public abstract int this [byte i] {
+                       get;
+               }
+
+               public abstract int this [int i] {
+                       get;
+               }
+
+               public abstract void TestVoid ();
+               public abstract void TestInt (int i);
        }
 
-       class DeriveVTable : Base {
-               public override int this [byte i] { get { return 1; } }
-               public override int this [int i] { get { return 1; } }
-               public override void TestVoid() { level = 1; }
-               public override void TestInt(int i) { level = 1; }
+       class DeriveVTable : Base
+       {
+               public override int this [byte i] {
+                       get { return 1; }
+               }
+
+               public override int this [int i] {
+                       get { return 1; }
+               }
+
+               public override void TestVoid ()
+               {
+                       level = 1;
+               }
+
+               public override void TestInt (int i)
+               {
+                       level = 1;
+               }
        }
 
-       class NewVTable : DeriveVTable {
-               public new int this [byte i] { get { return 2; } }
-               public new int this [int i] { get { return 2; } }
-               public new void TestVoid() { level = 2; }
-               public new void TestInt(int i) { level = 2; }
+       class NewVTable : DeriveVTable
+       {
+               public new int this [byte i] {
+                       get { return 2; }
+               }
 
-               public void Overload () { }
-               public void Overload (int i) { }
+               public new int this [int i] {
+                       get { return 2; }
+               }
 
-               public NewVTable (out int i) {
-                       i = 0;
+               public new void TestVoid ()
+               {
+                       level = 2;
                }
 
-               public void byref_method (out int i) {
+               public new void TestInt (int i)
+               {
+                       level = 2;
+               }
+
+               public void Overload ()
+               {
+               }
+
+               public void Overload (int i)
+               {
+               }
+
+               public NewVTable (out int i)
+               {
                        i = 0;
                }
 
+               public void byref_method (out int i)
+               {
+                       i = 0;
+               }
        }
 
-       class Base1 {
+       class Base1
+       {
                public virtual int Foo {
-                       get {
-                               return 1;
-                       }
-                       set {
-                       }
+                       get { return 1; }
+                       set { }
                }
        }
 
-       class Derived1 : Base1 {
+       class Derived1 : Base1
+       {
                public override int Foo {
-                       set {
-                       }
+                       set { }
+               }
+       }
+
+       class Derived2 : Base1
+       {
+               public new int Foo {
+                       get { return 1; }
+                       set { }
                }
        }
 
 #if NET_2_0
-       public class Foo<T> {
+       public class Foo<T>
+       {
                public T Whatever;
        
                public T Test {
                        get { throw new NotImplementedException (); }
                }
 
-               public T Execute(T a) {
+               public T Execute (T a)
+               {
                        return a;
                }
        }
 
-       public interface IBar<T> { }
-       public class Baz<T> : IBar<T> { }
+       public interface IBar<T>
+       {
+       }
+
+       public class Baz<T> : IBar<T>
+       {
+       }
 #endif
 
        [TestFixture]
        public class TypeTest
        {
-               private void ByrefMethod (ref int i, ref Derived1 j, ref Base1 k) {
+               private AssemblyBuilder assembly;
+               private ModuleBuilder module;
+               const string ASSEMBLY_NAME = "MonoTests.System.TypeTest";
+               static int typeIndexer = 0;
+
+               [SetUp]
+               public void SetUp ()
+               {
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = ASSEMBLY_NAME;
+                       assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (
+                                       assemblyName, AssemblyBuilderAccess.RunAndSave, Path.GetTempPath ());
+                       module = assembly.DefineDynamicModule ("module1");
+               }
+
+               private string genTypeName ()
+               {
+                       return "t" + (typeIndexer++);
                }
 
+               private void ByrefMethod (ref int i, ref Derived1 j, ref Base1 k)
+               {
+               }
+#if NET_2_0
+               private void GenericMethod<Q> (Q q)
+               {
+               }
+#endif
                [Test]
-               public void TestIsAssignableFrom () {
+               public void TestIsAssignableFrom ()
+               {
                        // Simple tests for inheritance
                        Assert.AreEqual (typeof (Super).IsAssignableFrom (typeof (Duper)) , true, "#01");
                        Assert.AreEqual (typeof (Duper).IsAssignableFrom (typeof (Duper)), true, "#02");
@@ -136,11 +234,16 @@ namespace MonoTests.System
                        Assert.AreEqual (typeof (ICloneable[][]).IsAssignableFrom (typeof (Duper[][])), true, "#12");
 
                        // Tests for vectors<->one dimensional arrays */
+#if TARGET_JVM // Lower bounds arrays are not supported for TARGET_JVM.
+                       Array arr1 = Array.CreateInstance (typeof (int), new int[] {1});
+                       Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr1.GetType ()), true, "#13");
+#else
                        Array arr1 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0});
                        Array arr2 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {10});
 
                        Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr1.GetType ()), true, "#13");
                        Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr2.GetType ()), false, "#14");
+#endif // TARGET_JVM
 
                        // Test that arrays of enums can be cast to their base types
                        Assert.AreEqual (typeof (int[]).IsAssignableFrom (typeof (TypeCode[])), true, "#15");
@@ -173,10 +276,18 @@ namespace MonoTests.System
                        MethodInfo mi = typeof (TypeTest).GetMethod ("ByrefMethod", BindingFlags.Instance|BindingFlags.NonPublic);
                        Assert.IsTrue (mi.GetParameters ()[2].ParameterType.IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
                        Assert.IsTrue (mi.GetParameters ()[1].ParameterType.IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
+
+                       // Tests for type parameters
+#if NET_2_0
+                       mi = typeof (TypeTest).GetMethod ("GenericMethod", BindingFlags.Instance|BindingFlags.NonPublic);
+                       Assert.IsTrue (mi.GetParameters ()[0].ParameterType.IsAssignableFrom (mi.GetParameters ()[0].ParameterType));
+                       Assert.IsFalse (mi.GetParameters ()[0].ParameterType.IsAssignableFrom (typeof (int)));
+#endif
                }
 
                [Test]
-               public void TestIsSubclassOf () {
+               public void TestIsSubclassOf ()
+               {
                        Assert.IsTrue (typeof (ICloneable).IsSubclassOf (typeof (object)), "#01");
 
                        // Tests for byref types
@@ -187,7 +298,8 @@ namespace MonoTests.System
                }
 
                [Test]
-               public void TestGetMethodImpl() {
+               public void TestGetMethodImpl ()
+               {
                        // Test binding of new slot methods (using no types)
                        Assert.AreEqual (typeof (Base), typeof (Base).GetMethod("TestVoid").DeclaringType, "#01");
                        Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetMethod ("TestVoid").DeclaringType, "#02");
@@ -206,7 +318,9 @@ namespace MonoTests.System
                }
 
                [Test]
-               public void TestGetPropertyImpl() {
+               [Category ("TargetJvmNotWorking")]
+               public void TestGetPropertyImpl ()
+               {
                        // Test getting property that is exact
                        Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetProperty ("Item", new Type[1] { typeof (Int32) }).DeclaringType, "#01");
 
@@ -217,17 +331,29 @@ namespace MonoTests.System
                        Assert.AreEqual (1, typeof (Derived1).GetProperties ().Length, "#03");
                }
 
+               [Test]
+               public void GetProperties ()
+               {
+                       // Test hide-by-name-and-signature
+                       Assert.AreEqual (1, typeof (Derived2).GetProperties ().Length);
+                       Assert.AreEqual (typeof (Derived2), typeof (Derived2).GetProperties ()[0].DeclaringType);
+               }
+
+#if !TARGET_JVM // StructLayout not supported for TARGET_JVM
                [StructLayout(LayoutKind.Explicit, Pack = 4, Size = 64)]
-               public class Class1 {
+               public class Class1
+               {
                }
 
                [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
-               public class Class2 {
+               public class Class2
+               {
                }
 
 #if NET_2_0
                [Test]
-               public void StructLayoutAttribute () {
+               public void StructLayoutAttribute ()
+               {
                        StructLayoutAttribute attr1 = typeof (TypeTest).StructLayoutAttribute;
                        Assert.AreEqual (LayoutKind.Auto, attr1.Value);
 
@@ -241,13 +367,16 @@ namespace MonoTests.System
                        Assert.AreEqual (CharSet.Unicode, attr3.CharSet);
                }
 #endif
+#endif // TARGET_JVM
 
                [Test]
-               public void Namespace () {
+               public void Namespace ()
+               {
                        Assert.AreEqual (null, typeof (NoNamespaceClass).Namespace);
                }
 
-               public static void Reflected (ref int a) {
+               public static void Reflected (ref int a)
+               {
                }
 
                [Test]
@@ -257,7 +386,8 @@ namespace MonoTests.System
                }
 
                [Test]
-               public void GetInterfaces () {
+               public void GetInterfaces ()
+               {
                        Type[] t = typeof (Duper).GetInterfaces ();
                        Assert.AreEqual (1, t.Length);
                        Assert.AreEqual (typeof (ICloneable), t[0]);
@@ -269,7 +399,8 @@ namespace MonoTests.System
                public int AField;
 
                [Test]
-               public void GetFieldIgnoreCase () {
+               public void GetFieldIgnoreCase ()
+               {
                        Assert.IsNotNull (typeof (TypeTest).GetField ("afield", BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase));
                }
 
@@ -284,22 +415,89 @@ namespace MonoTests.System
                }
 
                [Test]
-               public void GetPropertyAccessorModifiers () {
+               public void GetPropertyAccessorModifiers ()
+               {
                        Assert.IsNotNull (typeof (TypeTest).GetProperty ("Count", BindingFlags.Instance | BindingFlags.Public));
                        Assert.IsNull (typeof (TypeTest).GetProperty ("Count", BindingFlags.Instance | BindingFlags.NonPublic));
                }
 #endif
 
+               [Test]
+               public void IsAbstract ()
+               {
+                       Assert.IsFalse (typeof (string).IsAbstract, "#1");
+                       Assert.IsTrue (typeof (ICloneable).IsAbstract, "#2");
+                       Assert.IsTrue (typeof (ValueType).IsAbstract, "#3");
+                       Assert.IsTrue (typeof (Enum).IsAbstract, "#4");
+                       Assert.IsFalse (typeof (TimeSpan).IsAbstract, "#5");
+                       Assert.IsTrue (typeof (TextReader).IsAbstract, "#6");
+
+#if NET_2_0
+                       // LAMESPEC:
+                       // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=286308
+                       Type [] typeArgs = typeof (List<>).GetGenericArguments ();
+                       Assert.IsFalse (typeArgs [0].IsAbstract, "#7");
+#endif
+               }
+
+               [Test]
+               public void IsCOMObject ()
+               {
+                       Type type = typeof (string);
+                       Assert.IsFalse (type.IsCOMObject, "#1");
+
+                       TypeBuilder tb = module.DefineType (genTypeName ());
+                       type = tb.CreateType ();
+                       Assert.IsFalse (type.IsCOMObject, "#2");
+               }
+
+               [Test]
+               public void IsImport ()
+               {
+                       Type type = typeof (string);
+                       Assert.IsFalse (type.IsImport, "#1");
+
+                       TypeBuilder tb = module.DefineType (genTypeName ());
+                       type = tb.CreateType ();
+                       Assert.IsFalse (type.IsImport, "#2");
+
+                       tb = module.DefineType (genTypeName (), TypeAttributes.Import |
+                               TypeAttributes.Interface | TypeAttributes.Abstract);
+                       type = tb.CreateType ();
+                       Assert.IsTrue (type.IsImport, "#3");
+               }
+
+               [Test]
+               public void IsInterface ()
+               {
+                       Assert.IsFalse (typeof (string).IsInterface, "#1");
+                       Assert.IsTrue (typeof (ICloneable).IsInterface, "#2");
+               }
+
                [Test]
                public void IsPrimitive () {
-                       Assert.IsTrue (typeof (IntPtr).IsPrimitive);
+                       Assert.IsTrue (typeof (IntPtr).IsPrimitive, "#1");
+                       Assert.IsTrue (typeof (int).IsPrimitive, "#2");
+                       Assert.IsFalse (typeof (string).IsPrimitive, "#2");
+               }
+
+               [Test]
+               public void IsValueType ()
+               {
+                       Assert.IsTrue (typeof (int).IsValueType, "#1");
+                       Assert.IsFalse (typeof (Enum).IsValueType, "#2");
+                       Assert.IsFalse (typeof (ValueType).IsValueType, "#3");
+                       Assert.IsTrue (typeof (AttributeTargets).IsValueType, "#4");
+                       Assert.IsFalse (typeof (string).IsValueType, "#5");
+                       Assert.IsTrue (typeof (TimeSpan).IsValueType, "#6");
                }
 
                [Test]
                [Category("NotDotNet")]
                // Depends on the GAC working, which it doesn't durring make distcheck.
                [Category ("NotWorking")]
-               public void GetTypeWithWhitespace () {
+               public void GetTypeWithWhitespace ()
+               {
                        Assert.IsNotNull (Type.GetType
                                                   (@"System.Configuration.NameValueSectionHandler,
                        System,
@@ -310,62 +508,65 @@ PublicKeyToken=b77a5c561934e089"));
                }
                
                [Test]
-               public void ExerciseFilterName() {
+               public void ExerciseFilterName ()
+               {
                        MemberInfo[] mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterName, "*");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterName, "*");
                        Assert.AreEqual (4, mi.Length);
                        mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterName, "Test*");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterName, "Test*");
                        Assert.AreEqual (2, mi.Length);
                        mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterName, "TestVoid");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterName, "TestVoid");
                        Assert.AreEqual (1, mi.Length);
                        mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterName, "NonExistingMethod");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterName, "NonExistingMethod");
                        Assert.AreEqual (0, mi.Length);
                }
                
                [Test]
-               public void ExerciseFilterNameIgnoreCase() {
+               public void ExerciseFilterNameIgnoreCase ()
+               {
                        MemberInfo[] mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterNameIgnoreCase, "*");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterNameIgnoreCase, "*");
                        Assert.AreEqual (4, mi.Length);
                        mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterNameIgnoreCase, "test*");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterNameIgnoreCase, "test*");
                        Assert.AreEqual (2, mi.Length);
                        mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterNameIgnoreCase, "TESTVOID");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterNameIgnoreCase, "TESTVOID");
                        Assert.AreEqual (1, mi.Length);
                        mi = typeof(Base).FindMembers(
                                MemberTypes.Method, 
                                BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
-                           BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                           Type.FilterNameIgnoreCase, "NonExistingMethod");
+                               BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type.FilterNameIgnoreCase, "NonExistingMethod");
                        Assert.AreEqual (0, mi.Length);
                }
 
-               public class ByRef0 {
+               public class ByRef0
+               {
                        public int field;
                        public int property {
                                get { return 0; }
@@ -389,6 +590,19 @@ PublicKeyToken=b77a5c561934e089"));
                        Assert.IsNull (t.GetField ("field"));
                        Assert.IsNull (t.GetProperty ("property"));
                }
+               
+               [Test]
+               public void TestAssemblyQualifiedName ()
+               {
+                       Type t = Type.GetType ("System.Byte[]&");
+                       Assert.IsTrue (t.AssemblyQualifiedName.StartsWith ("System.Byte[]&"));
+                       
+                       t = Type.GetType ("System.Byte*&");
+                       Assert.IsTrue (t.AssemblyQualifiedName.StartsWith ("System.Byte*&"));
+                       
+                       t = Type.GetType ("System.Byte&");
+                       Assert.IsTrue (t.AssemblyQualifiedName.StartsWith ("System.Byte&"));
+               }
 
                struct B
                {
@@ -396,53 +610,310 @@ PublicKeyToken=b77a5c561934e089"));
                }
 
                [Test]
-               public void CreateValueTypeNoCtor () {
+               public void CreateValueTypeNoCtor ()
+               {
                        typeof(B).InvokeMember ("", BindingFlags.CreateInstance, null, null, null);
                }
 
                [Test]
                [ExpectedException (typeof (MissingMethodException))]
-               public void CreateValueTypeNoCtorArgs () {
+               public void CreateValueTypeNoCtorArgs ()
+               {
                        typeof(B).InvokeMember ("", BindingFlags.CreateInstance, null, null, new object [] { 1 });
                }
 
-               class X
+               static string bug336841 (string param1, params string [] param2)
                {
-                       public static int Value;
+                       StringBuilder sb = new StringBuilder ();
+                       sb.Append ("#A:");
+                       sb.Append (param1);
+                       sb.Append ("|");
+                       for (int i = 0; i < param2.Length; i++) {
+                               if (i > 0)
+                                       sb.Append (",");
+                               sb.Append (param2 [i]);
+                       }
+                       return sb.ToString ();
+               }
+
+               static string bug336841 (string param1)
+               {
+                       return "#B:" + param1;
                }
 
-               class Y  : X
+               static string bug336841 (params string [] param1)
                {
+                       StringBuilder sb = new StringBuilder ();
+                       sb.Append ("#C:");
+                       for (int i = 0; i < param1.Length; i++) {
+                               if (i > 0)
+                                       sb.Append (";");
+                               sb.Append (param1 [i]);
+                       }
+                       return sb.ToString ();
                }
 
                [Test]
-               public void InvokeMemberGetSetField () {
-                       typeof (X).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.SetField, null, null, new object [] { 5 });
+               public void InvokeMember_GetSetField ()
+               {
+                       typeof (X).InvokeMember ("Value", BindingFlags.Public |
+                               BindingFlags.Static | BindingFlags.FlattenHierarchy |
+                               BindingFlags.SetField, null, null, new object [] { 5 });
+
+                       Assert.AreEqual (5, X.Value, "#A1");
+                       Assert.AreEqual (5, typeof (X).InvokeMember ("Value",
+                               BindingFlags.Public | BindingFlags.Static |
+                               BindingFlags.FlattenHierarchy | BindingFlags.GetField,
+                               null, null, new object [0]), "#A2");
+                       Assert.AreEqual (5, Y.Value, "#A3");
+                       Assert.AreEqual (5, typeof (Y).InvokeMember ("Value",
+                               BindingFlags.Public | BindingFlags.Static |
+                               BindingFlags.FlattenHierarchy | BindingFlags.GetField,
+                               null, null, new object [0]), "#A4");
+
+                       try {
+                               typeof (X).InvokeMember ("Value", BindingFlags.Public |
+                                       BindingFlags.Static | BindingFlags.FlattenHierarchy |
+                                       BindingFlags.GetField | BindingFlags.SetField,
+                                       null, null, new object [] { 5 });
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentException ex) {
+                               // Cannot specify both Get and Set on a field
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsNotNull (ex.ParamName, "#B5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#B6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#B6");
+#endif
+                       }
+               }
+
+               [Test]
+               public void InvokeMember_GetSetProperty ()
+               {
+                       try {
+                               typeof (ArrayList).InvokeMember ("Item",
+                                       BindingFlags.GetProperty | BindingFlags.SetProperty |
+                                       BindingFlags.Instance | BindingFlags.Public,
+                                       null, new ArrayList (), new object [] { 0, "bar" });
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               // Cannot specify both Get and Set on a property
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#6");
+#endif
+                       }
+               }
 
-                       Assert.AreEqual (5, X.Value);
-                       Assert.AreEqual (5, typeof (X).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.GetField, null, null, new object [0]));
-                       Assert.AreEqual (5, Y.Value);
-                       Assert.AreEqual (5, typeof (Y).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.GetField, null, null, new object [0]));
-               }                       
 
-               class Z {
-                       public Z (IComparable value) {}
+               [Test]
+               public void InvokeMember_InvokeMethod_Set ()
+               {
+                       try {
+                               typeof (ArrayList).InvokeMember ("ToString",
+                                       BindingFlags.InvokeMethod | BindingFlags.SetField |
+                                       BindingFlags.Instance | BindingFlags.Public,
+                                       null, new ArrayList (), new object [0]);
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentException ex) {
+                               // Cannot specify Set on a field and Invoke on a method
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsNotNull (ex.ParamName, "#A5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#A6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#A6");
+#endif
+                       }
+
+                       try {
+                               typeof (ArrayList).InvokeMember ("ToString",
+                                       BindingFlags.InvokeMethod | BindingFlags.SetProperty |
+                                       BindingFlags.Instance | BindingFlags.Public,
+                                       null, new ArrayList (), new object [0]);
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentException ex) {
+                               // Cannot specify Set on a property and Invoke on a method
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsNotNull (ex.ParamName, "#B5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#B6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#B6");
+#endif
+                       }
                }
-       
+
+               [Test]
+               public void InvokeMember_MatchPrimitiveTypeWithInterface ()
+               {
+                       object [] invokeargs = { 1 };
+                       typeof (Z).InvokeMember ("", BindingFlags.DeclaredOnly |
+                               BindingFlags.Public | BindingFlags.NonPublic |
+                               BindingFlags.Instance | BindingFlags.CreateInstance,
+                               null, null, invokeargs);
+               }
+
+               [Test]
+               public void InvokeMember_Name_Null ()
+               {
+                       try {
+                               typeof (X).InvokeMember ((string) null,
+                                       BindingFlags.Public | BindingFlags.Static |
+                                       BindingFlags.FlattenHierarchy | BindingFlags.SetField,
+                                       null, null, new object [] { 5 });
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+                               Assert.AreEqual ("name", ex.ParamName, "#6");
+                       }
+               }
+
                [Test]
-               public void InvokeMemberMatchPrimitiveTypeWithInterface () {
-                       object[] invokeargs = {1};
-                       typeof (Z).InvokeMember( "", 
-                                                                                       BindingFlags.DeclaredOnly |
-                                                                                       BindingFlags.Public |
-                                                                                       BindingFlags.NonPublic |
-                                                                                       BindingFlags.Instance |
-                                                                                       BindingFlags.CreateInstance,
-                                                                                       null, null, invokeargs 
-                                                                                       );
+               public void InvokeMember_NoOperation ()
+               {
+                       try {
+                               typeof (TypeTest).InvokeMember ("Run", BindingFlags.Public |
+                                       BindingFlags.Static, null, null, new object [0]);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               // Must specify binding flags describing the
+                               // invoke operation required
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#6");
+#endif
+                       }
                }
 
-               class TakesInt {
+               [Test] // bug #321735
+               public void InvokeMember_SetFieldProperty ()
+               {
+                       ArrayList list = new ArrayList ();
+                       list.Add ("foo");
+                       list.GetType ().InvokeMember ("Item",
+                               BindingFlags.SetField | BindingFlags.SetProperty |
+                               BindingFlags.Instance | BindingFlags.Public,
+                               null, list, new object [] { 0, "bar" });
+                       Assert.AreEqual ("bar", list [0]);
+               }
+
+               [Test]
+               public void InvokeMember_SetField_ProvidedArgs ()
+               {
+                       try {
+                               typeof (X).InvokeMember ("Value", BindingFlags.Public |
+                                       BindingFlags.Static | BindingFlags.SetField,
+                                       null, null, new object [0]);
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentException ex) {
+                               // Only the field value can be specified to set
+                               // a field value
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsNotNull (ex.ParamName, "#A5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#6");
+#endif
+                       }
+
+                       try {
+                               typeof (X).InvokeMember ("Value", BindingFlags.Public |
+                                       BindingFlags.Static | BindingFlags.SetField,
+                                       null, null, null);
+                               Assert.Fail ("#B1");
+#if NET_2_0
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsNotNull (ex.ParamName, "#B5");
+                               Assert.AreEqual ("providedArgs", ex.ParamName, "#B6");
+                       }
+#else
+                       } catch (ArgumentException ex) {
+                               // Only the field value can be specified to set
+                               // a field value
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsNotNull (ex.ParamName, "#B5");
+#if NET_2_0
+                               Assert.AreEqual ("bindingFlags", ex.ParamName, "#B6");
+#else
+                               Assert.AreEqual ("invokeAttr", ex.ParamName, "#B6");
+#endif
+                       }
+#endif
+               }
+
+               [Test] // bug #336841
+               [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=306797
+               public void InvokeMember_VarArgs ()
+               {
+                       BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Public |
+                               BindingFlags.NonPublic | BindingFlags.OptionalParamBinding |
+                               BindingFlags.Static | BindingFlags.FlattenHierarchy |
+                               BindingFlags.Instance;
+
+                       Type type = typeof (TypeTest);
+                       string result = (string) type.InvokeMember ("bug336841",
+                               flags, null, null, new object [] { "1" });
+                       Assert.IsNotNull (result, "#A1");
+                       Assert.AreEqual ("#B:1", result, "#A2");
+
+                       result = (string) type.InvokeMember ("bug336841", flags,
+                               null, null, new object [] { "1", "2", "3", "4" });
+                       Assert.IsNotNull (result, "#B1");
+                       Assert.AreEqual ("#A:1|2,3,4", result, "#B2");
+               }
+
+               class X
+               {
+                       public static int Value;
+               }
+
+               class Y : X
+               {
+               }
+
+               class Z
+               {
+                       public Z (IComparable value)
+                       {
+                       }
+               }
+       
+               public static void Run ()
+               {
+               }
+
+               class TakesInt
+               {
                        private int i;
 
                        public TakesInt (int x)
@@ -455,12 +926,12 @@ PublicKeyToken=b77a5c561934e089"));
                        }
                }
 
-               class TakesObject {
+               class TakesObject
+               {
                        public TakesObject (object x) {}
                }
 
-               // Filed as bug #75241
-               [Test]
+               [Test] // bug #75241
                public void GetConstructorNullInTypes ()
                {
                        // This ends up calling type.GetConstructor ()
@@ -469,25 +940,330 @@ PublicKeyToken=b77a5c561934e089"));
                }
 
                [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void GetConstructorNullInTypes_Bug71300 ()
+               public void GetConstructor_TakeInt_Object ()
                {
-                       typeof (TakesInt).GetConstructor (new Type[1] { null });
-                       // so null in types isn't valid for GetConstructor!
+                       Assert.IsNull (typeof (TakesInt).GetConstructor (new Type[1] { typeof (object) }));
                }
 
                [Test]
-               public void GetConstructor_TakeInt_Object ()
+               public void GetCustomAttributes_All ()
                {
-                       Assert.IsNull (typeof (TakesInt).GetConstructor (new Type[1] { typeof (object) }));
+                       object [] attrs = typeof (A).GetCustomAttributes (false);
+                       Assert.AreEqual (2, attrs.Length, "#A1");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (FooAttribute)), "#A2");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (VolatileModifier)), "#A3");
+
+                       attrs = typeof (BA).GetCustomAttributes (false);
+                       Assert.AreEqual (1, attrs.Length, "#B1");
+                       Assert.AreEqual (typeof (BarAttribute), attrs [0].GetType (), "#B2");
+
+                       attrs = typeof (BA).GetCustomAttributes (true);
+                       Assert.AreEqual (2, attrs.Length, "#C1");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (BarAttribute)), "#C2");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (VolatileModifier)), "#C3");
+
+                       attrs = typeof (CA).GetCustomAttributes (false);
+                       Assert.AreEqual (0, attrs.Length, "#D");
+
+                       attrs = typeof (CA).GetCustomAttributes (true);
+                       Assert.AreEqual (1, attrs.Length, "#E1");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#E2");
+               }
+
+               static bool HasAttribute (object [] attrs, Type attributeType)
+               {
+                       foreach (object attr in attrs)
+                               if (attr.GetType () == attributeType)
+                                       return true;
+                       return false;
                }
 
-               // bug #76150
                [Test]
+               public void GetCustomAttributes_Type ()
+               {
+                       object [] attrs = null;
+
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (VolatileModifier), false);
+                       Assert.AreEqual (1, attrs.Length, "#A1");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#A2");
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (VolatileModifier), true);
+                       Assert.AreEqual (1, attrs.Length, "#A3");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#A4");
+
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (NemerleAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#B1");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#B2");
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (NemerleAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#B3");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#B4");
+
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (FooAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#C1");
+                       Assert.AreEqual (typeof (FooAttribute), attrs [0].GetType (), "#C2");
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (FooAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#C3");
+                       Assert.AreEqual (typeof (FooAttribute), attrs [0].GetType (), "#C4");
+
+                       attrs = typeof (BA).GetCustomAttributes (
+                               typeof (VolatileModifier), false);
+                       Assert.AreEqual (0, attrs.Length, "#D1");
+                       attrs = typeof (BA).GetCustomAttributes (
+                               typeof (VolatileModifier), true);
+                       Assert.AreEqual (1, attrs.Length, "#D2");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#D3");
+
+                       attrs = typeof (BA).GetCustomAttributes (
+                               typeof (NemerleAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#E1");
+                       attrs = typeof (BA).GetCustomAttributes (
+                               typeof (NemerleAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#E2");
+                       Assert.AreEqual (typeof (VolatileModifier), attrs [0].GetType (), "#E3");
+
+                       attrs = typeof (BA).GetCustomAttributes (
+                               typeof (FooAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#F1");
+                       Assert.AreEqual (typeof (BarAttribute), attrs [0].GetType (), "#F2");
+                       attrs = typeof (BA).GetCustomAttributes (
+                               typeof (FooAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#F3");
+                       Assert.AreEqual (typeof (BarAttribute), attrs [0].GetType (), "#F4");
+
+                       attrs = typeof (bug82431A1).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#G1");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#G2");
+                       attrs = typeof (bug82431A1).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#G3");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#G4");
+
+                       attrs = typeof (bug82431A1).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#H1");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#H2");
+                       attrs = typeof (bug82431A1).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#H3");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#H4");
+
+                       attrs = typeof (bug82431A2).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#I1");
+                       attrs = typeof (bug82431A2).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (0, attrs.Length, "#I2");
+
+                       attrs = typeof (bug82431A2).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#J1");
+                       attrs = typeof (bug82431A2).GetCustomAttributes (
+                               typeof (NotInheritAttribute), true);
+                       Assert.AreEqual (0, attrs.Length, "#J2");
+
+                       attrs = typeof (bug82431A3).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (2, attrs.Length, "#K1");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (InheritAttribute)), "#K2");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (NotInheritAttribute)), "#K3");
+                       attrs = typeof (bug82431A3).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (2, attrs.Length, "#K4");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (InheritAttribute)), "#K5");
+                       Assert.IsTrue (HasAttribute (attrs, typeof (NotInheritAttribute)), "#K6");
+
+                       attrs = typeof (bug82431A3).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#L1");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#L2");
+                       attrs = typeof (bug82431A3).GetCustomAttributes (
+                               typeof (NotInheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#L3");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#L4");
+
+                       attrs = typeof (bug82431B1).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#M1");
+                       Assert.AreEqual (typeof (InheritAttribute), attrs [0].GetType (), "#M2");
+                       attrs = typeof (bug82431B1).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#M3");
+                       Assert.AreEqual (typeof (InheritAttribute), attrs [0].GetType (), "#M4");
+
+                       attrs = typeof (bug82431B1).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#N1");
+                       attrs = typeof (bug82431B1).GetCustomAttributes (
+                               typeof (NotInheritAttribute), true);
+                       Assert.AreEqual (0, attrs.Length, "#N2");
+
+                       attrs = typeof (bug82431B2).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#O1");
+                       attrs = typeof (bug82431B2).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#O2");
+                       Assert.AreEqual (typeof (InheritAttribute), attrs [0].GetType (), "#O3");
+
+                       attrs = typeof (bug82431B2).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#P1");
+                       attrs = typeof (bug82431B2).GetCustomAttributes (
+                               typeof (NotInheritAttribute), true);
+                       Assert.AreEqual (0, attrs.Length, "#P2");
+
+                       attrs = typeof (bug82431B3).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#Q1");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#Q2");
+                       attrs = typeof (bug82431B3).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (2, attrs.Length, "#Q3");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#Q4");
+                       Assert.AreEqual (typeof (InheritAttribute), attrs [1].GetType (), "#Q5");
+
+                       attrs = typeof (bug82431B3).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (1, attrs.Length, "#R1");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#R2");
+                       attrs = typeof (bug82431B3).GetCustomAttributes (
+                               typeof (NotInheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#R3");
+                       Assert.AreEqual (typeof (NotInheritAttribute), attrs [0].GetType (), "#R4");
+
+                       attrs = typeof (bug82431B4).GetCustomAttributes (
+                               typeof (InheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#S1");
+                       attrs = typeof (bug82431B4).GetCustomAttributes (
+                               typeof (InheritAttribute), true);
+                       Assert.AreEqual (1, attrs.Length, "#S2");
+                       Assert.AreEqual (typeof (InheritAttribute), attrs [0].GetType (), "#S3");
+
+                       attrs = typeof (bug82431B4).GetCustomAttributes (
+                               typeof (NotInheritAttribute), false);
+                       Assert.AreEqual (0, attrs.Length, "#T1");
+                       attrs = typeof (bug82431B4).GetCustomAttributes (
+                               typeof (NotInheritAttribute), true);
+                       Assert.AreEqual (0, attrs.Length, "#T2");
+
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (string), false);
+                       Assert.AreEqual (0, attrs.Length, "#U1");
+                       attrs = typeof (A).GetCustomAttributes (
+                               typeof (string), true);
+                       Assert.AreEqual (0, attrs.Length, "#U2");
+               }
+
+               [Test] // bug #76150
                public void IsDefined ()
                {
-                       Assert.IsTrue (typeof (A).IsDefined (typeof (NemerleAttribute), false), "#1");
-                       Assert.IsTrue (typeof (A).IsDefined (typeof (VolatileModifier), false), "#2");
+                       Assert.IsTrue (typeof (A).IsDefined (typeof (NemerleAttribute), false), "#A1");
+                       Assert.IsTrue (typeof (A).IsDefined (typeof (VolatileModifier), false), "#A2");
+                       Assert.IsTrue (typeof (A).IsDefined (typeof (FooAttribute), false), "#A3");
+                       Assert.IsFalse (typeof (A).IsDefined (typeof (BarAttribute), false), "#A4");
+
+                       Assert.IsFalse (typeof (BA).IsDefined (typeof (NemerleAttribute), false), "#B1");
+                       Assert.IsFalse (typeof (BA).IsDefined (typeof (VolatileModifier), false), "#B2");
+                       Assert.IsTrue (typeof (BA).IsDefined (typeof (FooAttribute), false), "#B3");
+                       Assert.IsTrue (typeof (BA).IsDefined (typeof (BarAttribute), false), "#B4");
+                       Assert.IsFalse (typeof (BA).IsDefined (typeof (string), false), "#B5");
+                       Assert.IsFalse (typeof (BA).IsDefined (typeof (int), false), "#B6");
+                       Assert.IsTrue (typeof (BA).IsDefined (typeof (NemerleAttribute), true), "#B7");
+                       Assert.IsTrue (typeof (BA).IsDefined (typeof (VolatileModifier), true), "#B8");
+                       Assert.IsTrue (typeof (BA).IsDefined (typeof (FooAttribute), true), "#B9");
+                       Assert.IsTrue (typeof (BA).IsDefined (typeof (BarAttribute), true), "#B10");
+                       Assert.IsFalse (typeof (BA).IsDefined (typeof (string), true), "#B11");
+                       Assert.IsFalse (typeof (BA).IsDefined (typeof (int), true), "#B12");
+               }
+
+               [Test]
+               public void IsDefined_AttributeType_Null ()
+               {
+                       try {
+                               typeof (BA).IsDefined ((Type) null, false);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+                               Assert.AreEqual ("attributeType", ex.ParamName, "#6");
+                       }
+               }
+
+               [Test] // bug #82431
+#if NET_2_0
+               [Category ("NotWorking")]
+#endif
+               public void IsDefined_Inherited ()
+               {
+                       Assert.IsFalse (typeof (CA).IsDefined (typeof (NemerleAttribute), false), "#C1");
+                       Assert.IsFalse (typeof (CA).IsDefined (typeof (VolatileModifier), false), "#C2");
+                       Assert.IsFalse (typeof (CA).IsDefined (typeof (FooAttribute), false), "#C3");
+                       Assert.IsFalse (typeof (CA).IsDefined (typeof (BarAttribute), false), "#C4");
+                       Assert.IsTrue (typeof (CA).IsDefined (typeof (NemerleAttribute), true), "#C5");
+                       Assert.IsTrue (typeof (CA).IsDefined (typeof (VolatileModifier), true), "#C6");
+                       Assert.IsFalse (typeof (CA).IsDefined (typeof (FooAttribute), true), "#C7");
+                       Assert.IsFalse (typeof (CA).IsDefined (typeof (BarAttribute), true), "#C8");
+
+                       Assert.IsFalse (typeof (BBA).IsDefined (typeof (NemerleAttribute), false), "#D1");
+                       Assert.IsFalse (typeof (BBA).IsDefined (typeof (VolatileModifier), false), "#D2");
+                       Assert.IsFalse (typeof (BBA).IsDefined (typeof (FooAttribute), false), "#D3");
+                       Assert.IsFalse (typeof (BBA).IsDefined (typeof (BarAttribute), false), "#D4");
+                       Assert.IsTrue (typeof (BBA).IsDefined (typeof (NemerleAttribute), true), "#D5");
+                       Assert.IsTrue (typeof (BBA).IsDefined (typeof (VolatileModifier), true), "#D6");
+#if NET_2_0
+                       Assert.IsTrue (typeof (BBA).IsDefined (typeof (FooAttribute), true), "#D7");
+                       Assert.IsTrue (typeof (BBA).IsDefined (typeof (BarAttribute), true), "#D8");
+#else
+                       Assert.IsFalse (typeof (BBA).IsDefined (typeof (FooAttribute), true), "#D7");
+                       Assert.IsFalse (typeof (BBA).IsDefined (typeof (BarAttribute), true), "#D8");
+#endif
+
+                       Assert.IsTrue (typeof (bug82431A1).IsDefined (typeof (InheritAttribute), false), "#E1");
+                       Assert.IsTrue (typeof (bug82431A1).IsDefined (typeof (NotInheritAttribute), false), "#E2");
+                       Assert.IsTrue (typeof (bug82431A1).IsDefined (typeof (InheritAttribute), true), "#E3");
+                       Assert.IsTrue (typeof (bug82431A1).IsDefined (typeof (NotInheritAttribute), true), "#E4");
+
+                       Assert.IsFalse (typeof (bug82431A2).IsDefined (typeof (InheritAttribute), false), "#F1");
+                       Assert.IsFalse (typeof (bug82431A2).IsDefined (typeof (NotInheritAttribute), false), "#F2");
+#if NET_2_0
+                       Assert.IsFalse (typeof (bug82431A2).IsDefined (typeof (InheritAttribute), true), "#F3");
+#else
+                       Assert.IsTrue (typeof (bug82431A2).IsDefined (typeof (InheritAttribute), true), "#F3");
+#endif
+                       Assert.IsFalse (typeof (bug82431A2).IsDefined (typeof (NotInheritAttribute), true), "#F4");
+
+                       Assert.IsTrue (typeof (bug82431A3).IsDefined (typeof (InheritAttribute), false), "#G1");
+                       Assert.IsTrue (typeof (bug82431A3).IsDefined (typeof (NotInheritAttribute), false), "#G2");
+                       Assert.IsTrue (typeof (bug82431A3).IsDefined (typeof (InheritAttribute), true), "#G3");
+                       Assert.IsTrue (typeof (bug82431A3).IsDefined (typeof (NotInheritAttribute), true), "#G4");
+
+                       Assert.IsTrue (typeof (bug82431B1).IsDefined (typeof (InheritAttribute), false), "#H1");
+                       Assert.IsFalse (typeof (bug82431B1).IsDefined (typeof (NotInheritAttribute), false), "#H2");
+                       Assert.IsTrue (typeof (bug82431B1).IsDefined (typeof (InheritAttribute), true), "#H3");
+                       Assert.IsFalse (typeof (bug82431B1).IsDefined (typeof (NotInheritAttribute), true), "#H4");
+
+                       Assert.IsFalse (typeof (bug82431B2).IsDefined (typeof (InheritAttribute), false), "#I1");
+                       Assert.IsFalse (typeof (bug82431B2).IsDefined (typeof (NotInheritAttribute), false), "#I2");
+                       Assert.IsTrue (typeof (bug82431B2).IsDefined (typeof (InheritAttribute), true), "#I3");
+                       Assert.IsFalse (typeof (bug82431B2).IsDefined (typeof (NotInheritAttribute), true), "#I4");
+
+                       Assert.IsTrue (typeof (bug82431B3).IsDefined (typeof (InheritAttribute), false), "#J1");
+                       Assert.IsTrue (typeof (bug82431B3).IsDefined (typeof (NotInheritAttribute), false), "#J2");
+                       Assert.IsTrue (typeof (bug82431B3).IsDefined (typeof (InheritAttribute), true), "#J3");
+                       Assert.IsTrue (typeof (bug82431B3).IsDefined (typeof (NotInheritAttribute), true), "#J4");
+
+                       Assert.IsFalse (typeof (bug82431B4).IsDefined (typeof (InheritAttribute), false), "#K2");
+                       Assert.IsFalse (typeof (bug82431B4).IsDefined (typeof (NotInheritAttribute), false), "#K2");
+                       Assert.IsTrue (typeof (bug82431B4).IsDefined (typeof (InheritAttribute), true), "#K3");
+                       Assert.IsFalse (typeof (bug82431B4).IsDefined (typeof (NotInheritAttribute), true), "#K4");
                }
 
                [Test]
@@ -513,32 +1289,82 @@ PublicKeyToken=b77a5c561934e089"));
                        Assert.AreEqual (TypeCode.UInt64, Type.GetTypeCode (typeof (ulong)), "#18");
                }
 
-               [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void GetConstructor1a_Bug71300 ()
+               [Test] // GetConstructor (Type [])
+               public void GetConstructor1_Types_Null ()
                {
-                       typeof (BindingFlags).GetConstructor (null);
+                       try {
+                               typeof (BindingFlags).GetConstructor (null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+                               Assert.AreEqual ("types", ex.ParamName, "#6");
+                       }
                }
 
-               [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void GetConstructor1b_Bug71300 ()
+               [Test] // GetConstructor (Type [])
+               public void GetConstructor1_Types_ItemNull ()
                {
-                       typeof (BindingFlags).GetConstructor (new Type[1] { null });
+                       Type type = typeof (BindingFlags);
+                       try {
+                               type.GetConstructor (new Type[1] { 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.IsNotNull (ex.ParamName, "#A5");
+                               Assert.AreEqual ("types", ex.ParamName, "#A6");
+                       }
+
+                       type = typeof (TakesInt);
+                       try {
+                               type.GetConstructor (new Type [1] { null });
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsNotNull (ex.ParamName, "#B5");
+                               Assert.AreEqual ("types", ex.ParamName, "#B6");
+                       }
                }
 
-               [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void GetConstructor4_Bug71300 ()
+               [Test] // GetConstructor (BindingFlags, Binder, Type [], ParameterModifier [])
+               public void GetConstructor2_Types_ItemNull ()
                {
-                       typeof (BindingFlags).GetConstructor (BindingFlags.Default, null, new Type[1] { null }, null);
+                       Type type = typeof (BindingFlags);
+                       try {
+                               type.GetConstructor (BindingFlags.Default, null,
+                                       new Type[1] { null }, null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+                               Assert.AreEqual ("types", ex.ParamName, "#6");
+                       }
                }
 
-               [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void GetConstructor5_Bug71300 ()
+               [Test] // GetConstructor (BindingFlags, Binder, CallingConventions, Type [], ParameterModifier [])
+               public void GetConstructor3_Types_ItemNull ()
                {
-                       typeof (BindingFlags).GetConstructor (BindingFlags.Default, null, CallingConventions.Any, new Type[1] { null }, null);
+                       Type type = typeof (BindingFlags);
+                       try {
+                               type.GetConstructor (BindingFlags.Default,
+                                       null, CallingConventions.Any,
+                                       new Type[1] { null }, null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+                               Assert.AreEqual ("types", ex.ParamName, "#6");
+                       }
                }
 
                [Test]
@@ -548,6 +1374,40 @@ PublicKeyToken=b77a5c561934e089"));
                        Assert.IsNull (i);
                }
 
+#if !TARGET_JVM // Reflection.Emit is not supported for TARGET_JVM
+               [Test]
+               public void EqualsUnderlyingType ()
+               {
+                       AssemblyBuilderAccess access = AssemblyBuilderAccess.RunAndSave;
+                       TypeAttributes attribs = TypeAttributes.Public;
+
+                       AssemblyName name = new AssemblyName ();
+                       name.Name = "enumtest";
+                       AssemblyBuilder assembly = 
+                               AppDomain.CurrentDomain.DefineDynamicAssembly (
+                                       name, access);
+
+                       ModuleBuilder module = assembly.DefineDynamicModule 
+                               ("m", "enumtest.dll");
+                       EnumBuilder e = module.DefineEnum ("E", attribs, typeof (int));
+
+                       Assert.IsTrue (typeof (int).Equals (e));
+               }
+#endif // TARGET_JVM
+
+               [Test]
+               public void Equals_Type_Null ()
+               {
+                       Assert.IsFalse (typeof (int).Equals ((Type) null), "#1");
+                       Assert.IsFalse (typeof (int).Equals ((object) null), "#2");
+               }
+
+               [Test]
+               public void GetElementType_Bug63841 ()
+               {
+                       Assert.IsNull (typeof (TheEnum).GetElementType (), "#1");
+               }
+
 #if NET_2_0
                [Test]
                public void FullNameGenerics ()
@@ -641,21 +1501,6 @@ PublicKeyToken=b77a5c561934e089"));
                        Assert.IsNull (byref_type_param.DeclaringType);
                }
 
-               [Test]
-               [Category ("NotWorking")] // BindingFlags.SetField throws since args.Length != 1, even though we have SetProperty
-               public void Bug79023 ()
-               {
-                       ArrayList list = new ArrayList();
-                       list.Add("foo");
-
-                       // The next line used to throw because we had SetProperty
-                       list.GetType().InvokeMember("Item",
-                                                   BindingFlags.SetField|BindingFlags.SetProperty|
-                                                   BindingFlags.Instance|BindingFlags.Public,
-                                                   null, list, new object[] { 0, "bar" });
-                       Assert.AreEqual ("bar", list[0]);
-               }
-               
                [ComVisible (true)]
                public class ComFoo<T> {
                }
@@ -690,18 +1535,194 @@ PublicKeyToken=b77a5c561934e089"));
                        CheckGenericByRef (typeof (ByRef3<>));
                        CheckGenericByRef (typeof (ByRef4));
                }
+
+               public class Bug80242<T> {
+                       public interface IFoo { }
+                       public class Bar : IFoo { }
+                       public class Baz : Bar { }
+               }
+
+               [Test]
+               public void TestNestedTypes ()
+               {
+                       Type t = typeof (Bug80242<object>);
+                       Assert.IsFalse (t.IsGenericTypeDefinition);
+                       foreach (Type u in t.GetNestedTypes ()) {
+                               Assert.IsTrue (u.IsGenericTypeDefinition, "{0} isn't a generic definition", u);
+                               Assert.AreEqual (u, u.GetGenericArguments () [0].DeclaringType);
+                       }
+               }
+
+               [Test] // bug #82211
+               public void GetMembers_GenericArgument ()
+               {
+                       Type argType = typeof (ComFoo<>).GetGenericArguments () [0];
+                       MemberInfo [] members = argType.GetMembers ();
+                       Assert.IsNotNull (members, "#1");
+                       Assert.AreEqual (4, members.Length, "#2");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void ReflectionOnlyGetTypeNullTypeName ()
+               {
+                       Type.ReflectionOnlyGetType (null, false, false);
+               }
+
+               [Test]
+               public void ReflectionOnlyGetTypeDoNotThrow ()
+               {
+                       Assert.IsNull (Type.ReflectionOnlyGetType ("a, nonexistent.dll", false, false));
+               }
+
+               [Test]
+               [ExpectedException (typeof (FileNotFoundException))]
+               public void ReflectionOnlyGetTypeThrow ()
+               {
+                       Type.ReflectionOnlyGetType ("a, nonexistent.dll", true, false);
+               }
+
+               [Test]
+               public void ReflectionOnlyGetType ()
+               {
+                       Type t = Type.ReflectionOnlyGetType (typeof (int).AssemblyQualifiedName.ToString (), true, true);
+                       Assert.AreEqual ("System.Int32", t.FullName);
+               }
+
+               [Test] //bug #331199
+               //FIXME: 2.0 SP 1 has a diferent behavior
+               public void MakeGenericType_UserDefinedType ()
+               {
+                       Type ut = new UserType (typeof (int));
+                       Type t = typeof (Foo<>).MakeGenericType (ut);
+                       Assert.IsTrue (t.IsGenericType, "#A1");
+                       Assert.AreEqual (1, t.GetGenericArguments ().Length, "#A2");
+
+                       Type arg = t.GetGenericArguments () [0];
+                       Assert.IsNotNull (arg, "#B1");
+                       Assert.IsFalse (arg.IsGenericType, "#B2");
+                       Assert.AreEqual (typeof (int), arg, "#B3");
+               }
+
+               [Category ("NotWorking")]
+               //We dont support instantiating a user type 
+               public void MakeGenericType_NestedUserDefinedType ()
+               {
+                       Type ut = new UserType (new UserType (typeof (int)));
+                       Type t = typeof (Foo<>).MakeGenericType (ut);
+                       Assert.IsTrue (t.IsGenericType, "#A1");
+                       Assert.AreEqual (1, t.GetGenericArguments ().Length, "#A2");
+
+                       Type arg = t.GetGenericArguments () [0];
+                       Assert.IsNotNull (arg, "#B1");
+                       Assert.IsFalse (arg.IsGenericType, "#B2");
+                       Assert.AreEqual (ut, arg, "#B3");
+               }
+               
+               [Test]
+               [Category ("NotWorking")]
+               public void TestMakeGenericType_UserDefinedType_DotNet20SP1 () 
+               {
+                       Type ut = new UserType(typeof(int));
+                       Type t = typeof(Foo<>).MakeGenericType(ut);
+                       Assert.IsTrue (t.IsGenericType, "#1");
+
+                       Assert.AreEqual (ut, t.GetGenericArguments()[0], "#2");
+               }
+               
+               [Test]
+               public void MakeGenericType_BadUserType ()
+               {
+                       Type ut = new UserType (null);
+                       try {
+                               Type t = typeof (Foo<>).MakeGenericType (ut);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException) {
+                       }
+               }
 #endif
 
                public class NemerleAttribute : Attribute
-               { }
+               {
+               }
 
                public class VolatileModifier : NemerleAttribute
-               { }
+               {
+               }
 
                [VolatileModifier]
-               class A { }
+               [FooAttribute]
+               class A
+               {
+               }
+
+               [AttributeUsage (AttributeTargets.Class, Inherited=false)]
+               public class FooAttribute : Attribute
+               {
+               }
+
+               public class BarAttribute : FooAttribute
+               {
+               }
+
+               [BarAttribute]
+               class BA : A
+               {
+               }
+
+               class BBA : BA
+               {
+               }
+
+               class CA : A
+               {
+               }
+
+               [AttributeUsage (AttributeTargets.Class, Inherited=true)]
+               public class InheritAttribute : Attribute
+               {
+               }
+
+               [AttributeUsage (AttributeTargets.Class, Inherited=false)]
+               public class NotInheritAttribute : InheritAttribute
+               {
+               }
+
+               [NotInheritAttribute]
+               public class bug82431A1
+               {
+               }
+
+               public class bug82431A2 : bug82431A1
+               {
+               }
+
+               [NotInheritAttribute]
+               [InheritAttribute]
+               public class bug82431A3 : bug82431A1
+               {
+               }
+
+               [InheritAttribute]
+               public class bug82431B1
+               {
+               }
 
-               struct FooStruct {
+               public class bug82431B2 : bug82431B1
+               {
+               }
+
+               [NotInheritAttribute]
+               public class bug82431B3 : bug82431B2
+               {
+               }
+
+               public class bug82431B4 : bug82431B3
+               {
+               }
+
+               struct FooStruct
+               {
                }
 
                public class Bug77367
@@ -710,6 +1731,185 @@ PublicKeyToken=b77a5c561934e089"));
                        {
                        }
                }
+       }
 
+#if NET_2_0
+       class UserType : Type
+       {
+               private Type type;
+       
+               public UserType(Type type) {
+                       this.type = type;
+               }
+       
+               public override Type UnderlyingSystemType { get { return this.type; } }
+       
+               public override Assembly Assembly { get { return this.type.Assembly; } }
+       
+               public override string AssemblyQualifiedName { get { return null; } }
+       
+               public override Type BaseType { get { return null; } }
+       
+               public override Module Module { get { return this.type.Module; } }
+       
+               public override string Namespace { get { return null; } }
+       
+               public override bool IsGenericParameter { get { return true; } }
+        
+               public override RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } }
+       
+               public override bool ContainsGenericParameters { get { return true; } }
+       
+               public override string FullName { get { return this.type.Name; } }
+       
+               public override Guid GUID { get { throw new NotSupportedException(); } }
+       
+       
+               protected override bool IsArrayImpl() {
+                       return false;
+               }
+       
+               protected override bool IsByRefImpl()
+               {
+                       return false;
+               }
+       
+               protected override bool IsCOMObjectImpl()
+               {
+                       return false;
+               }
+       
+               protected override bool IsPointerImpl()
+               {
+                       return false;
+               }
+       
+               protected override bool IsPrimitiveImpl()
+               {
+                       return false;
+               }
+       
+       
+               protected override TypeAttributes GetAttributeFlagsImpl()
+               {
+                       return 0;
+               }
+       
+               protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder,
+                                                                          CallingConventions callConvention, Type[] types,
+                                                                          ParameterModifier[] modifiers)
+               {
+                       return null;
+               }
+       
+               public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+               public override Type GetElementType()
+               {
+                       return null;
+               }
+       
+               public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+       
+               public override FieldInfo GetField(string name, BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+       
+               public override Type GetInterface(string name, bool ignoreCase)
+               {
+                       return null;
+               }
+       
+               public override Type[] GetInterfaces()
+               {
+                       return null;
+               }
+       
+               public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+               public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+               {
+                       return null;
+               }
+       
+               public override object[] GetCustomAttributes(bool inherit)
+               {
+                       return null;
+               }
+       
+               public override bool IsDefined(Type attributeType, bool inherit)
+               {
+                       return false;
+               }
+       
+               public override string Name { get { return this.type.Name; } }
+       
+               public override EventInfo[] GetEvents(BindingFlags bindingAttr)
+               {
+                       throw new NotImplementedException();
+               }
+       
+               public override FieldInfo[] GetFields(BindingFlags bindingAttr)
+               {
+                       throw new NotImplementedException();
+               }
+       
+               protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder,
+                                                                CallingConventions callConvention, Type[] types,
+                                                                ParameterModifier[] modifiers)
+               {
+                       return null;
+               }
+       
+               public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+               public override Type GetNestedType(string name, BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+               public override Type[] GetNestedTypes(BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+               public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
+               {
+                       return null;
+               }
+       
+               protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder,
+                                                                Type returnType, Type[] types, ParameterModifier[] modifiers)
+               {
+                       return null;
+               }
+       
+               protected override bool HasElementTypeImpl()
+               {
+                       return false;
+               }
+       
+               public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target,
+                                                        object[] args, ParameterModifier[] modifiers, CultureInfo culture,
+                                                        string[] namedParameters)
+               {
+                       throw new NotSupportedException();
+               }
        }
+#endif
 }