Tue Nov 14 16:06:37 CET 2006 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / mcs / typemanager.cs
index c133019859293d00589d28533f3a350dd46a8561..308faf58212b6d1db024b322a0a3047d32450a89 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author: Miguel de Icaza (miguel@gnu.org)
 //         Ravi Pratap     (ravi@ximian.com)
+//         Marek Safar     (marek.safar@seznam.cz)
 //
 // Licensed under the terms of the GNU GPL
 //
@@ -30,7 +31,7 @@ using System.Diagnostics;
 
 namespace Mono.CSharp {
 
-public class TypeManager {
+public partial class TypeManager {
        //
        // A list of core types that the compiler requires or uses
        //
@@ -69,7 +70,9 @@ public class TypeManager {
        static public Type iasyncresult_type;
        static public Type asynccallback_type;
        static public Type intptr_type;
+       static public Type uintptr_type;
        static public Type monitor_type;
+       static public Type interlocked_type;
        static public Type runtime_field_handle_type;
        static public Type runtime_argument_handle_type;
        static public Type attribute_type;
@@ -89,6 +92,8 @@ public class TypeManager {
        static public Type conditional_attribute_type;
        static public Type in_attribute_type;
        static public Type out_attribute_type;
+       static public Type default_parameter_value_attribute_type;
+
        static public Type anonymous_method_type;
        static public Type cls_compliant_attribute_type;
        static public Type typed_reference_type;
@@ -100,23 +105,21 @@ public class TypeManager {
        static public Type required_attr_type;
        static public Type guid_attr_type;
        static public Type assembly_culture_attribute_type;
+       static public Type coclass_attr_type;
+       static public Type comimport_attr_type;
 
        /// 
        /// .NET 2.0
        ///
 #if NET_2_0
+       static internal Type runtime_compatibility_attr_type;
        static internal Type compiler_generated_attr_type;
        static internal Type fixed_buffer_attr_type;
        static internal Type default_charset_type;
+       static internal Type internals_visible_attr_type;
+       static internal Type type_forwarder_attr_type;
 #endif
 
-       //
-       // An empty array of types
-       //
-       static public Type [] NoTypes;
-       static public TypeExpr [] NoTypeExprs;
-
-
        // 
        // Expressions representing the internal types.  Used during declaration
        // definition.
@@ -185,13 +188,14 @@ public class TypeManager {
        static public MethodInfo int_array_get_lower_bound_int;
        static public MethodInfo int_array_get_upper_bound_int;
        static public MethodInfo void_array_copyto_array_int;
+       static public MethodInfo int_interlocked_compare_exchange;
        static public PropertyInfo ienumerator_getcurrent;
        
        //
        // The attribute constructors.
        //
        static public ConstructorInfo object_ctor;
-       static public ConstructorInfo cons_param_array_attribute;
+       static private ConstructorInfo cons_param_array_attribute;
        static public ConstructorInfo void_decimal_ctor_five_args;
        static public ConstructorInfo void_decimal_ctor_int_arg;
        static public ConstructorInfo unverifiable_code_ctor;
@@ -208,19 +212,6 @@ public class TypeManager {
        static internal ConstructorInfo fixed_buffer_attr_ctor;
 #endif
 
-       // <remarks>
-       //   Holds the Array of Assemblies that have been loaded
-       //   (either because it is the default or the user used the
-       //   -r command line option)
-       // </remarks>
-       static Assembly [] assemblies;
-
-       // <remarks>
-       //  Keeps a list of modules. We used this to do lookups
-       //  on the module using GetType -- needed for arrays
-       // </remarks>
-       static Module [] modules;
-
        static PtrHashtable builder_to_declspace;
 
        static PtrHashtable builder_to_member_cache;
@@ -231,12 +222,6 @@ public class TypeManager {
        // </remarks>
        static PtrHashtable builder_to_ifaces;
 
-       // <remarks>
-       //   Maps MethodBase.RuntimeTypeHandle to a Type array that contains
-       //   the arguments to the method
-       // </remarks>
-       static Hashtable method_arguments;
-
        // <remarks>
        //   Maps PropertyBuilder to a Type array that contains
        //   the arguments to the indexer
@@ -266,7 +251,13 @@ public class TypeManager {
        public static Hashtable AllClsTopLevelTypes;
 
        static Hashtable fieldbuilders_to_fields;
+       static Hashtable propertybuilder_to_property;
        static Hashtable fields;
+       static Hashtable events;
+
+#if GMCS_SOURCE
+       static PtrHashtable assembly_internals_vis_attrs;
+#endif
 
        struct Signature {
                public string name;
@@ -276,12 +267,10 @@ public class TypeManager {
        public static void CleanUp ()
        {
                // Lets get everything clean so that we can collect before generating code
-               assemblies = null;
-               modules = null;
                builder_to_declspace = null;
                builder_to_member_cache = null;
                builder_to_ifaces = null;
-               method_arguments = null;
+               builder_to_type_param = null;
                indexer_arguments = null;
                method_params = null;
                builder_to_method = null;
@@ -291,7 +280,12 @@ public class TypeManager {
                events = null;
                priv_fields_events = null;
                type_hash = null;
-               
+               propertybuilder_to_property = null;
+
+#if GMCS_SOURCE
+               assembly_internals_vis_attrs = null;
+#endif
+
                TypeHandle.CleanUp ();
        }
 
@@ -305,14 +299,14 @@ public class TypeManager {
 
                if (!(mi is MethodBase))
                        return false;
-               
+
                if (mi.Name != sig.name)
                        return false;
 
                int count = sig.args.Length;
                
                if (mi is MethodBuilder || mi is ConstructorBuilder){
-                       Type [] candidate_args = GetArgumentTypes ((MethodBase) mi);
+                       Type [] candidate_args = GetParameterData ((MethodBase) mi).Types;
 
                        if (candidate_args.Length != count)
                                return false;
@@ -376,27 +370,29 @@ public class TypeManager {
 
        static public void Reset ()
        {
-               assemblies = new Assembly [0];
-               modules = null;
-               
                builder_to_declspace = new PtrHashtable ();
                builder_to_member_cache = new PtrHashtable ();
                builder_to_method = new PtrHashtable ();
-               method_arguments = new PtrHashtable ();
+               builder_to_type_param = new PtrHashtable ();
                method_params = new PtrHashtable ();
                method_overrides = new PtrHashtable ();
                indexer_arguments = new PtrHashtable ();
                builder_to_ifaces = new PtrHashtable ();
                
-               NoTypes = new Type [0];
-               NoTypeExprs = new TypeExpr [0];
-
                fieldbuilders_to_fields = new Hashtable ();
+               propertybuilder_to_property = new Hashtable ();
                fields = new Hashtable ();
                type_hash = new DoubleHash ();
+
+#if GMCS_SOURCE
+               assembly_internals_vis_attrs = new PtrHashtable ();
+#endif
+
+               // to uncover regressions
+               cons_param_array_attribute = null;
        }
 
-       public static void AddUserType (string name, DeclSpace ds)
+       public static void AddUserType (DeclSpace ds)
        {
                builder_to_declspace.Add (ds.TypeBuilder, ds);
        }
@@ -413,6 +409,7 @@ public class TypeManager {
        public static void AddMethod (MethodBase builder, IMethodData method)
        {
                builder_to_method.Add (builder, method);
+               method_params.Add (builder, method.ParameterInfo);
        }
 
        public static IMethodData GetMethod (MethodBase builder)
@@ -440,18 +437,32 @@ public class TypeManager {
 
        public static MemberCache LookupMemberCache (Type t)
        {
+#if GMCS_SOURCE && MS_COMPATIBLE
+        if (t.IsGenericType && !t.IsGenericTypeDefinition)
+            t = t.GetGenericTypeDefinition ();
+#endif
+
                if (t is TypeBuilder) {
                        IMemberContainer container = builder_to_declspace [t] as IMemberContainer;
                        if (container != null)
                                return container.MemberCache;
                }
 
+#if GMCS_SOURCE
+               if (t is GenericTypeParameterBuilder) {
+                       IMemberContainer container = builder_to_type_param [t] as IMemberContainer;
+
+                       if (container != null)
+                               return container.MemberCache;
+               }
+#endif
+
                return TypeHandle.GetMemberCache (t);
        }
 
        public static MemberCache LookupBaseInterfacesCache (Type t)
        {
-               Type [] ifaces = t.GetInterfaces ();
+               Type [] ifaces = GetInterfaces (t);
 
                if (ifaces != null && ifaces.Length == 1)
                        return LookupMemberCache (ifaces [0]);
@@ -484,50 +495,6 @@ public class TypeManager {
        {
                return (Class) builder_to_declspace [t];
        }
-       
-       /// <summary>
-       ///   Registers an assembly to load types from.
-       /// </summary>
-       public static void AddAssembly (Assembly a)
-       {
-               foreach (Assembly assembly in assemblies) {
-                       if (a == assembly)
-                               return;
-               }
-
-               int top = assemblies.Length;
-               Assembly [] n = new Assembly [top + 1];
-
-               assemblies.CopyTo (n, 0);
-               
-               n [top] = a;
-               assemblies = n;
-       }
-
-        public static Assembly [] GetAssemblies ()
-        {
-                return assemblies;
-        }
-
-       /// <summary>
-       ///  Registers a module builder to lookup types from
-       /// </summary>
-       public static void AddModule (Module mb)
-       {
-               int top = modules != null ? modules.Length : 0;
-               Module [] n = new Module [top + 1];
-
-               if (modules != null)
-                       modules.CopyTo (n, 0);
-               n [top] = mb;
-               modules = n;
-       }
-
-       public static Module[] Modules {
-               get {
-                       return modules;
-               }
-       }
 
        //
        // We use this hash for multiple kinds of constructed types:
@@ -546,7 +513,11 @@ public class TypeManager {
        //
        public static Type GetReferenceType (Type t)
        {
+#if GMCS_SOURCE
+               return t.MakeByRefType ();
+#else
                return GetConstructedType (t, "&");
+#endif
        }
 
        //
@@ -560,128 +531,67 @@ public class TypeManager {
        public static Type GetConstructedType (Type t, string dim)
        {
                object ret = null;
-               if (!type_hash.Lookup (t, dim, out ret)) {
-                       ret = t.Module.GetType (t.ToString () + dim);
+               if (type_hash.Lookup (t, dim, out ret))
+                       return (Type) ret;
+
+               ret = t.Module.GetType (t.ToString () + dim);
+               if (ret != null) {
                        type_hash.Insert (t, dim, ret);
+                       return (Type) ret;
                }
-               return (Type) ret;
-       }
 
-       public static Type GetNestedType (Type t, string name)
-       {
-               object ret = null;
-               if (!type_hash.Lookup (t, name, out ret)) {
-                       ret = t.GetNestedType (name,
-                              BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
-                       type_hash.Insert (t, name, ret);
+               if (dim == "&") {
+                       ret = GetReferenceType (t);
+                       type_hash.Insert (t, dim, ret);
+                       return (Type) ret;
                }
-               return (Type) ret;
-       }
 
-       public static Type LookupTypeReflection (string name, Location loc)
-       {
-               Type found_type = null;
+#if GMCS_SOURCE
+               if (t.IsGenericParameter || t.IsGenericType) {
+                       int pos = 0;
+                       Type result = t;
+                       while ((pos < dim.Length) && (dim [pos] == '[')) {
+                               pos++;
 
-               foreach (Assembly a in assemblies) {
-                       Type t = a.GetType (name);
-                       if (t == null)
-                               continue;
+                               if (dim [pos] == ']') {
+                                       result = result.MakeArrayType ();
+                                       pos++;
 
-                       if (t.IsPointer)
-                               throw new InternalErrorException ("Use GetPointerType() to get a pointer");
+                                       if (pos < dim.Length)
+                                               continue;
 
-                       TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
-                       if (ta != TypeAttributes.NotPublic && ta != TypeAttributes.NestedPrivate &&
-                               ta != TypeAttributes.NestedAssembly && ta != TypeAttributes.NestedFamANDAssem) {
-                               if (found_type == null) {
-                                       found_type = t;
-                                       continue;
+                                       type_hash.Insert (t, dim, result);
+                                       return result;
                                }
 
-                               Report.SymbolRelatedToPreviousError (found_type);
-                               Report.SymbolRelatedToPreviousError (t);
-                               Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name);
-                               return found_type;
-                       }
-               }
+                               int rank = 0;
+                               while (dim [pos] == ',') {
+                                       pos++; rank++;
+                               }
 
-               foreach (Module mb in modules) {
-                       Type t = mb.GetType (name);
-                       if (t == null)
-                               continue;
-                       
-                       if (found_type == null) {
-                               found_type = t;
-                               continue;
-                       }
+                               if ((dim [pos] != ']') || (pos != dim.Length-1))
+                                       break;
 
-                       Report.SymbolRelatedToPreviousError (t);
-                       Report.SymbolRelatedToPreviousError (found_type);
-                       Report.Warning (436, 2, loc, "Ignoring imported type `{0}' since the current assembly already has a declaration with the same name",
-                               TypeManager.CSharpName (t));
-                       return t;
+                               result = result.MakeArrayType (rank + 1);
+                               type_hash.Insert (t, dim, result);
+                               return result;
+                       }
                }
+#endif
 
-               return found_type;
+               type_hash.Insert (t, dim, null);
+               return null;
        }
 
-       /// <summary>
-       ///   Computes the namespaces that we import from the assemblies we reference.
-       /// </summary>
-       public static void ComputeNamespaces ()
+       public static Type GetNestedType (Type t, string name)
        {
-               MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic);
-
-               Hashtable cache = null;
-
-               //
-               // First add the assembly namespaces
-               //
-               if (assembly_get_namespaces != null){
-                       int count = assemblies.Length;
-
-                       for (int i = 0; i < count; i++){
-                               Assembly a = assemblies [i];
-                               string [] namespaces = (string []) assembly_get_namespaces.Invoke (a, null);
-                               foreach (string ns in namespaces){
-                                       if (ns.Length == 0)
-                                               continue;
-                                       Namespace.LookupNamespace (ns, true);
-                               }
-                       }
-               } else {
-                       cache = new Hashtable ();
-                       cache.Add ("", null);
-                       foreach (Assembly a in assemblies) {
-                               foreach (Type t in a.GetExportedTypes ()) {
-                                       string ns = t.Namespace;
-                                       if (ns == null || cache.Contains (ns))
-                                               continue;
-
-                                       Namespace.LookupNamespace (ns, true);
-                                       cache.Add (ns, null);
-                               }
-                       }
-               }
-
-               //
-               // Then add module namespaces
-               //
-               foreach (Module m in modules) {
-                       if (m == CodeGen.Module.Builder)
-                               continue;
-                       if (cache == null) {
-                               cache = new Hashtable ();
-                               cache.Add ("", null);
-                       }
-                       foreach (Type t in m.GetTypes ()) {
-                               string ns = t.Namespace;
-                               if (ns == null || cache.Contains (ns))
-                                       continue;
-                               Namespace.LookupNamespace (ns, true);
-                               cache.Add (ns, null);
-                       }
+               object ret = null;
+               if (!type_hash.Lookup (t, name, out ret)) {
+                       ret = t.GetNestedType (name,
+                              BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
+                       type_hash.Insert (t, name, ret);
                }
+               return (Type) ret;
        }
 
        /// <summary>
@@ -691,7 +601,7 @@ public class TypeManager {
        public static void LoadAllImportedTypes ()
        {
                AllClsTopLevelTypes = new Hashtable (1500);
-               foreach (Assembly a in assemblies) {
+               foreach (Assembly a in RootNamespace.Global.Assemblies) {
                        foreach (Type t in a.GetExportedTypes ()) {
                                AllClsTopLevelTypes [t.FullName.ToLower (System.Globalization.CultureInfo.InvariantCulture)] = null;
                        }
@@ -700,7 +610,7 @@ public class TypeManager {
 
        public static bool NamespaceClash (string name, Location loc)
        {
-               if (Namespace.LookupNamespace (name, false) == null)
+               if (! RootNamespace.Global.IsNamespace (name))
                        return false;
 
                Report.Error (519, loc, String.Format ("`{0}' clashes with a predefined namespace", name));
@@ -712,7 +622,19 @@ public class TypeManager {
        /// </summary>
        static public string CSharpName (Type t)
        {
-               return Regex.Replace (t.FullName, 
+               if (t == typeof(NullType))
+                       return "null";
+
+#if GMCS_SOURCE 
+               if (IsNullableType (t) && !t.IsGenericTypeDefinition) {
+                       t = GetTypeArguments (t) [0];
+                       return CSharpName (t) + "?";
+               }
+#endif
+
+               string name = GetFullName (t);
+
+               return Regex.Replace (name, 
                        @"^System\." +
                        @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
                        @"Single|Double|Char|Decimal|Byte|SByte|Object|" +
@@ -752,11 +674,84 @@ public class TypeManager {
        /// </summary>
        static public string GetFullNameSignature (MemberInfo mi)
        {
+               PropertyInfo pi = mi as PropertyInfo;
+               if (pi != null) {
+                       MethodBase pmi = pi.GetGetMethod (true);
+                       if (pmi == null)
+                               pmi = pi.GetSetMethod (true);
+                       if (GetParameterData (pmi).Count > 0)
+                               mi = pmi;
+               }
                return (mi is MethodBase)
                        ? CSharpSignature (mi as MethodBase) 
                        : CSharpName (mi.DeclaringType) + '.' + mi.Name;
        }
 
+#if GMCS_SOURCE
+       private static int GetFullName (Type t, StringBuilder sb)
+       {
+               int pos = 0;
+
+               if (!t.IsGenericType) {
+                       sb.Append (t.FullName);
+                       return 0;
+               }
+
+               if (t.DeclaringType != null) {
+                       pos = GetFullName (t.DeclaringType, sb);
+                       sb.Append ('.');
+                       sb.Append (RemoveGenericArity (t.Name));
+               } else {
+                       sb.Append (RemoveGenericArity (t.FullName));
+               }
+
+               Type[] this_args = GetTypeArguments (t);
+
+               if (this_args.Length < pos)
+                       throw new InternalErrorException (
+                               "Enclosing class " + t.DeclaringType + " has more type arguments than " + t);
+               if (this_args.Length == pos)
+                       return pos;
+
+               sb.Append ('<');
+               for (;;) {
+                       sb.Append (CSharpName (this_args [pos++]));
+                       if (pos == this_args.Length)
+                               break;
+                       sb.Append (',');
+               }
+               sb.Append ('>');
+               return pos;
+       }
+
+       public static string GetFullName (Type t)
+       {
+               if (t.IsGenericParameter)
+                       return t.Name;
+               if (!t.IsGenericType)
+                       return t.FullName;
+
+               StringBuilder sb = new StringBuilder ();
+               int pos = GetFullName (t, sb);
+               if (pos <= 0)
+                       throw new InternalErrorException ("Generic Type " + t + " doesn't have type arguments");
+               return sb.ToString ();
+       }
+#else
+       public static string GetFullName (Type t)
+       {
+               return t.FullName;
+       }
+#endif
+
+       public static string RemoveGenericArity (string from)
+       {
+               int i = from.IndexOf ('`');
+               if (i > 0)
+                       return from.Substring (0, i);
+               return from;
+       }
+
        /// <summary>
        /// When we need to report accessors as well
        /// </summary>
@@ -794,10 +789,18 @@ public class TypeManager {
 
                // Is indexer
                if (mb.IsSpecialName && !mb.IsConstructor) {
-                       if (iparams.Count > 1) {
+                       if (iparams.Count > (mb.Name.StartsWith ("get_") ? 0 : 1)) {
                                sig.Append ("this[");
-                               int before_ret_val = parameters.LastIndexOf (',');
-                               sig.Append (parameters.Substring (1, before_ret_val - 1));
+                               if (show_accessor) {
+                                       sig.Append (parameters.Substring (1, parameters.Length - 2));
+                               }
+                               else {
+                                       int before_ret_val = parameters.LastIndexOf (',');
+                                       if (before_ret_val < 0)
+                                               sig.Append (parameters.Substring (1, parameters.Length - 2));
+                                       else
+                                               sig.Append (parameters.Substring (1, before_ret_val - 1));
+                               }
                                sig.Append (']');
                        } else {
                                sig.Append (mb.Name.Substring (4));
@@ -805,9 +808,23 @@ public class TypeManager {
                } else {
                        if (mb.Name == ".ctor")
                                sig.Append (mb.DeclaringType.Name);
-                       else
+                       else {
                                sig.Append (mb.Name);
 
+#if GMCS_SOURCE
+                               if (TypeManager.IsGenericMethod (mb)) {
+                                       Type[] args = mb.GetGenericArguments ();
+                                       sig.Append ('<');
+                                       for (int i = 0; i < args.Length; i++) {
+                                               if (i > 0)
+                                                       sig.Append (',');
+                                               sig.Append (args [i].Name);
+                                       }
+                                       sig.Append ('>');
+                               }
+#endif
+                       }
+
                        sig.Append (parameters);
                }
 
@@ -819,6 +836,18 @@ public class TypeManager {
                return sig.ToString ();
        }
 
+       public static string GetMethodName (MethodInfo m)
+       {
+#if GMCS_SOURCE
+               if (!IsGenericMethodDefinition (m) && !IsGenericMethod (m))
+                       return m.Name;
+
+               return MemberName.MakeName (m.Name, m.GetGenericArguments ().Length);
+#else
+               return m.Name;
+#endif
+       }
+
        static public string CSharpSignature (EventInfo ei)
        {
                return CSharpName (ei.DeclaringType) + '.' + ei.Name;
@@ -830,8 +859,8 @@ public class TypeManager {
        /// </summary>
        static Type CoreLookupType (string ns_name, string name)
        {
-               Namespace ns = Namespace.LookupNamespace (ns_name, true);
-               FullNamedExpression fne = ns.Lookup (RootContext.Tree.Types, name, Location.Null);
+               Namespace ns = RootNamespace.Global.GetNamespace (ns_name, true);
+               FullNamedExpression fne = ns.Lookup (RootContext.ToplevelTypes, name, Location.Null);
                Type t = fne == null ? null : fne.Type;
                if (t == null)
                        Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
@@ -876,7 +905,7 @@ public class TypeManager {
                return GetMethod (t, name, args, false, report_errors);
        }
 
-       static MethodInfo GetMethod (Type t, string name, Type [] args)
+       public static MethodInfo GetMethod (Type t, string name, Type [] args)
        {
                return GetMethod (t, name, args, true);
        }
@@ -885,10 +914,10 @@ public class TypeManager {
        ///   Returns the PropertyInfo for a property named `name' defined
        ///   in type `t'
        /// </summary>
-       static PropertyInfo GetProperty (Type t, string name)
+       public static PropertyInfo GetProperty (Type t, string name)
        {
                MemberList list = FindMembers (t, MemberTypes.Property, BindingFlags.Public |
-                                   BindingFlags.Instance, Type.FilterName, name);
+                                              BindingFlags.Instance, Type.FilterName, name);
                if (list.Count == 0) {
                        Report.Error (-19, "Can not find the core property `" + name + "'");
                        return null;
@@ -913,6 +942,9 @@ public class TypeManager {
 
                sig.name = ".ctor";
                sig.args = args;
+
+               if (t == null)
+                       throw new InternalErrorException ("Core types haven't been initialized yet?");
                
                list = FindMembers (t, MemberTypes.Constructor,
                                    instance_and_static | BindingFlags.Public | BindingFlags.DeclaredOnly,
@@ -933,7 +965,6 @@ public class TypeManager {
 
        public static void InitEnumUnderlyingTypes ()
        {
-
                int32_type    = CoreLookupType ("System", "Int32");
                int64_type    = CoreLookupType ("System", "Int64");
                uint32_type   = CoreLookupType ("System", "UInt32"); 
@@ -942,6 +973,15 @@ public class TypeManager {
                sbyte_type    = CoreLookupType ("System", "SByte");
                short_type    = CoreLookupType ("System", "Int16");
                ushort_type   = CoreLookupType ("System", "UInt16");
+
+               ienumerator_type     = CoreLookupType ("System.Collections", "IEnumerator");
+               ienumerable_type     = CoreLookupType ("System.Collections", "IEnumerable");
+
+               idisposable_type     = CoreLookupType ("System", "IDisposable");
+
+#if GMCS_SOURCE
+               InitGenericCoreTypes ();
+#endif
        }
        
        /// <remarks>
@@ -979,13 +1019,12 @@ public class TypeManager {
                runtime_handle_type  = CoreLookupType ("System", "RuntimeTypeHandle");
                asynccallback_type   = CoreLookupType ("System", "AsyncCallback");
                iasyncresult_type    = CoreLookupType ("System", "IAsyncResult");
-               ienumerator_type     = CoreLookupType ("System.Collections", "IEnumerator");
-               ienumerable_type     = CoreLookupType ("System.Collections", "IEnumerable");
-               idisposable_type     = CoreLookupType ("System", "IDisposable");
                icloneable_type      = CoreLookupType ("System", "ICloneable");
                iconvertible_type    = CoreLookupType ("System", "IConvertible");
+               interlocked_type     = CoreLookupType ("System.Threading", "Interlocked");
                monitor_type         = CoreLookupType ("System.Threading", "Monitor");
                intptr_type          = CoreLookupType ("System", "IntPtr");
+               uintptr_type         = CoreLookupType ("System", "UIntPtr");
 
                attribute_type       = CoreLookupType ("System", "Attribute");
                attribute_usage_type = CoreLookupType ("System", "AttributeUsageAttribute");
@@ -995,6 +1034,9 @@ public class TypeManager {
                param_array_type     = CoreLookupType ("System", "ParamArrayAttribute");
                in_attribute_type    = CoreLookupType ("System.Runtime.InteropServices", "InAttribute");
                out_attribute_type   = CoreLookupType ("System.Runtime.InteropServices", "OutAttribute");
+#if NET_2_0
+               default_parameter_value_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "DefaultParameterValueAttribute");
+#endif
                typed_reference_type = CoreLookupType ("System", "TypedReference");
                arg_iterator_type    = CoreLookupType ("System", "ArgIterator");
                mbr_type             = CoreLookupType ("System", "MarshalByRefObject");
@@ -1022,6 +1064,8 @@ public class TypeManager {
                required_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "RequiredAttributeAttribute");
                guid_attr_type = CoreLookupType ("System.Runtime.InteropServices", "GuidAttribute");
                assembly_culture_attribute_type = CoreLookupType ("System.Reflection", "AssemblyCultureAttribute");
+               comimport_attr_type = CoreLookupType ("System.Runtime.InteropServices", "ComImportAttribute");
+               coclass_attr_type = CoreLookupType ("System.Runtime.InteropServices", "CoClassAttribute");
 
                //
                // .NET 2.0
@@ -1030,6 +1074,9 @@ public class TypeManager {
                compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
                fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "FixedBufferAttribute");
                default_charset_type = CoreLookupType ("System.Runtime.InteropServices", "DefaultCharSetAttribute");
+               internals_visible_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
+               runtime_compatibility_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
+               type_forwarder_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "TypeForwardedToAttribute");
 #endif
                //
                // When compiling corlib, store the "real" types here.
@@ -1040,13 +1087,12 @@ public class TypeManager {
                        system_type_type = typeof (System.Type);
                        system_assemblybuilder_type = typeof (System.Reflection.Emit.AssemblyBuilder);
 
-                       Type [] void_arg = {  };
                        system_int_array_get_length = GetMethod (
-                               system_array_type, "get_Length", void_arg);
+                               system_array_type, "get_Length", Type.EmptyTypes);
                        system_int_array_get_rank = GetMethod (
-                               system_array_type, "get_Rank", void_arg);
+                               system_array_type, "get_Rank", Type.EmptyTypes);
                        system_object_array_clone = GetMethod (
-                               system_array_type, "Clone", void_arg);
+                               system_array_type, "Clone", Type.EmptyTypes);
 
                        Type [] system_int_arg = { system_int32_type };
                        system_int_array_get_length_int = GetMethod (
@@ -1173,23 +1219,22 @@ public class TypeManager {
                //
                // Void arguments
                //
-               Type [] void_arg = {  };
                ienumerator_getcurrent = GetProperty (
                        ienumerator_type, "Current");
                bool_movenext_void = GetMethod (
-                       ienumerator_type, "MoveNext", void_arg);
+                       ienumerator_type, "MoveNext", Type.EmptyTypes);
                void_reset_void = GetMethod (
-                       ienumerator_type, "Reset", void_arg);
+                       ienumerator_type, "Reset", Type.EmptyTypes);
                void_dispose_void = GetMethod (
-                       idisposable_type, "Dispose", void_arg);
+                       idisposable_type, "Dispose", Type.EmptyTypes);
                int_get_offset_to_string_data = GetMethod (
-                       runtime_helpers_type, "get_OffsetToStringData", void_arg);
+                       runtime_helpers_type, "get_OffsetToStringData", Type.EmptyTypes);
                int_array_get_length = GetMethod (
-                       array_type, "get_Length", void_arg);
+                       array_type, "get_Length", Type.EmptyTypes);
                int_array_get_rank = GetMethod (
-                       array_type, "get_Rank", void_arg);
+                       array_type, "get_Rank", Type.EmptyTypes);
                ienumerable_getenumerator_void = GetMethod (
-                       ienumerable_type, "GetEnumerator", void_arg);
+                       ienumerable_type, "GetEnumerator", Type.EmptyTypes);
                
                //
                // Int32 arguments
@@ -1206,7 +1251,7 @@ public class TypeManager {
                // System.Array methods
                //
                object_array_clone = GetMethod (
-                       array_type, "Clone", void_arg);
+                       array_type, "Clone", Type.EmptyTypes);
                Type [] array_int_arg = { array_type, int32_type };
                void_array_copyto_array_int = GetMethod (
                        array_type, "CopyTo", array_int_arg);
@@ -1243,8 +1288,7 @@ public class TypeManager {
                //
                // Attributes
                //
-               cons_param_array_attribute = GetConstructor (param_array_type, void_arg);
-               unverifiable_code_ctor = GetConstructor (unverifiable_code_type, void_arg);
+               unverifiable_code_ctor = GetConstructor (unverifiable_code_type, Type.EmptyTypes);
                default_member_ctor = GetConstructor (default_member_type, string_);
 
                Type[] short_arg = { short_type };
@@ -1256,20 +1300,39 @@ public class TypeManager {
                field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type []
                        { int32_type });
 
+               //
+               // System.Threading.CompareExchange
+               //
+               Type[] compare_exchange_types = {
+                       GetReferenceType (int32_type), int32_type, int32_type };
+               int_interlocked_compare_exchange = GetMethod (
+                       interlocked_type, "CompareExchange", compare_exchange_types);
+
                //
                // .NET 2.0 types
                //
 #if NET_2_0
                compiler_generated_attr = new CustomAttributeBuilder (
-                       GetConstructor (compiler_generated_attr_type, void_arg), new object[0]);
+                       GetConstructor (compiler_generated_attr_type, Type.EmptyTypes), new object[0]);
 
                Type[] type_int_arg = { type_type, int32_type };
                fixed_buffer_attr_ctor = GetConstructor (fixed_buffer_attr_type, type_int_arg);
 #endif
 
                // Object
-               object_ctor = GetConstructor (object_type, void_arg);
+               object_ctor = GetConstructor (object_type, Type.EmptyTypes);
 
+#if GMCS_SOURCE
+               InitGenericCodeHelpers ();
+#endif
+       }
+
+       static public ConstructorInfo ConsParamArrayAttribute {
+               get {
+                       if (cons_param_array_attribute == null)
+                               cons_param_array_attribute = GetConstructor (param_array_type, Type.EmptyTypes);
+                       return cons_param_array_attribute;
+               }
        }
 
        const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
@@ -1281,6 +1344,11 @@ public class TypeManager {
        public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
                                              MemberFilter filter, object criteria)
        {
+#if MS_COMPATIBLE && GMCS_SOURCE
+               if (t.IsGenericType && !t.IsGenericTypeDefinition)
+                       t = t.GetGenericTypeDefinition ();
+#endif
+
                DeclSpace decl = (DeclSpace) builder_to_declspace [t];
 
                //
@@ -1299,9 +1367,25 @@ public class TypeManager {
                // a TypeBuilder array will return a Type, not a TypeBuilder,
                // and we can not call FindMembers on this type.
                //
-               if (t.IsSubclassOf (TypeManager.array_type))
+               if (
+#if MS_COMPATIBLE && GMCS_SOURCE
+                       !t.IsGenericType &&
+#endif
+                       t.IsSubclassOf (TypeManager.array_type))
                        return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
 
+#if GMCS_SOURCE
+               if (t is GenericTypeParameterBuilder) {
+                       TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+                       Timer.StartTimer (TimerType.FindMembers);
+                       MemberList list = tparam.FindMembers (
+                               mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       return list;
+               }
+#endif
+
                //
                // Since FindMembers will not lookup both static and instance
                // members, we emulate this behaviour here.
@@ -1347,20 +1431,14 @@ public class TypeManager {
        ///   to check base classes and interfaces anymore.
        /// </summary>
        private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
-                                                           string name, out bool used_cache)
+                                                              string name, out bool used_cache)
        {
                MemberCache cache;
 
-               //
-               // We have to take care of arrays specially, because GetType on
-               // a TypeBuilder array will return a Type, not a TypeBuilder,
-               // and we can not call FindMembers on this type.
-               //
-               if (t == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
-                       used_cache = true;
-                       return TypeHandle.ArrayType.MemberCache.FindMembers (
-                               mt, bf, name, FilterWithClosure_delegate, null);
-               }
+#if GMCS_SOURCE && MS_COMPATIBLE
+        if (t.IsGenericType && !t.IsGenericTypeDefinition)
+            t = t.GetGenericTypeDefinition();
+#endif
 
                //
                // If this is a dynamic type, it's always in the `builder_to_declspace' hash table
@@ -1382,17 +1460,53 @@ public class TypeManager {
 
                        // If there is no MemberCache, we need to use the "normal" FindMembers.
                        // Note, this is a VERY uncommon route!
-                       
+
                        MemberList list;
                        Timer.StartTimer (TimerType.FindMembers);
                        list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
                                                 FilterWithClosure_delegate, name);
                        Timer.StopTimer (TimerType.FindMembers);
                        used_cache = false;
-                        
                        return (MemberInfo []) list;
                }
 
+               //
+               // We have to take care of arrays specially, because GetType on
+               // a TypeBuilder array will return a Type, not a TypeBuilder,
+               // and we can not call FindMembers on this type.
+               //
+               if (t.IsArray) { //  == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
+                       used_cache = true;
+                       return TypeHandle.ArrayType.MemberCache.FindMembers (
+                               mt, bf, name, FilterWithClosure_delegate, null);
+               }
+
+#if GMCS_SOURCE
+               if (t is GenericTypeParameterBuilder) {
+                       TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+                       MemberList list;
+                       Timer.StartTimer (TimerType.FindMembers);
+                       list = tparam.FindMembers (mt, bf & ~BindingFlags.DeclaredOnly,
+                                                  FilterWithClosure_delegate, name);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       used_cache = true;
+                       return (MemberInfo []) list;
+               }
+#endif
+
+               if (IsGenericType (t) && (mt == MemberTypes.NestedType)) {
+                       //
+                       // This happens if we're resolving a class'es base class and interfaces
+                       // in TypeContainer.DefineType().  At this time, the types aren't
+                       // populated yet, so we can't use the cache.
+                       //
+                       MemberInfo[] info = t.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
+                                                          FilterWithClosure_delegate, name);
+                       used_cache = false;
+                       return info;
+               }
+
                //
                // This call will always succeed.  There is exactly one TypeHandle instance per
                // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return
@@ -1406,6 +1520,7 @@ public class TypeManager {
 
        public static bool IsBuiltinType (Type t)
        {
+               t = TypeToCoreType (t);
                if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
                    t == int64_type || t == uint64_type || t == float_type || t == double_type ||
                    t == char_type || t == short_type || t == decimal_type || t == bool_type ||
@@ -1434,6 +1549,7 @@ public class TypeManager {
 
        public static bool IsDelegateType (Type t)
        {
+               t = DropGenericTypeArguments (t);
                if (t.IsSubclassOf (TypeManager.delegate_type))
                        return true;
                else
@@ -1445,6 +1561,10 @@ public class TypeManager {
                if (builder_to_declspace [t] is Enum)
                        return true;
 
+#if MS_COMPATIBLE && GMCS_SOURCE
+               if (t.IsGenericParameter || t.IsGenericType)
+                       return false;
+#endif
                return t.IsEnum;
        }
 
@@ -1459,6 +1579,16 @@ public class TypeManager {
                return false;
        }
 
+       public static bool IsNullType (Type t)
+       {
+               return t == null_type;
+       }
+
+       public static bool IsAttributeType (Type t)
+       {
+               return t == attribute_type && t.BaseType != null || IsSubclassOf (t, attribute_type);
+       }
+       
        static Stack unmanaged_enclosing_types = new Stack (4);
 
        //
@@ -1474,6 +1604,9 @@ public class TypeManager {
                if (t == TypeManager.object_type || t == TypeManager.string_type)
                        return false;
 
+               if (IsGenericType (t) || IsGenericParameter (t))
+                       return false;
+
                if (IsBuiltinOrEnum (t))
                        return true;
 
@@ -1488,14 +1621,21 @@ public class TypeManager {
                if (!IsValueType (t))
                        return false;
 
+#if GMCS_SOURCE
+               for (Type p = t.DeclaringType; p != null; p = p.DeclaringType) {
+                       if (p.IsGenericTypeDefinition)
+                               return false;
+               }
+#endif
+
                unmanaged_enclosing_types.Push (t);
 
                bool retval = true;
 
-               if (t is TypeBuilder){
+               if (t is TypeBuilder) {
                        TypeContainer tc = LookupTypeContainer (t);
                        if (tc.Fields != null){
-                               foreach (Field f in tc.Fields){
+                               foreach (FieldMember f in tc.Fields){
                                        // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked.
                                        if ((f.ModFlags & Modifiers.STATIC) != 0)
                                                continue;
@@ -1525,10 +1665,7 @@ public class TypeManager {
                
        public static bool IsValueType (Type t)
        {
-               if (t.IsSubclassOf (TypeManager.value_type) && (t != TypeManager.enum_type))
-                       return true;
-               else
-                       return false;
+               return t.IsValueType || IsGenericParameter (t);
        }
        
        public static bool IsInterfaceType (Type t)
@@ -1542,19 +1679,65 @@ public class TypeManager {
 
        public static bool IsSubclassOf (Type type, Type base_type)
        {
-               do {
-                       if (type.Equals (base_type))
+               TypeParameter tparam = LookupTypeParameter (type);
+               TypeParameter pparam = LookupTypeParameter (base_type);
+
+               if ((tparam != null) && (pparam != null)) {
+                       if (tparam == pparam)
                                return true;
 
-                       type = type.BaseType;
-               } while (type != null);
+                       return tparam.IsSubclassOf (base_type);
+               }
 
-               return false;
+#if MS_COMPATIBLE && GMCS_SOURCE
+               if (type.IsGenericType)
+                       type = type.GetGenericTypeDefinition ();
+#endif
+
+               if (type.IsSubclassOf (base_type))
+                       return true;
+
+               do {
+                       if (IsEqual (type, base_type))
+                               return true;
+
+                       type = type.BaseType;
+               } while (type != null);
+
+               return false;
        }
 
-       public static bool IsFamilyAccessible (Type type, Type base_type)
+       public static bool IsPrivateAccessible (Type type, Type parent)
        {
-               return IsSubclassOf (type, base_type);
+               if (type == null)
+                       return false;
+
+               if (type.Equals (parent))
+                       return true;
+
+               return DropGenericTypeArguments (type) == DropGenericTypeArguments (parent);
+       }
+
+       public static bool IsFamilyAccessible (Type type, Type parent)
+       {
+               TypeParameter tparam = LookupTypeParameter (type);
+               TypeParameter pparam = LookupTypeParameter (parent);
+
+               if ((tparam != null) && (pparam != null)) {
+                       if (tparam == pparam)
+                               return true;
+
+                       return tparam.IsSubclassOf (parent);
+               }
+
+               do {
+                       if (IsInstantiationOfSameGenericType (type, parent))
+                               return true;
+
+                       type = type.BaseType;
+               } while (type != null);
+
+               return false;
        }
 
        //
@@ -1563,7 +1746,7 @@ public class TypeManager {
        public static bool IsNestedFamilyAccessible (Type type, Type base_type)
        {
                do {
-                       if ((type == base_type) || type.IsSubclassOf (base_type))
+                       if (IsFamilyAccessible (type, base_type))
                                return true;
 
                        // Handle nested types.
@@ -1578,12 +1761,18 @@ public class TypeManager {
        //
        public static bool IsNestedChildOf (Type type, Type parent)
        {
-               if (type == parent)
+               if (type == null)
+                       return false;
+
+               type = DropGenericTypeArguments (type);
+               parent = DropGenericTypeArguments (parent);
+
+               if (IsEqual (type, parent))
                        return false;
 
                type = type.DeclaringType;
                while (type != null) {
-                       if (type == parent)
+                       if (IsEqual (type, parent))
                                return true;
 
                        type = type.DeclaringType;
@@ -1592,6 +1781,81 @@ public class TypeManager {
                return false;
        }
 
+#if GMCS_SOURCE
+       //
+       // Checks whether `extern_type' is friend of the output assembly
+       //
+       public static bool IsFriendAssembly (Assembly assembly)
+       {
+               if (assembly_internals_vis_attrs.Contains (assembly))
+                       return (bool)(assembly_internals_vis_attrs [assembly]);
+               
+               object [] attrs = assembly.GetCustomAttributes (internals_visible_attr_type, false);
+               if (attrs.Length == 0) {
+                       assembly_internals_vis_attrs.Add (assembly, false);
+                       return false;
+               }
+
+               AssemblyName this_name = CodeGen.Assembly.Name;
+               byte [] this_token = this_name.GetPublicKeyToken ();
+               bool is_friend = false;
+               foreach (InternalsVisibleToAttribute attr in attrs) {
+                       if (attr.AssemblyName == null || attr.AssemblyName.Length == 0)
+                               continue;
+                       
+                       AssemblyName aname = null;
+                       try {
+                               aname = new AssemblyName (attr.AssemblyName);
+                       } catch (FileLoadException) {
+                       } catch (ArgumentException) {
+                       }
+
+                       if (aname == null || aname.Name != this_name.Name)
+                               continue;
+                       
+                       byte [] key_token = aname.GetPublicKeyToken ();
+                       if (key_token != null) {
+                               if (this_token == null) {
+                                       // Same name, but key token is null
+                                       Error_FriendAccessNameNotMatching (aname.FullName);
+                                       break;
+                               }
+                               
+                               if (!CompareKeyTokens (this_token, key_token))
+                                       continue;
+                       }
+
+                       is_friend = true;
+                       break;
+               }
+
+               assembly_internals_vis_attrs.Add (assembly, is_friend);
+               return is_friend;
+       }
+
+       static bool CompareKeyTokens (byte [] token1, byte [] token2)
+       {
+               for (int i = 0; i < token1.Length; i++)
+                       if (token1 [i] != token2 [i])
+                               return false;
+
+               return true;
+       }
+
+       static void Error_FriendAccessNameNotMatching (string other_name)
+       {
+               Report.Error (281, "Friend access was granted to `" + other_name + 
+                               "', but the output assembly is named `" + CodeGen.Assembly.Name.FullName +
+                               "'. Try adding a reference to `" + other_name + 
+                               "' or change the output assembly name to match it");
+       }
+#else
+       public static bool IsFriendAssembly (Assembly assembly)
+       {
+               return false;
+       }
+#endif
+       
         //
         // Do the right thing when returning the element type of an
         // array type based on whether we are compiling corlib or not
@@ -1621,71 +1885,46 @@ public class TypeManager {
        ///   for anything which is dynamic, and we need this in a number of places,
        ///   we register this information here, and use it afterwards.
        /// </remarks>
-       static public void RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
+       static public void RegisterMethod (MethodBase mb, Parameters ip)
        {
-               if (args == null)
-                       args = NoTypes;
-                               
-               method_arguments.Add (mb, args);
                method_params.Add (mb, ip);
        }
        
        static public ParameterData GetParameterData (MethodBase mb)
        {
-               object pd = method_params [mb];
+               ParameterData pd = (ParameterData)method_params [mb];
                if (pd == null) {
                        if (mb is MethodBuilder || mb is ConstructorBuilder)
                                throw new InternalErrorException ("Argument for Method not registered" + mb);
 
-                       method_params [mb] = pd = new ReflectionParameters (mb);
+                       pd = new ReflectionParameters (mb);
+                       method_params.Add (mb, pd);
                }
-
-               return (ParameterData) pd;
+               return pd;
        }
 
        static public void RegisterOverride (MethodBase override_method, MethodBase base_method)
        {
-               if (method_overrides.Contains (override_method)) {
-                       if (method_overrides [override_method] != base_method)
-                               throw new InternalErrorException ("Override mismatch: " + override_method);
-                       return;
-               }
-               method_overrides [override_method] = base_method;
+               if (!method_overrides.Contains (override_method))
+                       method_overrides [override_method] = base_method;
+               if (method_overrides [override_method] != base_method)
+                       throw new InternalErrorException ("Override mismatch: " + override_method);
        }
 
        static public bool IsOverride (MethodBase m)
        {
+               m = DropGenericMethodArguments (m);
+
                return m.IsVirtual &&
                        (m.Attributes & MethodAttributes.NewSlot) == 0 &&
                        (m is MethodBuilder || method_overrides.Contains (m));
        }
 
-       /// <summary>
-       ///    Returns the argument types for a method based on its methodbase
-       ///
-       ///    For dynamic methods, we use the compiler provided types, for
-       ///    methods from existing assemblies we load them from GetParameters,
-       ///    and insert them into the cache
-       /// </summary>
-       static public Type [] GetArgumentTypes (MethodBase mb)
+       static public MethodBase TryGetBaseDefinition (MethodBase m)
        {
-               object t = method_arguments [mb];
-               if (t != null)
-                       return (Type []) t;
-
-               ParameterInfo [] pi = mb.GetParameters ();
-               int c = pi.Length;
-               Type [] types;
+               m = DropGenericMethodArguments (m);
 
-               if (c == 0) {
-                       types = NoTypes;
-               } else {
-                       types = new Type [c];
-                       for (int i = 0; i < c; i++)
-                               types [i] = pi [i].ParameterType;
-               }
-               method_arguments.Add (mb, types);
-               return types;
+               return (MethodBase) method_overrides [m];
        }
 
        /// <summary>
@@ -1703,12 +1942,12 @@ public class TypeManager {
                        // If we're a PropertyBuilder and not in the
                        // `indexer_arguments' hash, then we're a property and
                        // not an indexer.
-                       return NoTypes;
+                       return Type.EmptyTypes;
                else {
                        ParameterInfo [] pi = indexer.GetIndexParameters ();
                        // Property, not an indexer.
                        if (pi == null)
-                               return NoTypes;
+                               return Type.EmptyTypes;
                        int c = pi.Length;
                        Type [] types = new Type [c];
                        
@@ -1733,6 +1972,16 @@ public class TypeManager {
                return (IConstant)fields [fb];
        }
 
+       public static void RegisterProperty (PropertyInfo pi, PropertyBase pb)
+       {
+               propertybuilder_to_property.Add (pi, pb);
+       }
+
+       public static PropertyBase GetProperty (PropertyInfo pi)
+       {
+               return (PropertyBase)propertybuilder_to_property [pi];
+       }
+
        static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
        {
                if (fieldbuilders_to_fields.Contains (fb))
@@ -1749,11 +1998,12 @@ public class TypeManager {
        //
        static public FieldBase GetField (FieldInfo fb)
        {
+#if GMCS_SOURCE
+               fb = GetGenericFieldDefinition (fb);
+#endif
                return (FieldBase) fieldbuilders_to_fields [fb];
        }
        
-       static Hashtable events;
-
        static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
        {
                if (events == null)
@@ -1882,20 +2132,42 @@ public class TypeManager {
        ///   This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
        ///   be IA, IB, IC.
        /// </remarks>
-       public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
+       public static Type[] ExpandInterfaces (TypeExpr [] base_interfaces)
        {
                ArrayList new_ifaces = new ArrayList ();
 
                foreach (TypeExpr iface in base_interfaces){
-                       Type itype = iface.ResolveType (ec);
-                       if (itype == null)
-                               return null;
+                       Type itype = iface.Type;
 
-                       if (!new_ifaces.Contains (itype))
-                               new_ifaces.Add (itype);
+                       if (new_ifaces.Contains (itype))
+                               continue;
+
+                       new_ifaces.Add (itype);
                        
-                       Type [] implementing = itype.GetInterfaces ();
+                       Type [] implementing = GetInterfaces (itype);
+
+                       foreach (Type imp in implementing){
+                               if (!new_ifaces.Contains (imp))
+                                       new_ifaces.Add (imp);
+                       }
+               }
+               Type [] ret = new Type [new_ifaces.Count];
+               new_ifaces.CopyTo (ret, 0);
+               return ret;
+       }
+
+       public static Type[] ExpandInterfaces (Type [] base_interfaces)
+       {
+               ArrayList new_ifaces = new ArrayList ();
+
+               foreach (Type itype in base_interfaces){
+                       if (new_ifaces.Contains (itype))
+                               continue;
+
+                       new_ifaces.Add (itype);
                        
+                       Type [] implementing = GetInterfaces (itype);
+
                        foreach (Type imp in implementing){
                                if (!new_ifaces.Contains (imp))
                                        new_ifaces.Add (imp);
@@ -1905,7 +2177,7 @@ public class TypeManager {
                new_ifaces.CopyTo (ret, 0);
                return ret;
        }
-       
+               
        static PtrHashtable iface_cache = new PtrHashtable ();
                
        /// <summary>
@@ -1914,7 +2186,6 @@ public class TypeManager {
        /// </summary>
        public static Type [] GetInterfaces (Type t)
        {
-               
                Type [] cached = iface_cache [t] as Type [];
                if (cached != null)
                        return cached;
@@ -1932,16 +2203,24 @@ public class TypeManager {
                if (t.IsArray)
                        t = TypeManager.array_type;
                
-               if (t is TypeBuilder){
+               if ((t is TypeBuilder) || IsGenericType (t)) {
                        Type [] base_ifaces;
                        
                        if (t.BaseType == null)
-                               base_ifaces = NoTypes;
+                               base_ifaces = Type.EmptyTypes;
                        else
                                base_ifaces = GetInterfaces (t.BaseType);
-                       Type [] type_ifaces = (Type []) builder_to_ifaces [t];
-                       if (type_ifaces == null)
-                               type_ifaces = NoTypes;
+                       Type[] type_ifaces;
+                       if (IsGenericType (t))
+#if MS_COMPATIBLE && GMCS_SOURCE
+                               type_ifaces = t.GetGenericTypeDefinition().GetInterfaces ();
+#else
+                               type_ifaces = t.GetInterfaces ();
+#endif
+                       else
+                               type_ifaces = (Type []) builder_to_ifaces [t];
+                       if (type_ifaces == null || type_ifaces.Length == 0)
+                               type_ifaces = Type.EmptyTypes;
 
                        int base_count = base_ifaces.Length;
                        Type [] result = new Type [base_count + type_ifaces.Length];
@@ -1950,6 +2229,15 @@ public class TypeManager {
 
                        iface_cache [t] = result;
                        return result;
+#if GMCS_SOURCE
+               } else if (t is GenericTypeParameterBuilder){
+                       Type[] type_ifaces = (Type []) builder_to_ifaces [t];
+                       if (type_ifaces == null || type_ifaces.Length == 0)
+                               type_ifaces = Type.EmptyTypes;
+
+                       iface_cache [t] = type_ifaces;
+                       return type_ifaces;
+#endif
                } else {
                        Type[] ifaces = t.GetInterfaces ();
                        iface_cache [t] = ifaces;
@@ -2190,6 +2478,7 @@ public class TypeManager {
        /// </remarks>
        public static string IndexerPropertyName (Type t)
        {
+               t = DropGenericTypeArguments (t);
                if (t is TypeBuilder) {
                        TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
                        return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
@@ -2217,32 +2506,96 @@ public class TypeManager {
                                new Type [] { typeof (Type), typeof (bool)},
                                null);
                        if (declare_local_method == null){
-                               Report.Warning (-30, new Location (-1),
-                                               "This version of the runtime does not support making pinned local variables.  " +
-                                               "This code may cause errors on a runtime with a moving GC");
+                               Report.RuntimeMissingSupport (Location.Null, "pinned local variables");
                                return ig.DeclareLocal (t);
                        }
                }
                return (LocalBuilder) declare_local_method.Invoke (ig, new object [] { t, true });
        }
-       
+
+       private static bool IsSignatureEqual (Type a, Type b)
+       {
+               ///
+               /// Consider the following example (bug #77674):
+               ///
+               ///     public abstract class A
+               ///     {
+               ///        public abstract T Foo<T> ();
+               ///     }
+               ///
+               ///     public abstract class B : A
+               ///     {
+               ///        public override U Foo<T> ()
+               ///        { return default (U); }
+               ///     }
+               ///
+               /// Here, `T' and `U' are method type parameters from different methods
+               /// (A.Foo and B.Foo), so both `==' and Equals() will fail.
+               ///
+               /// However, since we're determining whether B.Foo() overrides A.Foo(),
+               /// we need to do a signature based comparision and consider them equal.
+
+               if (a == b)
+                       return true;
+
+#if GMCS_SOURCE
+               if (a.IsGenericParameter && b.IsGenericParameter &&
+                   (a.DeclaringMethod != null) && (b.DeclaringMethod != null)) {
+                       return a.GenericParameterPosition == b.GenericParameterPosition;
+               }
+#endif
+
+               if (a.IsArray && b.IsArray) {
+                       if (a.GetArrayRank () != b.GetArrayRank ())
+                               return false;
+
+                       return IsSignatureEqual (a.GetElementType (), b.GetElementType ());
+               }
+
+               if (a.IsByRef && b.IsByRef)
+                       return IsSignatureEqual (a.GetElementType (), b.GetElementType ());
+
+#if GMCS_SOURCE
+               if (a.IsGenericType && b.IsGenericType) {
+                       if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+                               return false;
+
+                       Type[] aargs = a.GetGenericArguments ();
+                       Type[] bargs = b.GetGenericArguments ();
+
+                       if (aargs.Length != bargs.Length)
+                               return false;
+
+                       for (int i = 0; i < aargs.Length; i++) {
+                               if (!IsSignatureEqual (aargs [i], bargs [i]))
+                                       return false;
+                       }
+
+                       return true;
+               }
+#endif
+
+               return false;
+       }
+
        //
        // Returns whether the array of memberinfos contains the given method
        //
        public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method)
        {
-               Type [] new_args = TypeManager.GetArgumentTypes (new_method);
+               Type [] new_args = TypeManager.GetParameterData (new_method).Types;
                
                foreach (MethodBase method in array) {
                        if (method.Name != new_method.Name)
                                continue;
 
                         if (method is MethodInfo && new_method is MethodInfo)
-                                if (((MethodInfo) method).ReturnType != ((MethodInfo) new_method).ReturnType)
+                                if (!IsSignatureEqual (((MethodInfo) method).ReturnType,
+                                                      ((MethodInfo) new_method).ReturnType))
                                         continue;
 
                         
-                       Type [] old_args = TypeManager.GetArgumentTypes (method);
+                       Type [] old_args = TypeManager.GetParameterData (method).Types;
                        int old_count = old_args.Length;
                        int i;
                        
@@ -2250,7 +2603,7 @@ public class TypeManager {
                                continue;
                        
                        for (i = 0; i < old_count; i++){
-                               if (old_args [i] != new_args [i])
+                               if (!IsSignatureEqual (old_args [i], new_args [i]))
                                        break;
                        }
                        if (i != old_count)
@@ -2292,6 +2645,323 @@ public class TypeManager {
                return target_list;
        }
 
+#region Generics
+       // <remarks>
+       //   Tracks the generic parameters.
+       // </remarks>
+       static PtrHashtable builder_to_type_param;
+
+       public static void AddTypeParameter (Type t, TypeParameter tparam)
+       {
+               if (!builder_to_type_param.Contains (t))
+                       builder_to_type_param.Add (t, tparam);
+       }
+
+       public static TypeParameter LookupTypeParameter (Type t)
+       {
+               return (TypeParameter) builder_to_type_param [t];
+       }
+
+       // This method always return false for non-generic compiler,
+       // while Type.IsGenericParameter is returned if it is supported.
+       public static bool IsGenericParameter (Type type)
+       {
+#if GMCS_SOURCE
+               return type.IsGenericParameter;
+#else
+               return false;
+#endif
+       }
+
+       public static int GenericParameterPosition (Type type)
+       {
+#if GMCS_SOURCE
+               return type.GenericParameterPosition;
+#else
+               throw new InternalErrorException ("should not be called");
+#endif
+       }
+
+       public static bool IsGenericType (Type type)
+       {
+#if GMCS_SOURCE
+               return type.IsGenericType;
+#else
+               return false;
+#endif
+       }
+
+       public static bool IsGenericTypeDefinition (Type type)
+       {
+#if GMCS_SOURCE
+               return type.IsGenericTypeDefinition;
+#else
+               return false;
+#endif
+       }
+
+       public static bool ContainsGenericParameters (Type type)
+       {
+#if GMCS_SOURCE
+               return type.ContainsGenericParameters;
+#else
+               return false;
+#endif
+       }
+
+       public static FieldInfo GetGenericFieldDefinition (FieldInfo fi)
+       {
+#if GMCS_SOURCE
+               if (fi.DeclaringType.IsGenericTypeDefinition ||
+                   !fi.DeclaringType.IsGenericType)
+                       return fi;
+
+               Type t = fi.DeclaringType.GetGenericTypeDefinition ();
+               BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
+                       BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
+
+               foreach (FieldInfo f in t.GetFields (bf))
+                       if (f.MetadataToken == fi.MetadataToken)
+                               return f;
+#endif
+
+               return fi;
+       }
+
+       public static bool IsEqual (Type a, Type b)
+       {
+               if (a.Equals (b))
+                       return true;
+
+#if GMCS_SOURCE
+               if (a.IsGenericParameter && b.IsGenericParameter) {
+                       if (a.DeclaringMethod != b.DeclaringMethod &&
+                           (a.DeclaringMethod == null || b.DeclaringMethod == null))
+                               return false;
+                       return a.GenericParameterPosition == b.GenericParameterPosition;
+               }
+
+               if (a.IsArray && b.IsArray) {
+                       if (a.GetArrayRank () != b.GetArrayRank ())
+                               return false;
+                       return IsEqual (a.GetElementType (), b.GetElementType ());
+               }
+
+               if (a.IsByRef && b.IsByRef)
+                       return IsEqual (a.GetElementType (), b.GetElementType ());
+
+               if (a.IsGenericType && b.IsGenericType) {
+                       if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+                               return false;
+
+                       Type[] aargs = a.GetGenericArguments ();
+                       Type[] bargs = b.GetGenericArguments ();
+
+                       if (aargs.Length != bargs.Length)
+                               return false;
+
+                       for (int i = 0; i < aargs.Length; i++) {
+                               if (!IsEqual (aargs [i], bargs [i]))
+                                       return false;
+                       }
+
+                       return true;
+               }
+#endif
+
+               return false;
+       }
+
+       public static Type DropGenericTypeArguments (Type t)
+       {
+#if GMCS_SOURCE
+               if (!t.IsGenericType)
+                       return t;
+               // Micro-optimization: a generic typebuilder is always a generic type definition
+               if (t is TypeBuilder)
+                       return t;
+               return t.GetGenericTypeDefinition ();
+#else
+               return t;
+#endif
+       }
+
+       public static MethodBase DropGenericMethodArguments (MethodBase m)
+       {
+#if GMCS_SOURCE
+               if (m.IsGenericMethodDefinition)
+                       return m;
+               if (m.IsGenericMethod)
+                       return ((MethodInfo) m).GetGenericMethodDefinition ();
+               if (!m.DeclaringType.IsGenericType)
+                       return m;
+
+               Type t = m.DeclaringType.GetGenericTypeDefinition ();
+               BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
+                       BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
+
+#if MS_COMPATIBLE
+        return m;
+#endif
+
+               if (m is ConstructorInfo) {
+                       foreach (ConstructorInfo c in t.GetConstructors (bf))
+                               if (c.MetadataToken == m.MetadataToken)
+                                       return c;
+               } else {
+                       foreach (MethodBase mb in t.GetMethods (bf))
+                               if (mb.MetadataToken == m.MetadataToken)
+                                       return mb;
+               }
+#endif
+
+               return m;
+       }
+
+       public static Type[] GetGenericArguments (MethodInfo mi)
+       {
+#if GMCS_SOURCE
+               return mi.GetGenericArguments ();
+#else
+               return Type.EmptyTypes;
+#endif
+       }
+
+       public static Type[] GetTypeArguments (Type t)
+       {
+#if GMCS_SOURCE
+               DeclSpace tc = LookupDeclSpace (t);
+               if (tc != null) {
+                       if (!tc.IsGeneric)
+                               return Type.EmptyTypes;
+
+                       TypeParameter[] tparam = tc.TypeParameters;
+                       Type[] ret = new Type [tparam.Length];
+                       for (int i = 0; i < tparam.Length; i++) {
+                               ret [i] = tparam [i].Type;
+                               if (ret [i] == null)
+                                       throw new InternalErrorException ();
+                       }
+
+                       return ret;
+               } else
+                       return t.GetGenericArguments ();
+#else
+               throw new InternalErrorException ();
+#endif
+       }
+
+       public static bool HasGenericArguments (Type t)
+       {
+               return GetNumberOfTypeArguments (t) > 0;
+       }
+
+       public static int GetNumberOfTypeArguments (Type t)
+       {
+#if GMCS_SOURCE
+               if (t.IsGenericParameter)
+                       return 0;
+               DeclSpace tc = LookupDeclSpace (t);
+               if (tc != null)
+                       return tc.IsGeneric ? tc.CountTypeParameters : 0;
+               else
+                       return t.IsGenericType ? t.GetGenericArguments ().Length : 0;
+#else
+               return 0;
+#endif
+       }
+
+       /// <summary>
+       ///   Check whether `type' and `parent' are both instantiations of the same
+       ///   generic type.  Note that we do not check the type parameters here.
+       /// </summary>
+       public static bool IsInstantiationOfSameGenericType (Type type, Type parent)
+       {
+               int tcount = GetNumberOfTypeArguments (type);
+               int pcount = GetNumberOfTypeArguments (parent);
+
+               if (tcount != pcount)
+                       return false;
+
+               type = DropGenericTypeArguments (type);
+               parent = DropGenericTypeArguments (parent);
+
+               return type.Equals (parent);
+       }
+
+       /// <summary>
+       ///   Whether `mb' is a generic method definition.
+       /// </summary>
+       public static bool IsGenericMethodDefinition (MethodBase mb)
+       {
+#if GMCS_SOURCE
+               if (mb.DeclaringType is TypeBuilder) {
+                       IMethodData method = (IMethodData) builder_to_method [mb];
+                       if (method == null)
+                               return false;
+
+                       return method.GenericMethod != null;
+               }
+
+               return mb.IsGenericMethodDefinition;
+#else
+               return false;
+#endif
+       }
+
+       /// <summary>
+       ///   Whether `mb' is a generic method.
+       /// </summary>
+       public static bool IsGenericMethod (MethodBase mb)
+       {
+#if GMCS_SOURCE
+               if (mb.DeclaringType is TypeBuilder) {
+                       IMethodData method = (IMethodData) builder_to_method [mb];
+                       if (method == null)
+                               return false;
+
+                       return method.GenericMethod != null;
+               }
+
+               return mb.IsGenericMethod;
+#else
+               return false;
+#endif
+       }
+
+       public static bool IsNullableType (Type t)
+       {
+#if GMCS_SOURCE
+               return generic_nullable_type == DropGenericTypeArguments (t);
+#else
+               return false;
+#endif
+       }
+
+       public static bool IsNullableTypeOf (Type t, Type nullable)
+       {
+#if GMCS_SOURCE
+               if (!IsNullableType (t))
+                       return false;
+
+               return GetTypeArguments (t) [0] == nullable;
+#else
+               return false;
+#endif
+       }
+
+       public static bool IsNullableValueType (Type t)
+       {
+#if GMCS_SOURCE
+               if (!IsNullableType (t))
+                       return false;
+
+               return GetTypeArguments (t) [0].IsValueType;
+#else
+               return false;
+#endif
+       }
+#endregion
 
 #region MemberLookup implementation
        
@@ -2300,11 +2970,6 @@ public class TypeManager {
        // uses NonPublic for both protected and private), we need to distinguish.
        //
 
-       static internal bool FilterNone (MemberInfo m, object filter_criteria)
-       {
-               return true;
-       }
-
        internal class Closure {
                internal bool     private_ok;
 
@@ -2325,18 +2990,19 @@ public class TypeManager {
                                // It resolved from a simple name, so it should be visible.
                                return true;
 
-                       // A nested class has access to all the protected members visible to its parent.
-                       if (qualifier_type != null && TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
+                       if (IsNestedChildOf (invocation_type, m.DeclaringType))
                                return true;
 
-                       if (invocation_type == m.DeclaringType || invocation_type.IsSubclassOf (m.DeclaringType)) {
+                       for (Type t = invocation_type; t != null; t = t.DeclaringType) {
+                               if (!IsFamilyAccessible (t, m.DeclaringType))
+                                       continue;
+
                                // Although a derived class can access protected members of its base class
                                // it cannot do so through an instance of the base class (CS1540).
                                // => Ancestry should be: declaring_type ->* invocation_type ->*  qualified_type
-                               if (is_static ||
-                                   qualifier_type == null ||
-                                   qualifier_type == invocation_type ||
-                                   qualifier_type.IsSubclassOf (invocation_type))
+                               if (is_static || qualifier_type == null ||
+                                   IsInstantiationOfSameGenericType (t, qualifier_type) ||
+                                   IsFamilyAccessible (qualifier_type, t))
                                        return true;
                        }
 
@@ -2353,17 +3019,18 @@ public class TypeManager {
                internal bool Filter (MemberInfo m, object filter_criteria)
                {
                        //
-                       // Hack: we know that the filter criteria will always be in the `closure'
-                       // fields. 
+                       // Hack: we know that the filter criteria will always be in the
+                       // `closure' // fields. 
                        //
 
                        if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
                                return false;
-                       
+
                        if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
-                           (m.DeclaringType == invocation_type))
+                           (invocation_type != null) &&
+                           IsPrivateAccessible (m.DeclaringType, invocation_type))
                                return true;
-                       
+
                        //
                        // Ugly: we need to find out the type of `m', and depending
                        // on this, tell whether we accept or not
@@ -2372,11 +3039,19 @@ public class TypeManager {
                                MethodBase mb = (MethodBase) m;
                                MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
 
+                               if (ma == MethodAttributes.Public)
+                                       return true;
+
+                               if (ma == MethodAttributes.PrivateScope)
+                                       return false;
+
                                if (ma == MethodAttributes.Private)
-                                       return private_ok || invocation_type == m.DeclaringType ||
+                                       return private_ok ||
+                                               IsPrivateAccessible (invocation_type, m.DeclaringType) ||
                                                IsNestedChildOf (invocation_type, m.DeclaringType);
 
-                               if (invocation_assembly == mb.DeclaringType.Assembly) {
+                               if (invocation_assembly == mb.DeclaringType.Assembly ||
+                                   TypeManager.IsFriendAssembly (mb.DeclaringType.Assembly)) {
                                        if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
                                                return true;
                                } else {
@@ -2384,43 +3059,44 @@ public class TypeManager {
                                                return false;
                                }
 
-                               if (ma == MethodAttributes.Family ||
-                                   ma == MethodAttributes.FamANDAssem ||
-                                   ma == MethodAttributes.FamORAssem)
-                                       return CheckValidFamilyAccess (mb.IsStatic, m);
-                               
-                               // Public.
-                               return true;
+                               // Family, FamORAssem or FamANDAssem
+                               return CheckValidFamilyAccess (mb.IsStatic, m);
                        }
                        
                        if (m is FieldInfo){
                                FieldInfo fi = (FieldInfo) m;
                                FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
                                
+                               if (fa == FieldAttributes.Public)
+                                       return true;
+
+                               if (fa == FieldAttributes.PrivateScope)
+                                       return false;
+
                                if (fa == FieldAttributes.Private)
-                                       return private_ok || (invocation_type == m.DeclaringType) ||
+                                       return private_ok ||
+                                               IsPrivateAccessible (invocation_type, m.DeclaringType) ||
                                                IsNestedChildOf (invocation_type, m.DeclaringType);
 
-                               if (invocation_assembly == fi.DeclaringType.Assembly) {
-                                       if (fa == FieldAttributes.Assembly || fa == FieldAttributes.FamORAssem)
+                               if ((invocation_assembly == fi.DeclaringType.Assembly) ||
+                                   (invocation_assembly == null) ||
+                                   TypeManager.IsFriendAssembly (fi.DeclaringType.Assembly)) {
+                                       if ((fa == FieldAttributes.Assembly) ||
+                                           (fa == FieldAttributes.FamORAssem))
                                                return true;
                                } else {
-                                       if (fa == FieldAttributes.Assembly || fa == FieldAttributes.FamANDAssem)
+                                       if ((fa == FieldAttributes.Assembly) ||
+                                           (fa == FieldAttributes.FamANDAssem))
                                                return false;
                                }
 
-                               if (fa == FieldAttributes.Family ||
-                                   fa == FieldAttributes.FamANDAssem ||
-                                   fa == FieldAttributes.FamORAssem)
-                                       return CheckValidFamilyAccess (fi.IsStatic, m);
-                               
-                               // Public.
-                               return true;
+                               // Family, FamORAssem or FamANDAssem
+                               return CheckValidFamilyAccess (fi.IsStatic, m);
                        }
-                       
+
                        //
-                       // EventInfos and PropertyInfos, return true because they lack permission
-                       // information, so we need to check later on the methods.
+                       // EventInfos and PropertyInfos, return true because they lack
+                       // permission information, so we need to check later on the methods.
                        //
                        return true;
                }
@@ -2460,7 +3136,7 @@ public class TypeManager {
        // that might return multiple matches.
        //
        public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
-                                                 Type queried_type,  MemberTypes mt,
+                                                 Type queried_type, MemberTypes mt,
                                                  BindingFlags original_bf, string name, IList almost_match)
        {
                Timer.StartTimer (TimerType.MemberLookup);
@@ -2580,8 +3256,7 @@ public class TypeManager {
                                if ((list.Length == 2) && (list [1] is FieldInfo))
                                        return new MemberInfo [] { list [0] };
 
-                               // Oooops
-                               return null;
+                               return list;
                        }
 
                        //
@@ -2602,20 +3277,13 @@ public class TypeManager {
                                mt &= (MemberTypes.Method | MemberTypes.Constructor);
                        }
                } while (searching);
-               
-               if (use_first_members_list) {
-                       foreach (MemberInfo mi in first_members_list) {
-                               if (! (mi is MethodBase)) {
-                                       method_list = CopyNewMethods (method_list, first_members_list);
-                                       return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
-                               }
-                       }
-                       return (MemberInfo []) first_members_list;
-               }
 
-               if (method_list != null && method_list.Count > 0)
-                        return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
-                
+               if (use_first_members_list)
+                       return first_members_list;
+
+               if (method_list != null && method_list.Count > 0) {
+                       return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+               }
                //
                // This happens if we already used the cache in the first iteration, in this case
                // the cache already looked in all interfaces.
@@ -2654,7 +3322,7 @@ public class TypeManager {
                string name = mb.Name;
                if (name.StartsWith ("get_") || name.StartsWith ("set_"))
                        return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
-
+                               
                if (name.StartsWith ("add_"))
                        return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
 
@@ -2666,7 +3334,7 @@ public class TypeManager {
                                if (oname == name)
                                        return true;
                        }
-               
+
                        foreach (string oname in Binary.oper_names) {
                                if (oname == name)
                                        return true;
@@ -2674,7 +3342,7 @@ public class TypeManager {
                }
                return false;
        }
-               
+
 #endregion
        
 }
@@ -2758,6 +3426,7 @@ public sealed class TypeHandle : IMemberContainer {
        private static TypeHandle array_type = null;
 
        private Type type;
+       private string full_name;
        private bool is_interface;
        private MemberCache member_cache;
        private MemberCache base_cache;
@@ -2765,12 +3434,17 @@ public sealed class TypeHandle : IMemberContainer {
        private TypeHandle (Type type)
        {
                this.type = type;
+#if MS_COMPATIBLE && GMCS_SOURCE
+               if (type.IsGenericType)
+                       this.type = this.type.GetGenericTypeDefinition ();
+#endif
+               full_name = type.FullName != null ? type.FullName : type.Name;
                if (type.BaseType != null) {
                        base_cache = TypeManager.LookupMemberCache (type.BaseType);
                        BaseType = base_cache.Container;
                } else if (type.IsInterface)
                        base_cache = TypeManager.LookupBaseInterfacesCache (type);
-               this.is_interface = type.IsInterface;
+               this.is_interface = type.IsInterface || TypeManager.IsGenericParameter (type);
                this.member_cache = new MemberCache (this);
        }
 
@@ -2778,7 +3452,7 @@ public sealed class TypeHandle : IMemberContainer {
 
        public string Name {
                get {
-                       return type.FullName;
+                       return full_name;
                }
        }
 
@@ -2803,6 +3477,12 @@ public sealed class TypeHandle : IMemberContainer {
        public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
        {
                 MemberInfo [] members;
+
+#if GMCS_SOURCE
+               if (type is GenericTypeParameterBuilder)
+                       return MemberList.Empty;
+#endif
+
                if (mt == MemberTypes.Event)
                         members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
                 else