updated browser capabilities file
[mono.git] / mcs / gmcs / class.cs
index cabe07c30173780739c79fbf8ea140ccbe8d9768..d9826277297703ecb4952d2d738b80384f6464d8 100755 (executable)
@@ -113,9 +113,6 @@ namespace Mono.CSharp {
 
                ArrayList type_bases;
 
-               // Attributes for this type
-               protected Attributes attributes;
-
                // Information in the case we are an attribute type
 
                public AttributeTargets Targets = AttributeTargets.All;
@@ -123,7 +120,7 @@ namespace Mono.CSharp {
                public bool Inherited;
 
                // The interfaces we implement.
-               Type [] ifaces;
+               TypeExpr [] ifaces;
 
                // The parent member container and our member cache
                IMemberContainer parent_container;
@@ -134,20 +131,18 @@ namespace Mono.CSharp {
                //
                public string IndexerName;
 
-               public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Location l)
-                       : base (ns, parent, name, l)
+               Type GenericType;
+
+               public TypeContainer ():
+                       this (null, null, "", null, new Location (-1)) {
+               }
+
+               public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, l)
                {
-                       string n;
                        types = new ArrayList ();
 
-                       if (parent == null)
-                               n = "";
-                       else 
-                               n = parent.Name;
-
                        base_class_name = null;
-
-                       //Console.WriteLine ("New class " + name + " inside " + n);
                }
 
                public AdditionResult AddConstant (Const constant)
@@ -245,7 +240,7 @@ namespace Mono.CSharp {
                        if (methods == null)
                                methods = new ArrayList ();
 
-                       if (method.Name.IndexOf (".") != -1)
+                       if (method.Name.IndexOf ('.') != -1)
                                methods.Insert (0, method);
                        else 
                                methods.Add (method);
@@ -348,19 +343,39 @@ namespace Mono.CSharp {
                public AdditionResult AddProperty (Property prop)
                {
                        AdditionResult res;
-                       string basename = prop.Name;
-                       string fullname = Name + "." + basename;
 
-                       if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+                       if ((res = AddProperty (prop, prop.Name)) != AdditionResult.Success)
                                return res;
 
+                       if (prop.Get != null) {
+                               if ((res = AddProperty (prop, "get_" + prop.Name)) != AdditionResult.Success)
+                                       return res;
+                       }
+
+                       if (prop.Set != null) {
+                               if ((res = AddProperty (prop, "set_" + prop.Name)) != AdditionResult.Success)
+                               return res;
+                       }
+
                        if (properties == null)
                                properties = new ArrayList ();
 
-                       if (prop.Name.IndexOf (".") != -1)
+                       if (prop.Name.IndexOf ('.') != -1)
                                properties.Insert (0, prop);
                        else
                                properties.Add (prop);
+
+                       return AdditionResult.Success;
+               }
+
+               AdditionResult AddProperty (Property prop, string basename)
+               {
+                       AdditionResult res;
+                       string fullname = Name + "." + basename;
+
+                       if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+                               return res;
+
                        DefineName (fullname, prop);
 
                        return AdditionResult.Success;
@@ -384,7 +399,7 @@ namespace Mono.CSharp {
                        return AdditionResult.Success;
                }
 
-               public AdditionResult AddIndexer (Indexer i)
+               public void AddIndexer (Indexer i)
                {
                        if (indexers == null)
                                indexers = new ArrayList ();
@@ -393,8 +408,6 @@ namespace Mono.CSharp {
                                indexers.Insert (0, i);
                        else
                                indexers.Add (i);
-
-                       return AdditionResult.Success;
                }
 
                public AdditionResult AddOperator (Operator op)
@@ -404,6 +417,12 @@ namespace Mono.CSharp {
 
                        operators.Add (op);
 
+                       string basename = op.Name;
+                       string fullname = Name + "." + basename;
+                       if (!defined_names.Contains (fullname))
+                       {
+                               DefineName (fullname, op);
+                       }
                        return AdditionResult.Success;
                }
 
@@ -507,12 +526,6 @@ namespace Mono.CSharp {
                        }
                }
                
-               public Attributes OptAttributes {
-                       get {
-                               return attributes;
-                       }
-               }
-               
                public bool HaveStaticConstructor {
                        get {
                                return have_static_constructor;
@@ -531,7 +544,6 @@ namespace Mono.CSharp {
                public bool EmitFieldInitializers (EmitContext ec)
                {
                        ArrayList fields;
-                       ILGenerator ig = ec.ig;
                        Expression instance_expr;
                        
                        if (ec.IsStatic){
@@ -571,22 +583,26 @@ namespace Mono.CSharp {
                void DefineDefaultConstructor (bool is_static)
                {
                        Constructor c;
-                       int mods = 0;
 
-                       c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
+                       // The default constructor is public
+                       // If the class is abstract, the default constructor is protected
+                       // The default static constructor is private
+
+                       int mods = Modifiers.PUBLIC;
+                       if (is_static)
+                               mods = Modifiers.STATIC | Modifiers.PRIVATE;
+                       else if ((ModFlags & Modifiers.ABSTRACT) != 0)
+                               mods = Modifiers.PROTECTED;
+
+                       c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
                                             new ConstructorBaseInitializer (
                                                     null, Parameters.EmptyReadOnlyParameters,
                                                     Location),
                                             Location);
                        
-                       if (is_static)
-                               mods = Modifiers.STATIC;
-
-                       c.ModFlags = mods;
-
                        AddConstructor (c);
                        
-                       c.Block = new Block (null);
+                       c.Block = new ToplevelBlock (null, Location);
                        
                }
 
@@ -624,7 +640,7 @@ namespace Mono.CSharp {
                ///   The @parent argument is set to the parent object or null
                ///   if this is `System.Object'. 
                /// </summary>
-               Type [] GetClassBases (bool is_class, out Type parent, out bool error)
+               TypeExpr [] GetClassBases (bool is_class, out TypeExpr parent, out bool error)
                {
                        ArrayList bases = Bases;
                        int count;
@@ -635,14 +651,14 @@ namespace Mono.CSharp {
                        if (is_class)
                                parent = null;
                        else
-                               parent = TypeManager.value_type;
+                               parent = TypeManager.system_valuetype_expr;
 
                        if (bases == null){
                                if (is_class){
                                        if (RootContext.StdLib)
-                                               parent = TypeManager.object_type;
+                                               parent = TypeManager.system_object_expr;
                                        else if (Name != "System.Object")
-                                               parent = TypeManager.object_type;
+                                               parent = TypeManager.system_object_expr;
                                } else {
                                        //
                                        // If we are compiling our runtime,
@@ -650,7 +666,7 @@ namespace Mono.CSharp {
                                        // parent is `System.Object'.
                                        //
                                        if (!RootContext.StdLib && Name == "System.ValueType")
-                                               parent = TypeManager.object_type;
+                                               parent = TypeManager.system_object_expr;
                                }
 
                                return null;
@@ -662,8 +678,7 @@ namespace Mono.CSharp {
                        count = bases.Count;
 
                        if (is_class){
-                               Expression name = (Expression) bases [0];
-                               name = ResolveTypeExpr (name, false, Location);
+                               TypeExpr name = ResolveTypeExpr ((Expression) bases [0], false, Location);
 
                                if (name == null){
                                        error = true;
@@ -676,33 +691,38 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               Type first = name.Type;
-
-                               if (first.IsClass){
-                                       parent = first;
+                               if (name.IsClass){
+                                       parent = name;
                                        start = 1;
                                } else {
-                                       parent = TypeManager.object_type;
+                                       parent = TypeManager.system_object_expr;
                                        start = 0;
                                }
-                               if (first.IsSealed){
+                               if (name.IsSealed){
                                        string detail = "";
                                        
-                                       if (first.IsValueType)
+                                       if (name.IsValueType)
                                                detail = " (a class can not inherit from a struct/enum)";
                                        
                                        Report.Error (509, "class `"+ Name +
                                                      "': Cannot inherit from sealed class `"+
-                                                     first + "'" + detail);
+                                                     name.Name + "'" + detail);
                                        error = true;
                                        return null;
                                }
 
-                               if (!AsAccessible (parent, ModFlags))
+                               if (!parent.CanInheritFrom ()){
+                                       Report.Error (644, Location,
+                                                     "`{0}' cannot inherit from special class `{1}'",
+                                                     Name, parent.Name);
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (!parent.AsAccessible (this, ModFlags))
                                        Report.Error (60, Location,
                                                      "Inconsistent accessibility: base class `" +
-                                                     TypeManager.CSharpName (parent) + "' is less " +
-                                                     "accessible than class `" +
+                                                     name.Name + "' is less accessible than class `" +
                                                      Name + "'");
 
                        } else {
@@ -712,30 +732,24 @@ namespace Mono.CSharp {
                        if (parent != null)
                                base_class_name = parent.Name;
 
-                       Type [] ifaces = new Type [count-start];
+                       TypeExpr [] ifaces = new TypeExpr [count-start];
                        
                        for (i = start, j = 0; i < count; i++, j++){
                                Expression name = (Expression) bases [i];
-                               Expression resolved = ResolveTypeExpr (name, false, Location);
+                               TypeExpr resolved = ResolveTypeExpr (name, false, Location);
                                if (resolved == null)
                                        return null;
                                
                                bases [i] = resolved;
-                               Type t = resolved.Type;
-
-                               if (t == null){
-                                       error = true;
-                                       return null;
-                               }
 
-                               if (is_class == false && !t.IsInterface){
+                               if (is_class == false && !resolved.IsInterface){
                                        Report.Error (527, "In Struct `" + Name + "', type `"+
                                                      name +"' is not an interface");
                                        error = true;
                                        return null;
                                }
                                
-                               if (t.IsClass) {
+                               if (resolved.IsClass) {
                                        if (parent != null){
                                                Report.Error (527, "In Class `" + Name + "', type `"+
                                                              name+"' is not an interface");
@@ -745,14 +759,14 @@ namespace Mono.CSharp {
                                }
 
                                for (int x = 0; x < j; x++) {
-                                       if (t == ifaces [x]) {
+                                       if (resolved == ifaces [x]) {
                                                Report.Error (528, "`" + name + "' is already listed in interface list");
                                                error = true;
                                                return null;
                                        }
                                }
 
-                               ifaces [j] = t;
+                               ifaces [j] = resolved;
                        }
 
                        return TypeManager.ExpandInterfaces (ifaces);
@@ -765,7 +779,7 @@ namespace Mono.CSharp {
                //
                public override TypeBuilder DefineType ()
                {
-                       Type parent;
+                       TypeExpr parent;
                        bool is_class;
 
                        if (TypeBuilder != null)
@@ -794,23 +808,12 @@ namespace Mono.CSharp {
                        if (error)
                                return null;
 
-                       if (is_class && parent != null){
-                               if (parent == TypeManager.enum_type ||
-                                   (parent == TypeManager.value_type && RootContext.StdLib) ||
-                                   parent == TypeManager.delegate_type ||
-                                   parent == TypeManager.array_type){
-                                       Report.Error (
-                                               644, Location, "`" + Name + "' cannot inherit from " +
-                                               "special class `" + TypeManager.CSharpName (parent) + "'");
-                                       error = true;
-                                       return null;
-                               }
-                       }
-
-                       if (IsGeneric && (parent == TypeManager.attribute_type ||
-                                         parent.IsSubclassOf (TypeManager.attribute_type))){
-                               Report.Error (-214, Location, "Generic type can not derive from Attribute");
-                               return null;
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       if (!type_param.Resolve (this)) {
+                                               error = true;
+                                               return null;
+                                       }
                        }
                        
                        if (!is_class && TypeManager.value_type == null)
@@ -818,27 +821,53 @@ namespace Mono.CSharp {
 
                        TypeAttributes type_attributes = TypeAttr;
 
+                       Type ptype;
+                       ConstructedType constructed = parent as ConstructedType;
+                       if ((constructed == null) && (parent != null))
+                               ptype = parent.ResolveType (ec);
+                       else
+                               ptype = null;
+
                        if (IsTopLevel){
                                if (TypeManager.NamespaceClash (Name, Location)) {
                                        error = true;
                                        return null;
                                }
-                               
-                               ModuleBuilder builder = CodeGen.ModuleBuilder;
+
+                               ModuleBuilder builder = CodeGen.Module.Builder;
                                TypeBuilder = builder.DefineType (
-                                       Name, type_attributes, parent, ifaces);
+                                       Name, type_attributes, ptype, null);
                                
                        } else {
                                TypeBuilder builder = Parent.DefineType ();
+                               if (builder == null)
+                                       return null;
+                               
                                TypeBuilder = builder.DefineNestedType (
-                                       Basename, type_attributes, parent, ifaces);
+                                       Basename, type_attributes, ptype, null);
                        }
 
                        if (IsGeneric) {
+                               CurrentType = new ConstructedType (
+                                       Name, CurrentTypeParameters, Location);
+
                                foreach (TypeParameter type_param in TypeParameters)
                                        type_param.Define (TypeBuilder);
                        }
 
+                       if (constructed != null) {
+                               ptype = constructed.ResolveType (ec);
+                               if (ptype == null)
+                                       return null;
+
+                               TypeBuilder.SetParent (ptype);
+                       }
+
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       type_param.DefineType (ec, TypeBuilder);
+                       }
+
                        //
                        // Structs with no fields need to have at least one byte.
                        // The right thing would be to set the PackingSize in a DefineType
@@ -849,10 +878,13 @@ namespace Mono.CSharp {
                        if (!is_class && !have_nonstatic_fields){
                                TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
                                                         FieldAttributes.Private);
-                               // add interfaces that were not added at type creation
-                               if (ifaces != null) {
-                                       foreach (Type i in ifaces)
-                                               TypeBuilder.AddInterfaceImplementation (i);
+                       }
+
+                       // add interfaces that were not added at type creation
+                       if (ifaces != null) {
+                               foreach (TypeExpr iface in ifaces) {
+                                       Type itype = iface.ResolveType (ec);
+                                       TypeBuilder.AddInterfaceImplementation (itype);
                                }
                        }
 
@@ -863,9 +895,7 @@ namespace Mono.CSharp {
 
                        TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
 
-                       if ((parent != null) &&
-                           (parent == TypeManager.attribute_type ||
-                            parent.IsSubclassOf (TypeManager.attribute_type))) {
+                       if ((parent != null) && parent.IsAttribute) {
                                RootContext.RegisterAttribute (this);
                                TypeManager.RegisterAttrType (TypeBuilder, this);
                        } else
@@ -1098,14 +1128,6 @@ namespace Mono.CSharp {
                        if (fields != null)
                                DefineMembers (fields, defined_names);
 
-                       if ((RootContext.WarningLevel >= 4) && (fields != null)) {
-                               foreach (Field f in fields) {
-                                       if (((f.ModFlags & Modifiers.READONLY) != 0) && !f.IsAssigned)
-                                               Report.Warning (649, "Field `" + MakeFQN (Name, f.Name) + "; is never " +
-                                                               "assigned and will ever have its default value");
-                               }
-                       }
-
                        if (this is Class){
                                if (instance_constructors == null){
                                        if (default_constructor == null)
@@ -1167,6 +1189,13 @@ namespace Mono.CSharp {
                        if (delegates != null)
                                DefineMembers (delegates, defined_names);
 
+                       if (CurrentType != null) {
+                               GenericType = CurrentType.ResolveType (ec);
+
+                               ec.ContainerType = GenericType;
+                       }
+
+
 #if CACHE
                        if (TypeBuilder.BaseType != null)
                                parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
@@ -1237,7 +1266,7 @@ namespace Mono.CSharp {
                public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
                                                        MemberFilter filter, object criteria)
                {
-                       ArrayList members = new ArrayList ();
+                       ArrayList members = null;
 
                        int modflags = 0;
                        if ((bf & BindingFlags.Public) != 0)
@@ -1269,35 +1298,52 @@ namespace Mono.CSharp {
 
                        if ((mt & MemberTypes.Field) != 0) {
                                if (fields != null) {
-                                       foreach (Field f in fields) {
+                                       int len = fields.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Field f = (Field) fields [i];
+                                               
                                                if ((f.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((f.ModFlags & static_mask) != static_flags)
                                                        continue;
 
                                                FieldBuilder fb = f.FieldBuilder;
-                                               if (fb != null && filter (fb, criteria) == true)
+                                               if (fb != null && filter (fb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (fb);
                                        }
                                }
+                               }
 
                                if (constants != null) {
-                                       foreach (Const con in constants) {
+                                       int len = constants.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Const con = (Const) constants [i];
+                                               
                                                if ((con.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((con.ModFlags & static_mask) != static_flags)
                                                        continue;
 
                                                FieldBuilder fb = con.FieldBuilder;
-                                               if (fb != null && filter (fb, criteria) == true)
+                                               if (fb != null && filter (fb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (fb);
                                        }
                                }
                        }
+                       }
 
                        if ((mt & MemberTypes.Method) != 0) {
                                if (methods != null) {
-                                       foreach (Method m in methods) {
+                                       int len = methods.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Method m = (Method) methods [i];
+                                               
                                                if ((m.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((m.ModFlags & static_mask) != static_flags)
@@ -1305,26 +1351,40 @@ namespace Mono.CSharp {
                                                
                                                MethodBuilder mb = m.MethodBuilder;
 
-                                               if (mb != null && filter (mb, criteria) == true)
+                                               if (mb != null && filter (mb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (mb);
                                        }
                                }
+                               }
+
+                               if (operators != null) {
+                                       int len = operators.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Operator o = (Operator) operators [i];
 
-                               if (operators != null){
-                                       foreach (Operator o in operators) {
                                                if ((o.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((o.ModFlags & static_mask) != static_flags)
                                                        continue;
                                                
                                                MethodBuilder ob = o.OperatorMethodBuilder;
-                                               if (ob != null && filter (ob, criteria) == true)
+                                               if (ob != null && filter (ob, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (ob);
                                        }
                                }
+                               }
+
+                               if (properties != null) {
+                                       int len = properties.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Property p = (Property) properties [i];
 
-                               if (properties != null){
-                                       foreach (Property p in properties){
                                                if ((p.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((p.ModFlags & static_mask) != static_flags)
@@ -1333,17 +1393,28 @@ namespace Mono.CSharp {
                                                MethodBuilder b;
 
                                                b = p.GetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
+                                               }
 
                                                b = p.SetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
                                        }
                                }
+                               }
+                               
+                               if (indexers != null) {
+                                       int len = indexers.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Indexer ix = (Indexer) indexers [i];
                                
-                               if (indexers != null){
-                                       foreach (Indexer ix in indexers){
                                                if ((ix.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((ix.ModFlags & static_mask) != static_flags)
@@ -1352,33 +1423,52 @@ namespace Mono.CSharp {
                                                MethodBuilder b;
 
                                                b = ix.GetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
+                                               }
 
                                                b = ix.SetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
                                        }
                                }
                        }
+                       }
 
                        if ((mt & MemberTypes.Event) != 0) {
-                               if (events != null)
-                                       foreach (Event e in events) {
+                               if (events != null) {
+                                       int len = events.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Event e = (Event) events [i];
+                                               
                                                if ((e.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((e.ModFlags & static_mask) != static_flags)
                                                        continue;
 
                                                MemberInfo eb = e.EventBuilder;
-                                               if (eb != null && filter (eb, criteria) == true)
+                                               if (eb != null && filter (eb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (e.EventBuilder);
                                        }
                        }
+                               }
+                       }
                        
                        if ((mt & MemberTypes.Property) != 0){
-                               if (properties != null)
-                                       foreach (Property p in properties) {
+                               if (properties != null) {
+                                       int len = properties.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Property p = (Property) properties [i];
+                                               
                                                if ((p.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((p.ModFlags & static_mask) != static_flags)
@@ -1386,12 +1476,19 @@ namespace Mono.CSharp {
 
                                                MemberInfo pb = p.PropertyBuilder;
                                                if (pb != null && filter (pb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (p.PropertyBuilder);
                                                }
                                        }
+                               }
+
+                               if (indexers != null) {
+                                       int len = indexers.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Indexer ix = (Indexer) indexers [i];
 
-                               if (indexers != null)
-                                       foreach (Indexer ix in indexers) {
                                                if ((ix.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((ix.ModFlags & static_mask) != static_flags)
@@ -1399,87 +1496,136 @@ namespace Mono.CSharp {
 
                                                MemberInfo ib = ix.PropertyBuilder;
                                                if (ib != null && filter (ib, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (ix.PropertyBuilder);
                                                }
                                        }
                        }
+                       }
                        
                        if ((mt & MemberTypes.NestedType) != 0) {
-                               if (types != null){
-                                       foreach (TypeContainer t in types) {
+                               if (types != null) {
+                                       int len = types.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               TypeContainer t = (TypeContainer) types [i];
+                                               
                                                if ((t.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = t.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                                members.Add (tb);
                                        }
                                }
+                               }
+
+                               if (enums != null) {
+                                       int len = enums.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Enum en = (Enum) enums [i];
 
-                               if (enums != null){
-                                       foreach (Enum en in enums){
                                                if ((en.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = en.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (tb);
                                        }
                                }
+                               }
+                               
+                               if (delegates != null) {
+                                       int len = delegates.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Delegate d = (Delegate) delegates [i];
                                
-                               if (delegates != null){
-                                       foreach (Delegate d in delegates){
                                                if ((d.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = d.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (tb);
                                        }
                                }
+                               }
+
+                               if (interfaces != null) {
+                                       int len = interfaces.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Interface iface = (Interface) interfaces [i];
 
-                               if (interfaces != null){
-                                       foreach (Interface iface in interfaces){
                                                if ((iface.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = iface.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (tb);
                                        }
                                }
                        }
+                       }
 
                        if ((mt & MemberTypes.Constructor) != 0){
                                if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
-                                       foreach (Constructor c in instance_constructors){
+                                       int len = instance_constructors.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Constructor c = (Constructor) instance_constructors [i];
+                                               
                                                ConstructorBuilder cb = c.ConstructorBuilder;
-                                               if (cb != null)
-                                                       if (filter (cb, criteria) == true)
+                                               if (cb != null && filter (cb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                                members.Add (cb);
                                        }
                                }
+                               }
 
                                if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
                                        ConstructorBuilder cb =
                                                default_static_constructor.ConstructorBuilder;
                                        
-                                       if (cb != null)
-                                       if (filter (cb, criteria) == true)
+                                       if (cb != null && filter (cb, criteria) == true) {
+                                               if (members == null)
+                                                       members = new ArrayList ();
+                                               
                                                members.Add (cb);
                                }
                        }
+                       }
 
                        //
                        // Lookup members in parent if requested.
                        //
                        if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
                                MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
+                               if (list.Count > 0) {
+                                       if (members == null)
+                                               members = new ArrayList ();
+                                       
                                members.AddRange (list);
                        }
+                       }
 
                        Timer.StopTimer (TimerType.TcFindMembers);
 
+                       if (members == null)
+                               return MemberList.Empty;
+                       else
                        return new MemberList (members);
                }
 
@@ -1517,7 +1663,7 @@ namespace Mono.CSharp {
                {
                        if (constants != null)
                                foreach (Const con in constants)
-                                       con.EmitConstant (this);
+                                       con.Emit (this);
                        return;
                }
 
@@ -1576,10 +1722,10 @@ namespace Mono.CSharp {
                        if (RootContext.WarningLevel >= 3) {
                                if (fields != null){
                                        foreach (Field f in fields) {
-                                               if ((f.ModFlags & Modifiers.PUBLIC) != 0)
+                                               if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
                                                        continue;
                                                
-                                               if (f.status == 0){
+                                               if ((f.status & Field.Status.USED) == 0){
                                                        Report.Warning (
                                                                169, f.Location, "Private field " +
                                                                MakeName (f.Name) + " is never used");
@@ -1617,11 +1763,12 @@ namespace Mono.CSharp {
                
                public override void CloseType ()
                {
+                       if (Created)
+                               return;
+                       
                        try {
-                               if (!Created){
                                        Created = true;
                                        TypeBuilder.CreateType ();
-                               }
                        } catch (TypeLoadException){
                                //
                                // This is fine, the code still created the type
@@ -1655,6 +1802,29 @@ namespace Mono.CSharp {
                        if (Delegates != null)
                                foreach (Delegate d in Delegates)
                                        d.CloseType ();
+                       
+                       types = null;
+                       properties = null;
+                       enums = null;
+                       delegates = null;
+                       fields = null;
+                       initialized_fields = null;
+                       initialized_static_fields = null;
+                       constants = null;
+                       interfaces = null;
+                       interface_order = null;
+                       methods = null;
+                       events = null;
+                       indexers = null;
+                       operators = null;
+                       ec = null;
+                       default_constructor = null;
+                       default_static_constructor = null;
+                       type_bases = null;
+                       OptAttributes = null;
+                       ifaces = null;
+                       parent_container = null;
+                       member_cache = null;
                }
 
                public string MakeName (string n)
@@ -1773,108 +1943,6 @@ namespace Mono.CSharp {
                        return ok;
                }
 
-               // Access level of a type.
-               enum AccessLevel {
-                       Public                  = 0,
-                       ProtectedInternal       = 1,
-                       Internal                = 2,
-                       Protected               = 3,
-                       Private                 = 4
-               }
-
-               // Check whether `flags' denotes a more restricted access than `level'
-               // and return the new level.
-               static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
-               {
-                       AccessLevel old_level = level;
-
-                       if ((flags & Modifiers.INTERNAL) != 0) {
-                               if ((flags & Modifiers.PROTECTED) != 0) {
-                                       if ((int) level < (int) AccessLevel.ProtectedInternal)
-                                               level = AccessLevel.ProtectedInternal;
-                               } else {
-                                       if ((int) level < (int) AccessLevel.Internal)
-                                               level = AccessLevel.Internal;
-                               }
-                       } else if ((flags & Modifiers.PROTECTED) != 0) {
-                               if ((int) level < (int) AccessLevel.Protected)
-                                       level = AccessLevel.Protected;
-                       } else if ((flags & Modifiers.PRIVATE) != 0)
-                               level = AccessLevel.Private;
-
-                       return level;
-               }
-
-               // Return the access level for a new member which is defined in the current
-               // TypeContainer with access modifiers `flags'.
-               AccessLevel GetAccessLevel (int flags)
-               {
-                       if ((flags & Modifiers.PRIVATE) != 0)
-                               return AccessLevel.Private;
-
-                       AccessLevel level;
-                       if (!IsTopLevel && (Parent != null))
-                               level = Parent.GetAccessLevel (flags);
-                       else
-                               level = AccessLevel.Public;
-
-                       return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
-               }
-
-               // Return the access level for type `t', but don't give more access than `flags'.
-               static AccessLevel GetAccessLevel (Type t, int flags)
-               {
-                       if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
-                               return AccessLevel.Private;
-
-                       AccessLevel level;
-                       if (TypeManager.IsBuiltinType (t))
-                               return AccessLevel.Public;
-                       else if ((t.DeclaringType != null) && (t != t.DeclaringType))
-                               level = GetAccessLevel (t.DeclaringType, flags);
-                       else {
-                               level = CheckAccessLevel (AccessLevel.Public, flags);
-                       }
-
-                       if (t.IsNestedPublic)
-                               return level;
-
-                       if (t.IsNestedAssembly || t.IsNotPublic) {
-                               if ((int) level < (int) AccessLevel.Internal)
-                                       level = AccessLevel.Internal;
-                       }
-
-                       if (t.IsNestedFamily) {
-                               if ((int) level < (int) AccessLevel.Protected)
-                                       level = AccessLevel.Protected;
-                       }
-
-                       if (t.IsNestedFamORAssem) {
-                               if ((int) level < (int) AccessLevel.ProtectedInternal)
-                                       level = AccessLevel.ProtectedInternal;
-                       }
-
-                       return level;
-               }
-
-               //
-               // Returns true if `parent' is as accessible as the flags `flags'
-               // given for this member.
-               //
-               public bool AsAccessible (Type parent, int flags)
-               {
-                       if (parent.IsUnboundGenericParameter)
-                               return true; // FIXME
-
-                       while (parent.IsArray || parent.IsPointer || parent.IsByRef)
-                               parent = TypeManager.GetElementType (parent);
-
-                       AccessLevel level = GetAccessLevel (flags);
-                       AccessLevel level2 = GetAccessLevel (parent, flags);
-
-                       return (int) level >= (int) level2;
-               }
-
                Hashtable builder_and_args;
                
                public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
@@ -1894,8 +1962,8 @@ namespace Mono.CSharp {
                        bool found = false;
 
                        if (ifaces != null){
-                               foreach (Type t in ifaces){
-                                       if (t == interface_type){
+                               foreach (TypeExpr t in ifaces){
+                                       if (t.Type == interface_type){
                                                found = true;
                                                break;
                                        }
@@ -1910,11 +1978,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
-               {
-                       Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
-               }
-
                //
                // IMemberContainer
                //
@@ -1951,7 +2014,13 @@ namespace Mono.CSharp {
 
                MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
                {
-                       return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
+                       BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
+
+                       if (GenericType != null)
+                               return TypeManager.FindMembers (GenericType, mt, new_bf,
+                                                               null, null);
+                       else
+                               return FindMembers (mt, new_bf, null, null);
                }
 
                //
@@ -2143,7 +2212,7 @@ namespace Mono.CSharp {
                        Modifiers.UNSAFE;
 
                public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
-                       : base (ns, parent, name, l)
+                       : base (ns, parent, name, attrs, l)
                {
                        int accmods;
 
@@ -2153,7 +2222,6 @@ namespace Mono.CSharp {
                                accmods = Modifiers.PRIVATE;
 
                        this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
-                       this.attributes = attrs;
                }
 
                //
@@ -2180,7 +2248,7 @@ namespace Mono.CSharp {
                        Modifiers.PRIVATE;
 
                public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
-                       : base (ns, parent, name, l)
+                       : base (ns, parent, name, attrs, l)
                {
                        int accmods;
                        
@@ -2192,8 +2260,6 @@ namespace Mono.CSharp {
                        this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
 
                        this.ModFlags |= Modifiers.SEALED;
-                       this.attributes = attrs;
-                       
                }
 
                //
@@ -2214,6 +2280,7 @@ namespace Mono.CSharp {
        public abstract class MethodCore : MemberBase {
                public readonly Parameters Parameters;
                protected Block block;
+               protected DeclSpace ds;
                
                //
                // Parameters, cached for semantic analysis.
@@ -2226,11 +2293,12 @@ namespace Mono.CSharp {
                // </summary>
                public bool OverridesSomething;
 
-               public MethodCore (Expression type, int mod, int allowed_mod, string name,
-                                  Attributes attrs, Parameters parameters, Location loc)
+               public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
+                                  string name, Attributes attrs, Parameters parameters, Location loc)
                        : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
                {
                        Parameters = parameters;
+                       this.ds = ds;
                }
                
                //
@@ -2259,14 +2327,14 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected virtual bool DoDefineParameters (TypeContainer container)
+               protected virtual bool DoDefineParameters ()
                {
                        // Check if arguments were correct
-                       parameter_types = Parameters.GetParameterInfo (container);
-                       if ((parameter_types == null) || !CheckParameters (container, parameter_types))
+                       parameter_types = Parameters.GetParameterInfo (ds);
+                       if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
                                return false;
 
-                       parameter_info = new InternalParameters (container, Parameters);
+                       parameter_info = new InternalParameters (ds, Parameters);
 
                        Parameter array_param = Parameters.ArrayParameter;
                        if ((array_param != null) &&
@@ -2401,6 +2469,7 @@ namespace Mono.CSharp {
        public class Method : MethodCore, IIteratorContainer {
                public MethodBuilder MethodBuilder;
                public MethodData MethodData;
+               public readonly GenericMethod GenericMethod;
 
                /// <summary>
                ///   Modifiers allowed in a class declaration
@@ -2417,15 +2486,24 @@ namespace Mono.CSharp {
                        Modifiers.OVERRIDE |
                        Modifiers.ABSTRACT |
                        Modifiers.UNSAFE |
+                       Modifiers.METHOD_YIELDS | 
                        Modifiers.EXTERN;
 
                //
                // return_type can be "null" for VOID values.
                //
-               public Method (Expression return_type, int mod, string name, Parameters parameters,
-                              Attributes attrs, Location l)
-                       : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
-               { }
+               public Method (DeclSpace ds, Expression return_type, int mod, string name,
+                              Parameters parameters, Attributes attrs, Location l)
+                       : base (ds, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
+               {
+               }
+
+               public Method (GenericMethod generic, Expression return_type, int mod, string name,
+                              Parameters parameters, Attributes attrs, Location l)
+                       : base (generic, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
+               {
+                       GenericMethod = generic;
+               }
 
                //
                // Returns the `System.Type' for the ReturnType of this
@@ -2487,7 +2565,7 @@ namespace Mono.CSharp {
                        base.CheckBase (container);
                        
                        // Check whether arguments were correct.
-                       if (!DoDefineParameters (container))
+                       if (!DoDefineParameters ())
                                return false;
 
                        MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
@@ -2582,7 +2660,17 @@ namespace Mono.CSharp {
                //
                public override bool Define (TypeContainer container)
                {
-                       if (!DoDefine (container))
+                       DeclSpace decl;
+                       MethodBuilder mb = null;
+                       if (GenericMethod != null) {
+                               mb = container.TypeBuilder.DefineGenericMethod (Name, flags);
+                               if (!GenericMethod.Define (mb))
+                                       return false;
+                               decl = GenericMethod;
+                       } else
+                               decl = container;
+
+                       if (!DoDefine (decl, container))
                                return false;
 
                        if (!CheckBase (container))
@@ -2590,9 +2678,9 @@ namespace Mono.CSharp {
 
                        CallingConventions cc = GetCallingConvention (container is Class);
 
-                       MethodData = new MethodData (this, null, MemberType, ParameterTypes,
-                                                    ParameterInfo, cc, OptAttributes,
-                                                    ModFlags, flags, true);
+                       MethodData = new MethodData (ds, this, null, MemberType,
+                                                    ParameterTypes, ParameterInfo, cc,
+                                                    OptAttributes, ModFlags, flags, true, mb);
 
                        if (!MethodData.Define (container))
                                return false;
@@ -2613,12 +2701,12 @@ namespace Mono.CSharp {
                        }
 
                        MethodBuilder = MethodData.MethodBuilder;
-                       
+
                        //
                        // This is used to track the Entry Point,
                        //
                        if (Name == "Main" &&
-                           ((ModFlags & Modifiers.STATIC) != 0) && 
+                           ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
                            (RootContext.MainClass == null ||
                             RootContext.MainClass == container.TypeBuilder.FullName)){
                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
@@ -2648,6 +2736,7 @@ namespace Mono.CSharp {
                {
                        MethodData.Emit (container, Block, this);
                        Block = null;
+                       MethodData = null;
                }
 
                void IIteratorContainer.SetYields ()
@@ -2681,7 +2770,7 @@ namespace Mono.CSharp {
                        Expression parent_constructor_group;
                        Type t;
 
-                       ec.CurrentBlock = new Block (null, Block.Flags.Implicit, parameters);
+                       ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
 
                        if (argument_list != null){
                                foreach (Argument a in argument_list){
@@ -2757,7 +2846,6 @@ namespace Mono.CSharp {
        public class Constructor : MethodCore {
                public ConstructorBuilder ConstructorBuilder;
                public ConstructorInitializer Initializer;
-               new public Attributes OptAttributes;
 
                // <summary>
                //   Modifiers allowed for a constructor.
@@ -2775,8 +2863,9 @@ namespace Mono.CSharp {
                // The spec claims that static is not permitted, but
                // my very own code has static constructors.
                //
-               public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
-                       : base (null, 0, AllowedModifiers, name, null, args, l)
+               public Constructor (DeclSpace ds, string name, int mod, Parameters args,
+                                   ConstructorInitializer init, Location l)
+                       : base (ds, null, mod, AllowedModifiers, name, null, args, l)
                {
                        Initializer = init;
                }
@@ -2806,7 +2895,7 @@ namespace Mono.CSharp {
                                               MethodAttributes.SpecialName);
 
                        // Check if arguments were correct.
-                       if (!DoDefineParameters (container))
+                       if (!DoDefineParameters ())
                                return false;
 
                        if ((ModFlags & Modifiers.STATIC) != 0){
@@ -2973,6 +3062,7 @@ namespace Mono.CSharp {
                //
                // Protected data.
                //
+               protected DeclSpace ds;
                protected MemberBase member;
                protected int modifiers;
                protected MethodAttributes flags;
@@ -2990,11 +3080,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               public MethodData (MemberBase member, string name, Type return_type,
+               public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
                                   Type [] parameter_types, InternalParameters parameters,
                                   CallingConventions cc, Attributes opt_attrs,
                                   int modifiers, MethodAttributes flags, bool is_method)
                {
+                       this.ds = ds;
                        this.member = member;
                        this.accessor_name = name;
                        this.ReturnType = return_type;
@@ -3009,6 +3100,17 @@ namespace Mono.CSharp {
                        this.conditionals = null;
                }
 
+               public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
+                                  Type [] parameter_types, InternalParameters parameters,
+                                  CallingConventions cc, Attributes opt_attrs,
+                                  int modifiers, MethodAttributes flags, bool is_method,
+                                  MethodBuilder builder)
+                       : this (ds, member, name, return_type, parameter_types, parameters,
+                               cc, opt_attrs, modifiers, flags, is_method)
+               {
+                       this.builder = builder;
+               }
+
                //
                // Attributes.
                //
@@ -3222,8 +3324,7 @@ namespace Mono.CSharp {
                                                member.InterfaceType, name, ReturnType, ParameterTypes);
 
                                if (member.InterfaceType != null && implementing == null){
-                                       TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
-                                               Location, name);
+                                       Report.Error (539, Location, "'{0}' in explicit interface declaration is not an interface", method_name);
                                        return false;
                                }
                        }
@@ -3313,15 +3414,19 @@ namespace Mono.CSharp {
                                }
                                
                                EmitContext ec = new EmitContext (
-                                       container, Location, null, ReturnType, modifiers);
+                                       container, ds, Location, null, ReturnType, modifiers, false);
                                
                                builder = dllimport_attribute.DefinePInvokeMethod (
                                        ec, container.TypeBuilder, method_name, flags,
                                        ReturnType, ParameterTypes);
-                       } else
+                       } else if (builder == null)
                                builder = container.TypeBuilder.DefineMethod (
                                        method_name, flags, CallingConventions,
                                        ReturnType, ParameterTypes);
+                       else
+                               builder.SetGenericMethodSignature (
+                                       flags, CallingConventions,
+                                       ReturnType, ParameterTypes);
 
                        if (builder == null)
                                return false;
@@ -3375,7 +3480,7 @@ namespace Mono.CSharp {
                        else
                                ig = null;
 
-                       ec = new EmitContext (container, Location, ig, ReturnType, modifiers);
+                       ec = new EmitContext (container, ds, Location, ig, ReturnType, modifiers, false);
 
                        if (OptAttributes != null)
                                Attribute.ApplyAttributes (ec, builder, kind, OptAttributes);
@@ -3436,7 +3541,7 @@ namespace Mono.CSharp {
                        //
                        // FIXME: This code generates buggy code
                        //
-                       if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
+                       if (member is Destructor)
                                EmitDestructor (ec, block);
                        else {
                                SymbolWriter sw = CodeGen.SymbolWriter;
@@ -3458,18 +3563,15 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        
                        Label finish = ig.DefineLabel ();
-                       bool old_in_try = ec.InTry;
+
+                       block.SetDestructor ();
                        
                        ig.BeginExceptionBlock ();
-                       ec.InTry = true;
                        ec.ReturnLabel = finish;
                        ec.HasReturnLabel = true;
                        ec.EmitTopBlock (block, null, Location);
-                       ec.InTry = old_in_try;
                        
                        // ig.MarkLabel (finish);
-                       bool old_in_finally = ec.InFinally;
-                       ec.InFinally = true;
                        ig.BeginFinallyBlock ();
                        
                        if (ec.ContainerType.BaseType != null) {
@@ -3484,7 +3586,6 @@ namespace Mono.CSharp {
                                        ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
                                }
                        }
-                       ec.InFinally = old_in_finally;
                        
                        ig.EndExceptionBlock ();
                        //ig.MarkLabel (ec.ReturnLabel);
@@ -3492,12 +3593,22 @@ namespace Mono.CSharp {
                }
        }
 
+       public class Destructor : Method {
+
+               public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
+                                  Parameters parameters, Attributes attrs, Location l)
+                       : base (ds, return_type, mod, name, parameters, attrs, l)
+               { }
+
+       }
+       
        abstract public class MemberBase : MemberCore {
                public Expression Type;
-               public readonly Attributes OptAttributes;
 
                protected MethodAttributes flags;
 
+               protected readonly int explicit_mod_flags;
+
                //
                // The "short" name of this property / indexer / event.  This is the
                // name without the explicit interface.
@@ -3539,11 +3650,11 @@ namespace Mono.CSharp {
                //
                protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
                                      Attributes attrs, Location loc)
-                       : base (name, loc)
+                       : base (name, attrs, loc)
                {
+                       explicit_mod_flags = mod;
                        Type = type;
                        ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
-                       OptAttributes = attrs;
                }
 
                protected virtual bool CheckBase (TypeContainer container)
@@ -3707,19 +3818,19 @@ namespace Mono.CSharp {
                        return ok;
                }
 
-               protected virtual bool CheckParameters (TypeContainer container, Type [] parameters)
+               protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
                {
                        bool error = false;
 
                        foreach (Type partype in parameters){
                                if (partype.IsPointer){
-                                       if (!UnsafeOK (container))
+                                       if (!UnsafeOK (ds))
                                                error = true;
                                        if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
                                                error = true;
                                }
 
-                               if (container.AsAccessible (partype, ModFlags))
+                               if (ds.AsAccessible (partype, ModFlags))
                                        continue;
 
                                if (this is Indexer)
@@ -3743,7 +3854,7 @@ namespace Mono.CSharp {
                        return !error;
                }
 
-               protected virtual bool DoDefine (TypeContainer container)
+               protected virtual bool DoDefine (DeclSpace decl, TypeContainer container)
                {
                        if (Name == null)
                                Name = "this";
@@ -3754,7 +3865,7 @@ namespace Mono.CSharp {
                        flags = Modifiers.MethodAttr (ModFlags);
 
                        // Lookup Type, verify validity
-                       MemberType = container.ResolveType (Type, false, Location);
+                       MemberType = decl.ResolveType (Type, false, Location);
                        if (MemberType == null)
                                return false;
 
@@ -3802,8 +3913,8 @@ namespace Mono.CSharp {
                        //
                        // Check for explicit interface implementation
                        //
-                       if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
-                               int pos = Name.LastIndexOf (".");
+                       if ((ExplicitInterfaceName == null) && (Name.IndexOf ('.') != -1)){
+                               int pos = Name.LastIndexOf ('.');
 
                                ExplicitInterfaceName = Name.Substring (0, pos);
                                ShortName = Name.Substring (pos + 1);
@@ -3816,12 +3927,19 @@ namespace Mono.CSharp {
                                if (InterfaceType == null)
                                        return false;
 
+                               if (InterfaceType.IsClass) {
+                                       Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
+                                       return false;
+                               }
+
                                // Compute the full name that we need to export.
                                Name = InterfaceType.FullName + "." + ShortName;
                                
                                if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
                                        return false;
                                
+                               Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
+                               
                                IsExplicitImpl = true;
                        } else
                                IsExplicitImpl = false;
@@ -3860,8 +3978,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool IsAssigned;
-
                protected readonly Object init;
                // Private.
                Expression init_expr;
@@ -3890,6 +4006,11 @@ namespace Mono.CSharp {
 
                        return init_expr;
                }
+
+               public void SetAssigned ()
+               {
+                       status |= Status.ASSIGNED;
+               }
        }
 
        //
@@ -3992,10 +4113,17 @@ namespace Mono.CSharp {
                                return false;
                        }
 
+                       try {
                        FieldBuilder = container.TypeBuilder.DefineField (
                                Name, t, Modifiers.FieldAttr (ModFlags));
 
                        TypeManager.RegisterFieldBase (FieldBuilder, this);
+                       }
+                       catch (ArgumentException) {
+                               Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
+                               return false;
+                       }
+
                        return true;
                }
 
@@ -4037,18 +4165,19 @@ namespace Mono.CSharp {
 
                protected EmitContext ec;
 
-               public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
-                                    Parameters parameters, Accessor get_block, Accessor set_block,
+               public PropertyBase (DeclSpace ds, Expression type, string name, int mod_flags,
+                                    int allowed_mod, Parameters parameters,
+                                    Accessor get_block, Accessor set_block,
                                     Attributes attrs, Location loc)
-                       : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
+                       : base (ds, type, mod_flags, allowed_mod, name, attrs, parameters, loc)
                {
                        Get = get_block;
                        Set = set_block;
                }
 
-               protected override bool DoDefine (TypeContainer container)
+               protected override bool DoDefine (DeclSpace decl, TypeContainer container)
                {
-                       if (!base.DoDefine (container))
+                       if (!base.DoDefine (decl, container))
                                return false;
 
                        ec = new EmitContext (container, Location, null, MemberType, ModFlags);
@@ -4064,7 +4193,7 @@ namespace Mono.CSharp {
                        base.CheckBase (container);
                        
                        // Check whether arguments were correct.
-                       if (!DoDefineParameters (container))
+                       if (!DoDefineParameters ())
                                return false;
 
                        if (IsExplicitImpl)
@@ -4195,7 +4324,7 @@ namespace Mono.CSharp {
                }
        }
                        
-       public class Property : PropertyBase {
+       public class Property : PropertyBase, IIteratorContainer {
                const int AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -4208,12 +4337,13 @@ namespace Mono.CSharp {
                        Modifiers.ABSTRACT |
                        Modifiers.UNSAFE |
                        Modifiers.EXTERN |
+                       Modifiers.METHOD_YIELDS |
                        Modifiers.VIRTUAL;
 
-               public Property (Expression type, string name, int mod_flags,
+               public Property (DeclSpace ds, Expression type, string name, int mod_flags,
                                 Accessor get_block, Accessor set_block,
                                 Attributes attrs, Location loc)
-                       : base (type, name, mod_flags, AllowedModifiers,
+                       : base (ds, type, name, mod_flags, AllowedModifiers,
                                Parameters.EmptyReadOnlyParameters,
                                get_block, set_block, attrs, loc)
                {
@@ -4221,7 +4351,7 @@ namespace Mono.CSharp {
 
                public override bool Define (TypeContainer container)
                {
-                       if (!DoDefine (container))
+                       if (!DoDefine (container, container))
                                return false;
 
                        if (!CheckBase (container))
@@ -4235,10 +4365,24 @@ namespace Mono.CSharp {
                                InternalParameters ip = new InternalParameters (
                                        container, Parameters.EmptyReadOnlyParameters);
 
-                               GetData = new MethodData (this, "get", MemberType,
+                               GetData = new MethodData (container, this, "get", MemberType,
                                                          parameters, ip, CallingConventions.Standard,
                                                          Get.OptAttributes, ModFlags, flags, false);
 
+                               //
+                               // Setup iterator if we are one
+                               //
+                               if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
+                                       IteratorHandler ih = new  IteratorHandler (
+                                                                                  "get", container, MemberType,
+                                                                                  parameters, ip, ModFlags, Location);
+                                       
+                                       Block new_block = ih.Setup (block);
+                                       if (new_block == null)
+                                               return false;
+                                       block = new_block;
+                               }
+                               
                                if (!GetData.Define (container))
                                        return false;
 
@@ -4254,7 +4398,7 @@ namespace Mono.CSharp {
                                InternalParameters ip = new InternalParameters (
                                        container, new Parameters (parms, null, Location));
 
-                               SetData = new MethodData (this, "set", TypeManager.void_type,
+                               SetData = new MethodData (container, this, "set", TypeManager.void_type,
                                                          parameters, ip, CallingConventions.Standard,
                                                          Set.OptAttributes, ModFlags, flags, false);
 
@@ -4295,6 +4439,11 @@ namespace Mono.CSharp {
                        }
                        return true;
                }
+
+               public void SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
        }
 
        /// </summary>
@@ -4475,7 +4624,7 @@ namespace Mono.CSharp {
                        EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
                        MethodAttributes m_attr = MethodAttributes.HideBySig | MethodAttributes.SpecialName
 ;
-                       if (!DoDefine (container))
+                       if (!DoDefine (container, container))
                                return false;
 
                        if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
@@ -4504,7 +4653,7 @@ namespace Mono.CSharp {
                        //
                        // Now define the accessors
                        //
-                       AddData = new MethodData (this, "add", TypeManager.void_type,
+                       AddData = new MethodData (container, this, "add", TypeManager.void_type,
                                                  parameter_types, ip, CallingConventions.Standard,
                                                  (Add != null) ? Add.OptAttributes : null,
                                                  ModFlags, flags | m_attr, false);
@@ -4515,7 +4664,7 @@ namespace Mono.CSharp {
                        AddBuilder = AddData.MethodBuilder;
                        AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
 
-                       RemoveData = new MethodData (this, "remove", TypeManager.void_type,
+                       RemoveData = new MethodData (container, this, "remove", TypeManager.void_type,
                                                     parameter_types, ip, CallingConventions.Standard,
                                                     (Remove != null) ? Remove.OptAttributes : null,
                                                     ModFlags, flags | m_attr, false);
@@ -4641,11 +4790,10 @@ namespace Mono.CSharp {
                //
                // Are we implementing an interface ?
                //
-               bool IsImplementing = false;
-               
-               public Indexer (Expression type, string int_type, int flags, Parameters parameters,
-                               Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
-                       : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
+               public Indexer (DeclSpace ds, Expression type, string int_type, int flags,
+                               Parameters parameters, Accessor get_block, Accessor set_block,
+                               Attributes attrs, Location loc)
+                       : base (ds, type, "", flags, AllowedModifiers, parameters, get_block, set_block,
                                attrs, loc)
                {
                        ExplicitInterfaceName = int_type;
@@ -4657,7 +4805,7 @@ namespace Mono.CSharp {
                                PropertyAttributes.RTSpecialName |
                                PropertyAttributes.SpecialName;
                        
-                       if (!DoDefine (container))
+                       if (!DoDefine (container, container))
                                return false;
 
                        IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
@@ -4677,6 +4825,9 @@ namespace Mono.CSharp {
                                Name = ShortName;
                        }
 
+                       if (!CheckNameCollision (container))
+                               return false;
+
                        if (!CheckBase (container))
                                return false;
 
@@ -4684,7 +4835,7 @@ namespace Mono.CSharp {
                        if (Get != null){
                                 InternalParameters ip = new InternalParameters (container, Parameters);
 
-                               GetData = new MethodData (this, "get", MemberType,
+                               GetData = new MethodData (container, this, "get", MemberType,
                                                          ParameterTypes, ip, CallingConventions.Standard,
                                                          Get.OptAttributes, ModFlags, flags, false);
 
@@ -4729,7 +4880,7 @@ namespace Mono.CSharp {
                                
                                InternalParameters ip = new InternalParameters (container, set_formal_params);
 
-                               SetData = new MethodData (this, "set", TypeManager.void_type,
+                               SetData = new MethodData (container, this, "set", TypeManager.void_type,
                                                          set_pars, ip, CallingConventions.Standard,
                                                          Set.OptAttributes, ModFlags, flags, false);
 
@@ -4768,11 +4919,6 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (GetData != null)
-                               IsImplementing = GetData.IsImplementing;
-                       else if (SetData != null)
-                               IsImplementing = SetData.IsImplementing;
-
                        //
                        // Define the PropertyBuilder if one of the following conditions are met:
                        // a) we're not implementing an interface indexer.
@@ -4795,9 +4941,53 @@ namespace Mono.CSharp {
 
                        return true;
                }
+
+               bool CheckNameCollision (TypeContainer container) {
+                       switch (VerifyName (container)){
+                               case DeclSpace.AdditionResult.NameExists:
+                                       Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
+                                       return false;
+
+                               case DeclSpace.AdditionResult.Success:
+                                       return true;
+                       }
+                       throw new NotImplementedException ();
+               }
+
+               DeclSpace.AdditionResult VerifyName (TypeContainer container) {
+                       if (!AddIndexer (container, container.Name + "." + Name))
+                               return DeclSpace.AdditionResult.NameExists;
+
+                       if (Get != null) {
+                               if (!AddIndexer (container, container.Name + ".get_" + Name))
+                                       return DeclSpace.AdditionResult.NameExists;
+                       }
+
+                       if (Set != null) {
+                               if (!AddIndexer (container, container.Name + ".set_" + Name))
+                                       return DeclSpace.AdditionResult.NameExists;
+                       }
+                       return DeclSpace.AdditionResult.Success;
+               }
+
+               bool AddIndexer (TypeContainer container, string fullname)
+               {
+                       object value = container.GetDefinition (fullname);
+
+                       if (value != null) {
+                               return value.GetType () != GetType () ? false : true;
+                       }
+
+                       container.DefineName (fullname, this);
+                       return true;
+               }
+
+               public override string GetSignatureForError () {
+                       return TypeManager.CSharpSignature (PropertyBuilder, true);
+               }
        }
 
-       public class Operator : MemberBase {
+       public class Operator : MemberBase, IIteratorContainer {
 
                const int AllowedModifiers =
                        Modifiers.PUBLIC |
@@ -4864,6 +5054,7 @@ namespace Mono.CSharp {
                        : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
                {
                        OperatorType = type;
+                       Name = "op_" + OperatorType;
                        ReturnType = ret_type;
                        FirstArgType = arg1type;
                        FirstArgName = arg1name;
@@ -4903,10 +5094,11 @@ namespace Mono.CSharp {
                                param_list[1] = new Parameter (SecondArgType, SecondArgName,
                                                               Parameter.Modifier.NONE, null);
                        
-                       OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
+                       OperatorMethod = new Method (container, ReturnType, ModFlags, MethodName,
                                                     new Parameters (param_list, null, Location),
                                                     OptAttributes, Location);
 
+                       OperatorMethod.Block = Block;
                        OperatorMethod.IsOperator = true;                       
                        OperatorMethod.Define (container);
 
@@ -5021,7 +5213,6 @@ namespace Mono.CSharp {
                        if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
                                return;
                        
-                       OperatorMethod.Block = Block;
                        OperatorMethod.Emit (container);
                        Block = null;
                }
@@ -5103,6 +5294,11 @@ namespace Mono.CSharp {
                                        GetName (OperatorType),
                                        param_types [0], param_types [1]);
                }
+
+               public void SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
        }
 
        //
@@ -5278,10 +5474,7 @@ namespace Mono.CSharp {
                        // If only accessible to the defining assembly or 
                        if (prot == MethodAttributes.FamANDAssem ||
                            prot == MethodAttributes.Assembly){
-                               if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
-                                       return true;
-                               else
-                                       return false;
+                               return m.DeclaringType.Assembly == CodeGen.Assembly.Builder;
                        }
 
                        // Anything else (FamOrAssembly and Public) is fine