Merge pull request #606 from sesef/master
[mono.git] / mcs / mcs / class.cs
index 740af6be4d9ea74c3471736d748ad95aeea39028..a13adb2ef79335f5e47d7394c9d4d7cea8832dd0 100644 (file)
@@ -17,7 +17,9 @@ using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Permissions;
-using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Mono.CompilerServices.SymbolWriter;
 
 #if NET_2_1
 using XmlElement = System.Object;
@@ -35,17 +37,366 @@ using System.Reflection.Emit;
 
 namespace Mono.CSharp
 {
-
-       public interface ITypesContainer
+       //
+       // General types container, used as a base class for all constructs which can hold types
+       //
+       public abstract class TypeContainer : MemberCore
        {
-               Location Location { get; }
-               MemberName MemberName { get; }
+               public readonly MemberKind Kind;
+               public readonly string Basename;
+
+               protected List<TypeContainer> containers;
+
+               TypeDefinition main_container;
+
+               protected Dictionary<string, MemberCore> defined_names;
+
+               protected bool is_defined;
+
+               public TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+                       : base (parent, name, attrs)
+               {
+                       this.Kind = kind;
+                       if (name != null)
+                               this.Basename = name.Basename;
+
+                       defined_names = new Dictionary<string, MemberCore> ();
+               }
+
+               public override TypeSpec CurrentType {
+                       get {
+                               return null;
+                       }
+               }
+
+               public Dictionary<string, MemberCore> DefinedNames {
+                       get {
+                               return defined_names;
+                       }
+               }
+
+               public TypeDefinition PartialContainer {
+                       get {
+                               return main_container;
+                       }
+                       protected set {
+                               main_container = value;
+                       }
+               }
+
+               public IList<TypeContainer> Containers {
+                       get {
+                               return containers;
+                       }
+               }
+
+               //
+               // Any unattached attributes during parsing get added here. User
+               // by FULL_AST mode
+               //
+               public Attributes UnattachedAttributes {
+                       get; set;
+               }
+
+               public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
+               {
+                       containers.Add (c);
+               }
+
+               public virtual void AddPartial (TypeDefinition next_part)
+               {
+                       MemberCore mc;
+                       (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
+
+                       AddPartial (next_part, mc as TypeDefinition);
+               }
+
+               protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
+               {
+                       next_part.ModFlags |= Modifiers.PARTIAL;
+
+                       if (existing == null) {
+                               AddTypeContainer (next_part);
+                               return;
+                       }
+
+                       if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
+                               if (existing.Kind != next_part.Kind) {
+                                       AddTypeContainer (next_part);
+                               } else {
+                                       Report.SymbolRelatedToPreviousError (next_part);
+                                       Error_MissingPartialModifier (existing);
+                               }
+
+                               return;
+                       }
+
+                       if (existing.Kind != next_part.Kind) {
+                               Report.SymbolRelatedToPreviousError (existing);
+                               Report.Error (261, next_part.Location,
+                                       "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
+                                       next_part.GetSignatureForError ());
+                       }
+
+                       if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
+                               ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
+                                (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
+                                        Report.SymbolRelatedToPreviousError (existing);
+                               Report.Error (262, next_part.Location,
+                                       "Partial declarations of `{0}' have conflicting accessibility modifiers",
+                                       next_part.GetSignatureForError ());
+                       }
+
+                       var tc_names = existing.CurrentTypeParameters;
+                       if (tc_names != null) {
+                               for (int i = 0; i < tc_names.Count; ++i) {
+                                       var tp = next_part.MemberName.TypeParameters[i];
+                                       if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
+                                               Report.SymbolRelatedToPreviousError (existing.Location, "");
+                                               Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
+                                                       next_part.GetSignatureForError ());
+                                               break;
+                                       }
+
+                                       if (tc_names[i].Variance != tp.Variance) {
+                                               Report.SymbolRelatedToPreviousError (existing.Location, "");
+                                               Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
+                                                       next_part.GetSignatureForError ());
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+                               existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
+                       } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+                               existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
+                               existing.ModFlags |= next_part.ModFlags;
+                       } else {
+                               existing.ModFlags |= next_part.ModFlags;
+                       }
+
+                       existing.Definition.Modifiers = existing.ModFlags;
+
+                       if (next_part.attributes != null) {
+                               if (existing.attributes == null)
+                                       existing.attributes = next_part.attributes;
+                               else
+                                       existing.attributes.AddAttributes (next_part.attributes.Attrs);
+                       }
+
+                       next_part.PartialContainer = existing;
+
+                       if (containers == null)
+                               containers = new List<TypeContainer> ();
+
+                       containers.Add (next_part);
+               }
+
+               public virtual void AddTypeContainer (TypeContainer tc)
+               {
+                       containers.Add (tc);
+
+                       var tparams = tc.MemberName.TypeParameters;
+                       if (tparams != null && tc.PartialContainer != null) {
+                               var td = (TypeDefinition) tc;
+                               for (int i = 0; i < tparams.Count; ++i) {
+                                       var tp = tparams[i];
+                                       if (tp.MemberName == null)
+                                               continue;
+
+                                       td.AddNameToContainer (tp, tp.Name);
+                               }
+                       }
+               }
+
+               public virtual void CloseContainer ()
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.CloseContainer ();
+                               }
+                       }
+               }
+
+               public virtual void CreateMetadataName (StringBuilder sb)
+               {
+                       if (Parent != null && Parent.MemberName != null)
+                               Parent.CreateMetadataName (sb);
+
+                       MemberName.CreateMetadataName (sb);
+               }
+
+               public virtual bool CreateContainer ()
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.CreateContainer ();
+                               }
+                       }
+
+                       return true;
+               }
+
+               public override bool Define ()
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.Define ();
+                               }
+                       }
+
+                       // Release cache used by parser only
+                       if (Module.Evaluator == null) {
+                               defined_names = null;
+                       } else {
+                               defined_names.Clear ();
+                       }
+
+                       return true;
+               }
+
+               public virtual void PrepareEmit ()
+               {
+                       if (containers != null) {
+                               foreach (var t in containers) {
+                                       try {
+                                               t.PrepareEmit ();
+                                       } catch (Exception e) {
+                                               if (MemberName == MemberName.Null)
+                                                       throw;
+
+                                               throw new InternalErrorException (t, e);
+                                       }
+                               }
+                       }
+               }
+
+               public virtual bool DefineContainer ()
+               {
+                       if (is_defined)
+                               return true;
+
+                       is_defined = true;
+
+                       DoDefineContainer ();
+
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       try {
+                                               tc.DefineContainer ();
+                                       } catch (Exception e) {
+                                               if (MemberName == MemberName.Null)
+                                                       throw;
+
+                                               throw new InternalErrorException (tc, e);
+                                       }
+                               }
+                       }
+
+                       return true;
+               }
+
+               public virtual void ExpandBaseInterfaces ()
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.ExpandBaseInterfaces ();
+                               }
+                       }
+               }
+
+               protected virtual void DefineNamespace ()
+               {
+                       if (containers != null) {
+                               foreach (var tc in containers) {
+                                       try {
+                                               tc.DefineNamespace ();
+                                       } catch (Exception e) {
+                                               throw new InternalErrorException (tc, e);
+                                       }
+                               }
+                       }
+               }
+
+               protected virtual void DoDefineContainer ()
+               {
+               }
+
+               public virtual void EmitContainer ()
+               {
+                       if (containers != null) {
+                               for (int i = 0; i < containers.Count; ++i)
+                                       containers[i].EmitContainer ();
+                       }
+               }
+
+               protected void Error_MissingPartialModifier (MemberCore type)
+               {
+                       Report.Error (260, type.Location,
+                               "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
+                               type.GetSignatureForError ());
+               }
+
+               public override string GetSignatureForDocumentation ()
+               {
+                       if (Parent != null && Parent.MemberName != null)
+                               return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
+
+                       return MemberName.GetSignatureForDocumentation ();
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       if (Parent != null && Parent.MemberName != null) 
+                               return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
+
+                       return MemberName.GetSignatureForError ();
+               }
+
+               public string GetSignatureForMetadata ()
+               {
+#if STATIC
+                       if (Parent is TypeDefinition) {
+                               return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
+                       }
+
+                       var sb = new StringBuilder ();
+                       CreateMetadataName (sb);
+                       return sb.ToString ();
+#else
+                       throw new NotImplementedException ();
+#endif
+               }
+
+               public virtual void RemoveContainer (TypeContainer cont)
+               {
+                       if (containers != null)
+                               containers.Remove (cont);
+
+                       var tc = Parent == Module ? Module : this;
+                       tc.defined_names.Remove (cont.Basename);
+               }
+
+               public virtual void VerifyMembers ()
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers)
+                                       tc.VerifyMembers ();
+                       }
+               }
+
+               public override void WriteDebugSymbol (MonoSymbolFile file)
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.WriteDebugSymbol (file);
+                               }
+                       }
+               }
        }
 
-       /// <summary>
-       ///   This is the base class for structs and classes.  
-       /// </summary>
-       public abstract class TypeContainer : MemberCore, ITypeDefinition, ITypesContainer
+       public abstract class TypeDefinition : TypeContainer, ITypeDefinition
        {
                //
                // Different context is needed when resolving type container base
@@ -135,24 +486,7 @@ namespace Mono.CSharp
                        HasStaticFieldInitializer       = 1 << 2
                }
 
-
-               // Whether this is a struct, class or interface
-               public readonly MemberKind Kind;
-
-               // Holds a list of classes and structures
-               protected List<TypeContainer> types;
-
-               List<MemberCore> ordered_explicit_member_list;
-               List<MemberCore> ordered_member_list;
-
-               // Holds the list of properties
-               List<MemberCore> properties;
-
-               // Holds the list of constructors
-               protected List<Constructor> instance_constructors;
-
-               // Holds the list of fields
-               protected List<FieldBase> fields;
+               readonly List<MemberCore> members;
 
                // Holds a list of fields that have initializers
                protected List<FieldInitializer> initialized_fields;
@@ -160,42 +494,17 @@ namespace Mono.CSharp
                // Holds a list of static fields that have initializers
                protected List<FieldInitializer> initialized_static_fields;
 
-               // Holds the list of constants
-               protected List<MemberCore> constants;
-
-               // Holds the methods.
-               List<MemberCore> methods;
-
-               // Holds the events
-               protected List<MemberCore> events;
-
-               // Holds the indexers
-               List<MemberCore> indexers;
-
-               // Holds the operators
-               List<MemberCore> operators;
-
-               // Holds the compiler generated classes
-               protected List<CompilerGeneratedClass> compiler_generated;
-
                Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
 
-               protected Dictionary<string, MemberCore> defined_names;
                Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
 
-               //
-               // Pointers to the default constructor and the default static constructor
-               //
-               protected Constructor default_constructor;
-               protected Constructor default_static_constructor;
-
                //
                // Points to the first non-static field added to the container.
                //
                // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
                // and the first one's as good as any.
                //
-               FieldBase first_nonstatic_field;
+               protected FieldBase first_nonstatic_field;
 
                //
                // This one is computed after we can distinguish interfaces
@@ -207,12 +516,7 @@ namespace Mono.CSharp
 
                protected List<FullNamedExpression> type_bases;
 
-               bool members_defined;
-               bool members_defined_ok;
-               bool type_defined;
-
-               TypeContainer InTransit;
-               public TypeContainer PartialContainer;
+               TypeDefinition InTransit;
 
                public TypeBuilder TypeBuilder;
                GenericTypeParameterBuilder[] all_tp_builders;
@@ -222,28 +526,24 @@ namespace Mono.CSharp
                //
                TypeParameters all_type_parameters;
 
-               //
-               // This is the namespace in which this typecontainer
-               // was declared.  We use this to resolve names.
-               //
-               public NamespaceContainer NamespaceEntry;
-
-               public readonly string Basename;
                public const string DefaultIndexerName = "Item";
 
-               private bool seen_normal_indexers = false;
-               private string indexer_name = DefaultIndexerName;
+               bool has_normal_indexers;
+               string indexer_name;
                protected bool requires_delayed_unmanagedtype_check;
                bool error;
+               bool members_defined;
+               bool members_defined_ok;
+               protected bool has_static_constructor;
 
                private CachedMethods cached_method;
 
                protected TypeSpec spec;
                TypeSpec current_type;
 
-               List<TypeContainer> partial_parts;
-
                public int DynamicSitesCounter;
+               public int AnonymousMethodsCounter;
+               public int MethodGroupsCounter;
 
                static readonly string[] attribute_targets = new string[] { "type" };
 
@@ -253,18 +553,11 @@ namespace Mono.CSharp
                /// </remarks>
                PendingImplementation pending;
 
-               public TypeContainer (NamespaceContainer ns, TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
-                       : base (parent, name, attrs)
+               public TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+                       : base (parent, name, attrs, kind)
                {
-                       if (parent != null && parent.NamespaceEntry != ns)
-                               throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
-
-                       this.Kind = kind;
-                       this.PartialContainer = this;
-                       this.Basename = name.Basename;
-                       this.NamespaceEntry = ns;
-
-                       defined_names = new Dictionary<string, MemberCore> ();
+                       PartialContainer = this;
+                       members = new List<MemberCore> ();
                }
 
                #region Properties
@@ -317,48 +610,109 @@ namespace Mono.CSharp
 
                IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
                        get {
-                               return Module.DeclaringAssembly;
+                               return Module.DeclaringAssembly;
+                       }
+               }
+
+               public TypeSpec Definition {
+                       get {
+                               return spec;
+                       }
+               }
+
+               public bool HasMembersDefined {
+                       get {
+                               return members_defined;
+                       }
+               }
+
+               public bool HasInstanceConstructor {
+                       get {
+                               return (caching_flags & Flags.HasInstanceConstructor) != 0;
+                       }
+                       set {
+                               caching_flags |= Flags.HasInstanceConstructor;
+                       }
+               }
+
+               // Indicated whether container has StructLayout attribute set Explicit
+               public bool HasExplicitLayout {
+                       get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
+                       set { caching_flags |= Flags.HasExplicitLayout; }
+               }
+
+               public bool HasOperators {
+                       get {
+                               return (caching_flags & Flags.HasUserOperators) != 0;
+                       }
+                       set {
+                               caching_flags |= Flags.HasUserOperators;
+                       }
+               }
+
+               public bool HasStructLayout {
+                       get { return (caching_flags & Flags.HasStructLayout) != 0; }
+                       set { caching_flags |= Flags.HasStructLayout; }
+               }
+
+               public TypeSpec[] Interfaces {
+                       get {
+                               return iface_exprs;
+                       }
+               }
+
+               public bool IsGenericOrParentIsGeneric {
+                       get {
+                               return all_type_parameters != null;
+                       }
+               }
+
+               public bool IsTopLevel {
+                       get {
+                               return !(Parent is TypeDefinition);
                        }
                }
 
-               public TypeSpec Definition {
+               public bool IsPartial {
                        get {
-                               return spec;
+                               return (ModFlags & Modifiers.PARTIAL) != 0;
                        }
                }
 
-               public bool HasMembersDefined {
+               bool ITypeDefinition.IsTypeForwarder {
                        get {
-                               return members_defined;
+                               return false;
                        }
                }
 
-               public TypeSpec[] Interfaces {
+               //
+               // Returns true for secondary partial containers
+               //
+               bool IsPartialPart {
                        get {
-                               return iface_exprs;
+                               return PartialContainer != this;
                        }
                }
 
-               public bool IsGenericOrParentIsGeneric {
+               public MemberCache MemberCache {
                        get {
-                               return all_type_parameters != null;
+                               return spec.MemberCache;
                        }
                }
 
-               // 
-               // root_types contains all the types.  All TopLevel types
-               // hence have a parent that points to `root_types', that is
-               // why there is a non-obvious test down here.
-               //
-               public bool IsTopLevel {
+               public List<MemberCore> Members {
                        get {
-                               return Parent != null && Parent.Parent == null;
+                               return members;
                        }
                }
 
                string ITypeDefinition.Namespace {
                        get {
-                               return NamespaceEntry.NS.MemberName.GetSignatureForError ();
+                               var p = Parent;
+                               while (p.Kind != MemberKind.Namespace)
+                                       p = p.Parent;
+
+                               return p.MemberName == null ? null : p.GetSignatureForError ();
                        }
                }
 
@@ -381,62 +735,66 @@ namespace Mono.CSharp
                        visitor.Visit (this);
                }
 
-               public bool AddMember (MemberCore symbol)
+               public void AddMember (MemberCore symbol)
                {
-                       return AddToContainer (symbol, symbol.MemberName.Basename);
-               }
+                       if (symbol.MemberName.ExplicitInterface != null) {
+                               if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
+                                       Report.Error (541, symbol.Location,
+                                               "`{0}': explicit interface declaration can only be declared in a class or struct",
+                                               symbol.GetSignatureForError ());
+                               }
+                       }
 
-               public bool AddMember (MemberCore symbol, string name)
-               {
-                       return AddToContainer (symbol, name);
+                       AddNameToContainer (symbol, symbol.MemberName.Basename);
+                       members.Add (symbol);
                }
 
-               protected virtual bool AddMemberType (TypeContainer ds)
+               public override void AddTypeContainer (TypeContainer tc)
                {
-                       return AddToContainer (ds, ds.Basename);
-               }
+                       AddNameToContainer (tc, tc.Basename);
 
-               protected virtual void RemoveMemberType (TypeContainer ds)
-               {
-                       defined_names.Remove (ds.Basename);
+                       if (containers == null)
+                               containers = new List<TypeContainer> ();
+
+                       members.Add (tc);
+                       base.AddTypeContainer (tc);
                }
 
-               public void AddConstant (Const constant)
+               public override void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
                {
-                       if (!AddMember (constant))
-                               return;
+                       members.Add (c);
 
-                       if (constants == null)
-                               constants = new List<MemberCore> ();
-                       
-                       constants.Add (constant);
+                       if (containers == null)
+                               containers = new List<TypeContainer> ();
+
+                       base.AddCompilerGeneratedClass (c);
                }
 
                //
                // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
                //
-               protected virtual bool AddToContainer (MemberCore symbol, string name)
+               public virtual void AddNameToContainer (MemberCore symbol, string name)
                {
+                       if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
+                               return;
+
                        MemberCore mc;
-                       if (!defined_names.TryGetValue (name, out mc)) {
-                               defined_names.Add (name, symbol);
-                               return true;
+                       if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
+                               PartialContainer.defined_names.Add (name, symbol);
+                               return;
                        }
 
-                       if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
-                               return true;
-
                        if (symbol.EnableOverloadChecks (mc))
-                               return true;
+                               return;
 
                        InterfaceMemberBase im = mc as InterfaceMemberBase;
                        if (im != null && im.IsExplicitImpl)
-                               return true;
+                               return;
 
                        Report.SymbolRelatedToPreviousError (mc);
                        if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
                                Error_MissingPartialModifier (symbol);
-                               return false;
+                               return;
                        }
 
                        if (symbol is TypeParameter) {
@@ -448,272 +806,70 @@ namespace Mono.CSharp
                                        GetSignatureForError (), name);
                        }
 
-                       return false;
-               }
-
-               public TypeContainer AddTypeContainer (TypeContainer tc)
-               {
-                       if (!AddMemberType (tc))
-                               return tc;
-
-                       var tparams = tc.MemberName.TypeParameters;
-                       if (tparams != null) {
-                               for (int i = 0; i < tparams.Count; ++i) {
-                                       var tp = tparams[i];
-                                       if (tp.MemberName == null)
-                                               continue;
-
-                                       tc.AddMember (tp, tp.Name);
-                               }
-                       }
-
-                       if (types == null)
-                               types = new List<TypeContainer> ();
-
-                       types.Add (tc);
-                       return tc;
-               }
-
-               public virtual TypeContainer AddPartial (TypeContainer next_part)
-               {
-                       return AddPartial (next_part, next_part.Basename);
-               }
-
-               protected TypeContainer AddPartial (TypeContainer next_part, string name)
-               {
-                       next_part.ModFlags |= Modifiers.PARTIAL;
-                       TypeContainer tc = GetDefinition (name) as TypeContainer;
-                       if (tc == null)
-                               return AddTypeContainer (next_part);
-
-                       if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
-                               Report.SymbolRelatedToPreviousError (next_part);
-                               Error_MissingPartialModifier (tc);
-                       }
-
-                       if (tc.Kind != next_part.Kind) {
-                               Report.SymbolRelatedToPreviousError (tc);
-                               Report.Error (261, next_part.Location,
-                                       "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
-                                       next_part.GetSignatureForError ());
-                       }
-
-                       if ((tc.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
-                               ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
-                                (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
-                               Report.SymbolRelatedToPreviousError (tc);
-                               Report.Error (262, next_part.Location,
-                                       "Partial declarations of `{0}' have conflicting accessibility modifiers",
-                                       next_part.GetSignatureForError ());
-                       }
-
-                       var tc_names = tc.CurrentTypeParameters;
-                       if (tc_names != null) {
-                               for (int i = 0; i < tc_names.Count; ++i) {
-                                       var tp = next_part.MemberName.TypeParameters[i];
-                                       if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
-                                               Report.SymbolRelatedToPreviousError (tc.Location, "");
-                                               Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
-                                                       next_part.GetSignatureForError ());
-                                               break;
-                                       }
-
-                                       if (tc_names[i].Variance != tp.Variance) {
-                                               Report.SymbolRelatedToPreviousError (tc.Location, "");
-                                               Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
-                                                       next_part.GetSignatureForError ());
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if (tc.partial_parts == null)
-                               tc.partial_parts = new List<TypeContainer> (1);
-
-                       if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
-                               tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
-                       } else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
-                               tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
-                               tc.ModFlags |= next_part.ModFlags;
-                       } else {
-                               tc.ModFlags |= next_part.ModFlags;
-                       }
-
-                       tc.spec.Modifiers = tc.ModFlags;
-
-                       if (next_part.attributes != null) {
-                               if (tc.attributes == null)
-                                       tc.attributes = next_part.attributes;
-                               else
-                                       tc.attributes.AddAttributes (next_part.attributes.Attrs);
-                       }
-
-                       next_part.PartialContainer = tc;
-                       tc.partial_parts.Add (next_part);
-                       return tc;
-               }
-
-               public virtual void RemoveTypeContainer (TypeContainer next_part)
-               {
-                       if (types != null)
-                               types.Remove (next_part);
-
-                       Cache.Remove (next_part.Basename);
-                       RemoveMemberType (next_part);
-               }
-               
-               public void AddDelegate (Delegate d)
-               {
-                       AddTypeContainer (d);
-               }
-
-               private void AddMemberToList (InterfaceMemberBase mc, List<MemberCore> alist)
-               {
-                       if (ordered_explicit_member_list == null)  {
-                               ordered_explicit_member_list = new List<MemberCore> ();
-                               ordered_member_list = new List<MemberCore> ();
-                       }
-
-                       if (mc.IsExplicitImpl) {
-                               if (Kind == MemberKind.Interface) {
-                                       Report.Error (541, mc.Location,
-                                               "`{0}': explicit interface declaration can only be declared in a class or struct",
-                                               mc.GetSignatureForError ());
-                               }
-
-                               ordered_explicit_member_list.Add (mc);
-                               alist.Insert (0, mc);
-                       } else {
-                               ordered_member_list.Add (mc);
-                               alist.Add (mc);
-                       }
-
+                       return;
                }
-               
-               public void AddMethod (MethodOrOperator method)
+       
+               public void AddConstructor (Constructor c)
                {
-                       if (!AddToContainer (method, method.MemberName.Basename))
-                               return;
-                       
-                       if (methods == null)
-                               methods = new List<MemberCore> ();
-
-                       AddMemberToList (method, methods);
+                       AddConstructor (c, false);
                }
 
-               public void AddConstructor (Constructor c)
+               public void AddConstructor (Constructor c, bool isDefault)
                {
                        bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
-                       if (!AddToContainer (c, is_static ? Constructor.ConstructorName : Constructor.TypeConstructorName))
-                               return;
-                       
-                       if (is_static && c.ParameterInfo.IsEmpty){
-                               if (default_static_constructor != null) {
-                                   Report.SymbolRelatedToPreviousError (default_static_constructor);
-                                       Report.Error (111, c.Location,
-                                               "A member `{0}' is already defined. Rename this member or use different parameter types",
-                                               c.GetSignatureForError ());
-                                   return;
-                               }
+                       if (!isDefault)
+                               AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
 
-                               default_static_constructor = c;
+                       if (is_static && c.ParameterInfo.IsEmpty) {
+                               PartialContainer.has_static_constructor = true;
                        } else {
-                               if (c.ParameterInfo.IsEmpty)
-                                       default_constructor = c;
-                               
-                               if (instance_constructors == null)
-                                       instance_constructors = new List<Constructor> ();
-                               
-                               instance_constructors.Add (c);
+                               PartialContainer.HasInstanceConstructor = true;
                        }
+
+                       members.Add (c);
                }
 
                public bool AddField (FieldBase field)
                {
-                       if (!AddMember (field))
-                               return false;
-
-                       if (fields == null)
-                               fields = new List<FieldBase> ();
-
-                       fields.Add (field);
+                       AddMember (field);
 
                        if ((field.ModFlags & Modifiers.STATIC) != 0)
                                return true;
 
-                       if (first_nonstatic_field == null) {
-                               first_nonstatic_field = field;
+                       var first_field = PartialContainer.first_nonstatic_field;
+                       if (first_field == null) {
+                               PartialContainer.first_nonstatic_field = field;
                                return true;
                        }
 
-                       if (Kind == MemberKind.Struct && first_nonstatic_field.Parent != field.Parent) {
-                               Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
+                       if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
+                               Report.SymbolRelatedToPreviousError (first_field.Parent);
                                Report.Warning (282, 3, field.Location,
                                        "struct instance field `{0}' found in different declaration from instance field `{1}'",
-                                       field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
+                                       field.GetSignatureForError (), first_field.GetSignatureForError ());
                        }
                        return true;
                }
 
-               public void AddProperty (Property prop)
-               {
-                       if (!AddMember (prop))
-                               return;
-
-                       if (properties == null)
-                               properties = new List<MemberCore> ();
-
-                       AddMemberToList (prop, properties);
-               }
-
-               public void AddEvent (Event e)
-               {
-                       if (!AddMember (e))
-                               return;
-
-                       if (events == null)
-                               events = new List<MemberCore> ();
-
-                       events.Add (e);
-               }
-
                /// <summary>
                /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
                /// </summary>
                public void AddIndexer (Indexer i)
                {
-                       if (indexers == null)
-                               indexers = new List<MemberCore> ();
-
-                       AddMemberToList (i, indexers);
+                       members.Add (i);
                }
 
                public void AddOperator (Operator op)
                {
-                       if (!AddMember (op))
-                               return;
-
-                       if (operators == null)
-                               operators = new List<MemberCore> ();
-
-                       operators.Add (op);
-               }
-
-               public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
-               {
-                       if (compiler_generated == null)
-                               compiler_generated = new List<CompilerGeneratedClass> ();
-
-                       compiler_generated.Add (c);
+                       PartialContainer.HasOperators = true;
+                       AddMember (op);
                }
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
-                       if (a.Type == pa.DefaultMember) {
-                               if (Indexers != null) {
-                                       Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
-                                       return;
-                               }
+                       if (has_normal_indexers && a.Type == pa.DefaultMember) {
+                               Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
+                               return;
                        }
 
                        if (a.Type == pa.Required) {
@@ -730,66 +886,12 @@ namespace Mono.CSharp
                        }
                }
 
-               public IList<TypeContainer> Types {
-                       get {
-                               return types;
-                       }
-               }
-
-               public IList<MemberCore> Methods {
-                       get {
-                               return methods;
-                       }
-               }
-
-               public IList<MemberCore> Constants {
-                       get {
-                               return constants;
-                       }
-               }
-
                public TypeSpec BaseType {
                        get {
                                return spec.BaseType;
                        }
                }
 
-               public IList<FieldBase> Fields {
-                       get {
-                               return fields;
-                       }
-               }
-
-               public IList<Constructor> InstanceConstructors {
-                       get {
-                               return instance_constructors;
-                       }
-               }
-
-               public IList<MemberCore> Properties {
-                       get {
-                               return properties;
-                       }
-               }
-
-               public IList<MemberCore> Events {
-                       get {
-                               return events;
-                       }
-               }
-               
-               public IList<MemberCore> Indexers {
-                       get {
-                               return indexers;
-                       }
-               }
-
-               public IList<MemberCore> Operators {
-                       get {
-                               return operators;
-                       }
-               }
-
                protected virtual TypeAttributes TypeAttr {
                        get {
                                return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
@@ -810,7 +912,7 @@ namespace Mono.CSharp
 
                public string GetAttributeDefaultMember ()
                {
-                       return indexers == null ? DefaultIndexerName : indexer_name;
+                       return indexer_name ?? DefaultIndexerName;
                }
 
                public bool IsComImport {
@@ -824,9 +926,12 @@ namespace Mono.CSharp
 
                public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
                {
+                       if (IsPartialPart)
+                               PartialContainer.RegisterFieldForInitialization (field, expression);
+
                        if ((field.ModFlags & Modifiers.STATIC) != 0){
                                if (initialized_static_fields == null) {
-                                       PartialContainer.HasStaticFieldInitializer = true;
+                                       HasStaticFieldInitializer = true;
                                        initialized_static_fields = new List<FieldInitializer> (4);
                                }
 
@@ -841,16 +946,8 @@ namespace Mono.CSharp
 
                public void ResolveFieldInitializers (BlockContext ec)
                {
-                       if (partial_parts != null) {
-                               foreach (TypeContainer part in partial_parts) {
-                                       part.DoResolveFieldInitializers (ec);
-                               }
-                       }
-                       DoResolveFieldInitializers (ec);
-               }
+                       Debug.Assert (!IsPartialPart);
 
-               void DoResolveFieldInitializers (BlockContext ec)
-               {
                        if (ec.IsStatic) {
                                if (initialized_static_fields == null)
                                        return;
@@ -923,46 +1020,13 @@ namespace Mono.CSharp
 
                internal override void GenerateDocComment (DocumentationBuilder builder)
                {
-                       base.GenerateDocComment (builder);
-
-                       if (DefaultStaticConstructor != null)
-                               DefaultStaticConstructor.GenerateDocComment (builder);
-
-                       if (InstanceConstructors != null)
-                               foreach (Constructor c in InstanceConstructors)
-                                       c.GenerateDocComment (builder);
-
-                       if (Types != null)
-                               foreach (TypeContainer tc in Types)
-                                       tc.GenerateDocComment (builder);
-
-                       if (Constants != null)
-                               foreach (Const c in Constants)
-                                       c.GenerateDocComment (builder);
-
-                       if (Fields != null)
-                               foreach (FieldBase f in Fields)
-                                       f.GenerateDocComment (builder);
-
-                       if (Events != null)
-                               foreach (Event e in Events)
-                                       e.GenerateDocComment (builder);
-
-                       if (Indexers != null)
-                               foreach (Indexer ix in Indexers)
-                                       ix.GenerateDocComment (builder);
-
-                       if (Properties != null)
-                               foreach (Property p in Properties)
-                                       p.GenerateDocComment (builder);
+                       if (IsPartialPart)
+                               return;
 
-                       if (Methods != null)
-                               foreach (MethodOrOperator m in Methods)
-                                       m.GenerateDocComment (builder);
+                       base.GenerateDocComment (builder);
 
-                       if (Operators != null)
-                               foreach (Operator o in Operators)
-                                       o.GenerateDocComment (builder);
+                       foreach (var member in members)
+                               member.GenerateDocComment (builder);
                }
 
                public TypeSpec GetAttributeCoClass ()
@@ -990,9 +1054,21 @@ namespace Mono.CSharp
                        return a.GetAttributeUsageAttribute ();
                }
 
-               public virtual void AddBasesForPart (TypeContainer part, List<FullNamedExpression> bases)
+               public virtual CompilationSourceFile GetCompilationSourceFile ()
+               {
+                       TypeContainer ns = Parent;
+                       while (true) {
+                               var sf = ns as CompilationSourceFile;
+                               if (sf != null)
+                                       return sf;
+
+                               ns = ns.Parent;
+                       }
+               }
+
+               public virtual void AddBasesForPart (List<FullNamedExpression> bases)
                {
-                       part.type_bases = bases;
+                       type_bases = bases;
                }
 
                /// <summary>
@@ -1065,70 +1141,9 @@ namespace Mono.CSharp
                                }
 
                                ifaces [j++] = fne_resolved;
-                       }
-
-                       return ifaces;
-               }
-
-               //
-               // Returns the MemberCore associated with a given name in the declaration
-               // space. It doesn't return method based symbols !!
-               //
-               // TODO: protected or private
-               //
-               public MemberCore GetDefinition (string name)
-               {
-                       MemberCore mc = null;
-                       defined_names.TryGetValue (name, out mc);
-                       return mc;
-               }
-
-               TypeSpec[] GetNormalPartialBases ()
-               {
-                       var ifaces = new List<TypeSpec> (0);
-                       if (iface_exprs != null)
-                               ifaces.AddRange (iface_exprs);
-
-                       foreach (TypeContainer part in partial_parts) {
-                               FullNamedExpression new_base_class;
-                               var new_ifaces = part.ResolveBaseTypes (out new_base_class);
-                               if (new_base_class != null) {
-                                       if (base_type_expr != null && part.base_type != base_type) {
-                                               Report.SymbolRelatedToPreviousError (new_base_class.Location, "");
-                                               Report.Error (263, part.Location,
-                                                       "Partial declarations of `{0}' must not specify different base classes",
-                                                       part.GetSignatureForError ());
-                                       } else {
-                                               base_type_expr = new_base_class;
-                                               base_type = part.base_type;
-                                       }
-                               }
-
-                               if (new_ifaces == null)
-                                       continue;
-
-                               foreach (var iface in new_ifaces) {
-                                       if (ifaces.Contains (iface))
-                                               continue;
-
-                                       ifaces.Add (iface);
-                               }
-                       }
-
-                       if (ifaces.Count == 0)
-                               return null;
-
-                       return ifaces.ToArray ();
-               }
-
-               public override string GetSignatureForDocumentation ()
-               {
-                       return MemberName.GetName (true);
-               }
-
-               public override string GetSignatureForError ()
-               {
-                       return MemberName.GetSignatureForError ();
+                       }
+
+                       return ifaces;
                }
 
                //
@@ -1143,26 +1158,28 @@ namespace Mono.CSharp
                void CheckPairedOperators ()
                {
                        bool has_equality_or_inequality = false;
-                       var operators = this.operators.ToArray ();
-                       bool[] has_pair = new bool[operators.Length];
+                       List<Operator.OpType> found_matched = new List<Operator.OpType> ();
 
-                       for (int i = 0; i < operators.Length; ++i) {
-                               if (operators[i] == null)
+                       for (int i = 0; i < members.Count; ++i) {
+                               var o_a = members[i] as Operator;
+                               if (o_a == null)
                                        continue;
 
-                               Operator o_a = (Operator) operators[i];
-                               Operator.OpType o_type = o_a.OperatorType;
+                               var o_type = o_a.OperatorType;
                                if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
                                        has_equality_or_inequality = true;
 
-                               Operator.OpType matching_type = o_a.GetMatchingOperator ();
+                               if (found_matched.Contains (o_type))
+                                       continue;
+
+                               var matching_type = o_a.GetMatchingOperator ();
                                if (matching_type == Operator.OpType.TOP) {
-                                       operators[i] = null;
                                        continue;
                                }
 
-                               for (int ii = 0; ii < operators.Length; ++ii) {
-                                       Operator o_b = (Operator) operators[ii];
+                               bool pair_found = false;
+                               for (int ii = i + 1; ii < members.Count; ++ii) {
+                                       var o_b = members[ii] as Operator;
                                        if (o_b == null || o_b.OperatorType != matching_type)
                                                continue;
 
@@ -1172,47 +1189,56 @@ namespace Mono.CSharp
                                        if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
                                                continue;
 
-                                       operators[i] = null;
-
-                                       //
-                                       // Used to ignore duplicate user conversions
-                                       //
-                                       has_pair[ii] = true;
+                                       found_matched.Add (matching_type);
+                                       pair_found = true;
+                                       break;
                                }
-                       }
-
-                       for (int i = 0; i < operators.Length; ++i) {
-                               if (operators[i] == null || has_pair[i])
-                                       continue;
 
-                               Operator o = (Operator) operators [i];
-                               Report.Error (216, o.Location,
-                                       "The operator `{0}' requires a matching operator `{1}' to also be defined",
-                                       o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ()));
+                               if (!pair_found) {
+                                       Report.Error (216, o_a.Location,
+                                               "The operator `{0}' requires a matching operator `{1}' to also be defined",
+                                               o_a.GetSignatureForError (), Operator.GetName (matching_type));
+                               }
                        }
 
                        if (has_equality_or_inequality) {
-                               if (Methods == null || !HasEquals)
+                               if (!HasEquals)
                                        Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
                                                GetSignatureForError ());
 
-                               if (Methods == null || !HasGetHashCode)
+                               if (!HasGetHashCode)
                                        Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
                                                GetSignatureForError ());
                        }
                }
+
+               public override void CreateMetadataName (StringBuilder sb)
+               {
+                       if (Parent.MemberName != null) {
+                               Parent.CreateMetadataName (sb);
+
+                               if (sb.Length != 0) {
+                                       sb.Append (".");
+                               }
+                       }
+
+                       sb.Append (MemberName.Basename);
+               }
        
                bool CreateTypeBuilder ()
                {
                        //
                        // Sets .size to 1 for structs with no instance fields
                        //
-                       int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
+                       int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
 
-                       if (IsTopLevel) {
-                               TypeBuilder = Module.CreateBuilder (MemberName.GetName (true), TypeAttr, type_size);
+                       var parent_def = Parent as TypeDefinition;
+                       if (parent_def == null) {
+                               var sb = new StringBuilder ();
+                               CreateMetadataName (sb);
+                               TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
                        } else {
-                               TypeBuilder = Parent.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
+                               TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
                        }
 
                        if (DeclaringAssembly.Importer != null)
@@ -1220,13 +1246,16 @@ namespace Mono.CSharp
 
                        spec.SetMetaInfo (TypeBuilder);
                        spec.MemberCache = new MemberCache (this);
-                       spec.DeclaringType = Parent.CurrentType;
 
-                       if (!IsTopLevel)
-                               Parent.MemberCache.AddMember (spec);
+                       TypeParameters parentAllTypeParameters = null;
+                       if (parent_def != null) {
+                               spec.DeclaringType = Parent.CurrentType;
+                               parent_def.MemberCache.AddMember (spec);
+                               parentAllTypeParameters = parent_def.all_type_parameters;
+                       }
 
-                       if (MemberName.TypeParameters != null || Parent.IsGenericOrParentIsGeneric) {
-                               var tparam_names = CreateTypeParameters ();
+                       if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
+                               var tparam_names = CreateTypeParameters (parentAllTypeParameters);
 
                                all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
 
@@ -1237,20 +1266,19 @@ namespace Mono.CSharp
                        return true;
                }
 
-               string[] CreateTypeParameters ()
+               string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
                {
                        string[] names;
                        int parent_offset = 0;
-                       var parent_all = Parent.all_type_parameters;
-                       if (parent_all != null) {
+                       if (parentAllTypeParameters != null) {
                                if (CurrentTypeParameters == null) {
-                                       all_type_parameters = Parent.all_type_parameters;
-                                       return Parent.all_tp_builders.Select (l => l.Name).ToArray ();
+                                       all_type_parameters = parentAllTypeParameters;
+                                       return parentAllTypeParameters.GetAllNames ();
                                }
 
-                               names = new string[parent_all.Count + CurrentTypeParameters.Count];
+                               names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
                                all_type_parameters = new TypeParameters (names.Length);
-                               all_type_parameters.Add (Parent.all_type_parameters);
+                               all_type_parameters.Add (parentAllTypeParameters);
 
                                parent_offset = all_type_parameters.Count;
                                for (int i = 0; i < parent_offset; ++i)
@@ -1284,6 +1312,18 @@ namespace Mono.CSharp
                }
 
 
+               public SourceMethodBuilder CreateMethodSymbolEntry ()
+               {
+                       if (Module.DeclaringAssembly.SymbolWriter == null)
+                               return null;
+
+                       var source_file = GetCompilationSourceFile ();
+                       if (source_file == null)
+                               return null;
+
+                       return new SourceMethodBuilder (source_file.SymbolUnitEntry);
+               }
+
                //
                // Creates a proxy base method call inside this container for hoisted base member calls
                //
@@ -1302,23 +1342,13 @@ namespace Mono.CSharp
                        }
 
                        if (proxy_method == null) {
-                               string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
-                               var base_parameters = new Parameter[method.Parameters.Count];
-                               for (int i = 0; i < base_parameters.Length; ++i) {
-                                       var base_param = method.Parameters.FixedParameters[i];
-                                       base_parameters[i] = new Parameter (new TypeExpression (method.Parameters.Types[i], Location),
-                                               base_param.Name, base_param.ModFlags, null, Location);
-                                       base_parameters[i].Resolve (this, i);
-                               }
-
-                               var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
-                               if (method.Parameters.HasArglist) {
-                                       cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
-                                       cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
-                               }
+                               string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
 
                                MemberName member_name;
                                TypeArguments targs = null;
+                               TypeSpec return_type = method.ReturnType;
+                               var local_param_types = method.Parameters.Types;
+
                                if (method.IsGeneric) {
                                        //
                                        // Copy all base generic method type parameters info
@@ -1330,23 +1360,48 @@ namespace Mono.CSharp
                                        targs.Arguments = new TypeSpec[hoisted_tparams.Length];
                                        for (int i = 0; i < hoisted_tparams.Length; ++i) {
                                                var tp = hoisted_tparams[i];
-                                               tparams.Add (new TypeParameter (tp, null, new MemberName (tp.Name, Location), null));
+                                               var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
+                                               tparams.Add (local_tp);
 
                                                targs.Add (new SimpleName (tp.Name, Location));
-                                               targs.Arguments[i] = tp;
+                                               targs.Arguments[i] = local_tp.Type;
                                        }
 
                                        member_name = new MemberName (name, tparams, Location);
+
+                                       //
+                                       // Mutate any method type parameters from original
+                                       // to newly created hoisted version
+                                       //
+                                       var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
+                                       return_type = mutator.Mutate (return_type);
+                                       local_param_types = mutator.Mutate (local_param_types);
                                } else {
                                        member_name = new MemberName (name);
                                }
 
+                               var base_parameters = new Parameter[method.Parameters.Count];
+                               for (int i = 0; i < base_parameters.Length; ++i) {
+                                       var base_param = method.Parameters.FixedParameters[i];
+                                       base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
+                                               base_param.Name, base_param.ModFlags, null, Location);
+                                       base_parameters[i].Resolve (this, i);
+                               }
+
+                               var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
+                               if (method.Parameters.HasArglist) {
+                                       cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
+                                       cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
+                               }
+
                                // Compiler generated proxy
-                               proxy_method = new Method (this, new TypeExpression (method.ReturnType, Location),
+                               proxy_method = new Method (this, new TypeExpression (return_type, Location),
                                        Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
                                        member_name, cloned_params, null);
 
-                               var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location);
+                               var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
+                                       IsCompilerGenerated = true
+                               };
 
                                var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
                                mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
@@ -1364,7 +1419,7 @@ namespace Mono.CSharp
                                block.AddStatement (statement);
                                proxy_method.Block = block;
 
-                               methods.Add (proxy_method);
+                               members.Add (proxy_method);
                                proxy_method.Define ();
 
                                hoisted_base_call_proxies.Add (method, proxy_method);
@@ -1373,11 +1428,55 @@ namespace Mono.CSharp
                        return proxy_method.Spec;
                }
 
-               bool DefineBaseTypes ()
+               protected bool DefineBaseTypes ()
                {
                        iface_exprs = ResolveBaseTypes (out base_type_expr);
-                       if (partial_parts != null) {
-                               iface_exprs = GetNormalPartialBases ();
+                       bool set_base_type;
+
+                       if (IsPartialPart) {
+                               set_base_type = false;
+
+                               if (base_type_expr != null) {
+                                       if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
+                                               Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
+                                               Report.Error (263, Location,
+                                                       "Partial declarations of `{0}' must not specify different base classes",
+                                                       GetSignatureForError ());
+                                       } else {
+                                               PartialContainer.base_type_expr = base_type_expr;
+                                               PartialContainer.base_type = base_type;
+                                               set_base_type = true;
+                                       }
+                               }
+
+                               if (iface_exprs != null) {
+                                       if (PartialContainer.iface_exprs == null)
+                                               PartialContainer.iface_exprs = iface_exprs;
+                                       else {
+                                               var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
+                                               foreach (var iface_partial in iface_exprs) {
+                                                       if (ifaces.Contains (iface_partial))
+                                                               continue;
+
+                                                       ifaces.Add (iface_partial);
+                                               }
+
+                                               PartialContainer.iface_exprs = ifaces.ToArray ();
+                                       }
+                               }
+
+                               PartialContainer.members.AddRange (members);
+                               if (containers != null) {
+                                       if (PartialContainer.containers == null)
+                                               PartialContainer.containers = new List<TypeContainer> ();
+
+                                       PartialContainer.containers.AddRange (containers);
+                               }
+
+                               members_defined = members_defined_ok = true;
+                               caching_flags |= Flags.CloseTypeCreated;
+                       } else {
+                               set_base_type = true;
                        }
 
                        var cycle = CheckRecursiveDefinition (this);
@@ -1389,12 +1488,14 @@ namespace Mono.CSharp
                                            GetSignatureForError (), cycle.GetSignatureForError ());
 
                                        iface_exprs = null;
+                                       PartialContainer.iface_exprs = null;
                                } else {
                                        Report.Error (146, Location,
                                                "Circular base class dependency involving `{0}' and `{1}'",
                                                GetSignatureForError (), cycle.GetSignatureForError ());
 
                                        base_type = null;
+                                       PartialContainer.base_type = null;
                                }
                        }
 
@@ -1408,26 +1509,6 @@ namespace Mono.CSharp
                                                continue;
 
                                        TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
-
-                                       // Ensure the base is always setup
-                                       var compiled_iface = iface_type.MemberDefinition as Interface;
-                                       if (compiled_iface != null) {
-                                               // TODO: Need DefineBaseType only
-                                               compiled_iface.DefineType ();
-                                       }
-
-                                       if (iface_type.Interfaces != null) {
-                                               var base_ifaces = new List<TypeSpec> (iface_type.Interfaces);
-                                               for (int i = 0; i < base_ifaces.Count; ++i) {
-                                                       var ii_iface_type = base_ifaces[i];
-                                                       if (spec.AddInterfaceDefined (ii_iface_type)) {
-                                                               TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ());
-
-                                                               if (ii_iface_type.Interfaces != null)
-                                                                       base_ifaces.AddRange (ii_iface_type.Interfaces);
-                                                       }
-                                               }
-                                       }
                                }
                        }
 
@@ -1436,60 +1517,112 @@ namespace Mono.CSharp
                                return true;
                        }
 
-                       if (base_type != null) {
-                               spec.BaseType = base_type;
+                       if (set_base_type) {
+                               if (base_type != null) {
+                                       spec.BaseType = base_type;
 
-                               // Set base type after type creation
-                               TypeBuilder.SetParent (base_type.GetMetaInfo ());
-                       } else {
-                               TypeBuilder.SetParent (null);
+                                       // Set base type after type creation
+                                       TypeBuilder.SetParent (base_type.GetMetaInfo ());
+                               } else {
+                                       TypeBuilder.SetParent (null);
+                               }
                        }
 
                        return true;
                }
 
-               public virtual void DefineConstants ()
+               public override void ExpandBaseInterfaces ()
                {
-                       if (constants != null) {
-                               foreach (Const c in constants) {
-                                       c.DefineValue ();
-                               }
-                       }
+                       if (!IsPartialPart)
+                               DoExpandBaseInterfaces ();
+
+                       base.ExpandBaseInterfaces ();
+               }
+
+               public void DoExpandBaseInterfaces ()
+               {
+                       if ((caching_flags & Flags.InterfacesExpanded) != 0)
+                               return;
+
+                       caching_flags |= Flags.InterfacesExpanded;
+
+                       //
+                       // Expand base interfaces. It cannot be done earlier because all partial
+                       // interface parts need to be defined before the type they are used from
+                       //
+                       if (iface_exprs != null) {
+                               foreach (var iface in iface_exprs) {
+                                       if (iface == null)
+                                               continue;
 
-                       if (instance_constructors != null) {
-                               foreach (MethodCore m in instance_constructors) {
-                                       var p = m.ParameterInfo;
-                                       if (!p.IsEmpty) {
-                                               p.ResolveDefaultValues (m);
+                                       var td = iface.MemberDefinition as TypeDefinition;
+                                       if (td != null)
+                                               td.DoExpandBaseInterfaces ();
+
+                                       if (iface.Interfaces == null)
+                                               continue;
+
+                                       foreach (var biface in iface.Interfaces) {
+                                               if (spec.AddInterfaceDefined (biface)) {
+                                                       TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
+                                               }
                                        }
                                }
                        }
 
-                       if (methods != null) {
-                               foreach (MethodCore m in methods) {
-                                       var p = m.ParameterInfo;
-                                       if (!p.IsEmpty) {
-                                               p.ResolveDefaultValues (m);
+                       //
+                       // Include all base type interfaces too, see ImportTypeBase for details
+                       //
+                       if (base_type != null) {
+                               var td = base_type.MemberDefinition as TypeDefinition;
+                               if (td != null)
+                                       td.DoExpandBaseInterfaces ();
+
+                               //
+                               // Simply use base interfaces only, they are all expanded which makes
+                               // it easy to handle generic type argument propagation with single
+                               // inflator only.
+                               //
+                               // interface IA<T> : IB<T>
+                               // interface IB<U> : IC<U>
+                               // interface IC<V>
+                               //
+                               if (base_type.Interfaces != null) {
+                                       foreach (var iface in base_type.Interfaces) {
+                                               spec.AddInterfaceDefined (iface);
                                        }
                                }
                        }
+               }
+
+               public override void PrepareEmit ()
+               {
+                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                               return;
+
+                       foreach (var member in members) {
+                               var pm = member as IParametersMember;
+                               if (pm != null) {
+
+                                       var p = pm.Parameters;
+                                       if (p.IsEmpty)
+                                               continue;
 
-                       if (indexers != null) {
-                               foreach (Indexer i in indexers) {
-                                       i.ParameterInfo.ResolveDefaultValues (i);
+                                       ((ParametersCompiled) p).ResolveDefaultValues (member);
                                }
-                       }
 
-                       if (types != null) {
-                               foreach (var t in types)
-                                       t.DefineConstants ();
+                               var c = member as Const;
+                               if (c != null)
+                                       c.DefineValue ();
                        }
+
+                       base.PrepareEmit ();
                }
 
                //
                // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
                //
-               public bool CreateType ()
+               public override bool CreateContainer ()
                {
                        if (TypeBuilder != null)
                                return !error;
@@ -1497,57 +1630,26 @@ namespace Mono.CSharp
                        if (error)
                                return false;
 
-                       if (!CreateTypeBuilder ()) {
-                               error = true;
-                               return false;
-                       }
-
-                       if (partial_parts != null) {
-                               foreach (TypeContainer part in partial_parts) {
-                                       part.spec = spec;
-                                       part.current_type = current_type;
-                                       part.TypeBuilder = TypeBuilder;
-                                       part.all_type_parameters = all_type_parameters;
-                                       part.all_tp_builders = all_tp_builders;
-                               }
-                       }
-
-                       if (Types != null) {
-                               foreach (TypeContainer tc in Types) {
-                                       tc.CreateType ();
+                       if (IsPartialPart) {
+                               spec = PartialContainer.spec;
+                               TypeBuilder = PartialContainer.TypeBuilder;
+                               all_tp_builders = PartialContainer.all_tp_builders;
+                               all_type_parameters = PartialContainer.all_type_parameters;
+                       } else {
+                               if (!CreateTypeBuilder ()) {
+                                       error = true;
+                                       return false;
                                }
                        }
 
-                       return true;
+                       return base.CreateContainer ();
                }
 
-               public void DefineType ()
+               protected override void DoDefineContainer ()
                {
-                       if (error)
-                               return;
-                       if (type_defined)
-                               return;
-
-                       type_defined = true;
-
-                       // Nested type share same namespace
-                       if (IsTopLevel && !IsCompilerGenerated) {
-                               NamespaceEntry.Define ();
-                               if (partial_parts != null) {
-                                       foreach (var part in partial_parts)
-                                               part.NamespaceEntry.Define ();
-                               }
-                       }
-
-                       if (!DefineBaseTypes ()) {
-                               error = true;
-                               return;
-                       }
+                       DefineBaseTypes ();
 
-                       if (!DefineNestedTypes ()) {
-                               error = true;
-                               return;
-                       }
+                       DoResolveTypeParameters ();
                }
 
                //
@@ -1572,7 +1674,7 @@ namespace Mono.CSharp
                        current_type = null;
                }
 
-               void UpdateTypeParameterConstraints (TypeContainer part)
+               void UpdateTypeParameterConstraints (TypeDefinition part)
                {
                        for (int i = 0; i < CurrentTypeParameters.Count; i++) {
                                if (CurrentTypeParameters[i].AddPartialConstraints (part, part.MemberName.TypeParameters[i]))
@@ -1585,24 +1687,11 @@ namespace Mono.CSharp
                        }
                }
 
-               public bool ResolveTypeParameters ()
+               public override void RemoveContainer (TypeContainer cont)
                {
-                       if (!DoResolveTypeParameters ())
-                               return false;
-
-                       if (types != null) {
-                               foreach (var type in types)
-                                       if (!type.ResolveTypeParameters ())
-                                               return false;
-                       }
-
-                       if (compiler_generated != null) {
-                               foreach (CompilerGeneratedClass c in compiler_generated)
-                                       if (!c.ResolveTypeParameters ())
-                                               return false;
-                       }
-
-                       return true;
+                       base.RemoveContainer (cont);
+                       Members.Remove (cont);
+                       Cache.Remove (cont.Basename);
                }
 
                protected virtual bool DoResolveTypeParameters ()
@@ -1611,9 +1700,6 @@ namespace Mono.CSharp
                        if (tparams == null)
                                return true;
 
-                       if (PartialContainer != this)
-                               throw new InternalErrorException ();
-
                        var base_context = new BaseContext (this);
                        for (int i = 0; i < tparams.Count; ++i) {
                                var tp = tparams[i];
@@ -1624,25 +1710,14 @@ namespace Mono.CSharp
                                }
                        }
 
-                       if (partial_parts != null) {
-                               foreach (TypeContainer part in partial_parts)
-                                       UpdateTypeParameterConstraints (part);
-                       }
-
-                       return true;
-               }
-
-               protected virtual bool DefineNestedTypes ()
-               {
-                       if (Types != null) {
-                               foreach (TypeContainer tc in Types)
-                                       tc.DefineType ();
+                       if (IsPartialPart) {
+                               PartialContainer.UpdateTypeParameterConstraints (this);
                        }
 
                        return true;
                }
 
-               TypeSpec CheckRecursiveDefinition (TypeContainer tc)
+               TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
                {
                        if (InTransit != null)
                                return spec;
@@ -1650,7 +1725,7 @@ namespace Mono.CSharp
                        InTransit = tc;
 
                        if (base_type != null) {
-                               var ptc = base_type.MemberDefinition as TypeContainer;
+                               var ptc = base_type.MemberDefinition as TypeDefinition;
                                if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
                                        return base_type;
                        }
@@ -1684,16 +1759,15 @@ namespace Mono.CSharp
                        members_defined_ok = DoDefineMembers ();
                        members_defined = true;
 
-                       if (types != null) {
-                               foreach (var nested in types)
-                                       nested.Define ();
-                       }
+                       base.Define ();
 
                        return members_defined_ok;
                }
 
                protected virtual bool DoDefineMembers ()
                {
+                       Debug.Assert (!IsPartialPart);
+
                        if (iface_exprs != null) {
                                foreach (var iface_type in iface_exprs) {
                                        if (iface_type == null)
@@ -1704,9 +1778,6 @@ namespace Mono.CSharp
                                        if (compiled_iface != null)
                                                compiled_iface.Define ();
 
-                                       if (Kind == MemberKind.Interface)
-                                               MemberCache.AddInterface (iface_type);
-
                                        ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
                                        if (oa != null && !IsObsolete)
                                                AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
@@ -1724,21 +1795,25 @@ namespace Mono.CSharp
                                        }
 
                                        if (iface_type.IsGenericOrParentIsGeneric) {
-                                               if (spec.Interfaces != null) {
-                                                       foreach (var prev_iface in iface_exprs) {
-                                                               if (prev_iface == iface_type)
-                                                                       break;
-
-                                                               if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
-                                                                       continue;
-
-                                                               Report.Error (695, Location,
-                                                                       "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
-                                                                       GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
-                                                       }
+                                               foreach (var prev_iface in iface_exprs) {
+                                                       if (prev_iface == iface_type || prev_iface == null)
+                                                               break;
+
+                                                       if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
+                                                               continue;
+
+                                                       Report.Error (695, Location,
+                                                               "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
+                                                               GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
                                                }
                                        }
                                }
+
+                               if (Kind == MemberKind.Interface) {
+                                       foreach (var iface in spec.Interfaces) {
+                                               MemberCache.AddInterface (iface);
+                                       }
+                               }
                        }
 
                        if (base_type != null) {
@@ -1757,11 +1832,6 @@ namespace Mono.CSharp
                                        }
                                }
 
-                               if (base_type.Interfaces != null) {
-                                       foreach (var iface in base_type.Interfaces)
-                                               spec.AddInterface (iface);
-                               }
-
                                var baseContainer = base_type.MemberDefinition as ClassOrStruct;
                                if (baseContainer != null) {
                                        baseContainer.Define ();
@@ -1774,37 +1844,57 @@ namespace Mono.CSharp
                                }
                        }
 
-                       DefineContainerMembers (constants);
-                       DefineContainerMembers (fields);
-
                        if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
                                pending = PendingImplementation.GetPendingImplementations (this);
+                       }
 
-                               if (requires_delayed_unmanagedtype_check) {
-                                       requires_delayed_unmanagedtype_check = false;
-                                       foreach (FieldBase f in fields) {
-                                               if (f.MemberType != null && f.MemberType.IsPointer)
-                                                       TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
-                                       }
+                       var count = members.Count;              
+                       for (int i = 0; i < count; ++i) {
+                               var mc = members[i] as InterfaceMemberBase;
+                               if (mc == null || !mc.IsExplicitImpl)
+                                       continue;
+
+                               try {
+                                       mc.Define ();
+                               } catch (Exception e) {
+                                       throw new InternalErrorException (mc, e);
                                }
                        }
-               
-                       //
-                       // Constructors are not in the defined_names array
-                       //
-                       DefineContainerMembers (instance_constructors);
-               
-                       DefineContainerMembers (events);
-                       DefineContainerMembers (ordered_explicit_member_list);
-                       DefineContainerMembers (ordered_member_list);
 
-                       if (operators != null) {
-                               DefineContainerMembers (operators);
+                       for (int i = 0; i < count; ++i) {
+                               var mc = members[i] as InterfaceMemberBase;
+                               if (mc != null && mc.IsExplicitImpl)
+                                       continue;
+
+                               if (members[i] is TypeContainer)
+                                       continue;
+
+                               try {
+                                       members[i].Define ();
+                               } catch (Exception e) {
+                                       throw new InternalErrorException (members[i], e);
+                               }
+                       }
+
+                       if (HasOperators) {
                                CheckPairedOperators ();
                        }
 
+                       if (requires_delayed_unmanagedtype_check) {
+                               requires_delayed_unmanagedtype_check = false;
+                               foreach (var member in members) {
+                                       var f = member as Field;
+                                       if (f != null && f.MemberType != null && f.MemberType.IsPointer)
+                                               TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
+                               }
+                       }
+
                        ComputeIndexerName();
-                       CheckEqualsAndGetHashCode();
+
+                       if (HasEquals && !HasGetHashCode) {
+                               Report.Warning (659, 3, Location,
+                                       "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
+                       }
 
                        if (Kind == MemberKind.Interface && iface_exprs != null) {
                                MemberCache.RemoveHiddenMembers (spec);
@@ -1813,212 +1903,157 @@ namespace Mono.CSharp
                        return true;
                }
 
-               protected virtual void DefineContainerMembers (System.Collections.IList mcal) // IList<MemberCore>
-               {
-                       if (mcal != null) {
-                               for (int i = 0; i < mcal.Count; ++i) {
-                                       MemberCore mc = (MemberCore) mcal[i];
-                                       try {
-                                               mc.Define ();
-                                       } catch (Exception e) {
-                                               throw new InternalErrorException (mc, e);
-                                       }
-                               }
-                       }
-               }
-               
-               protected virtual void ComputeIndexerName ()
+               void ComputeIndexerName ()
                {
+                       var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
                        if (indexers == null)
                                return;
 
                        string class_indexer_name = null;
 
                        //
-                       // If there's both an explicit and an implicit interface implementation, the
-                       // explicit one actually implements the interface while the other one is just
-                       // a normal indexer.  See bug #37714.
+                       // Check normal indexers for consistent name, explicit interface implementation
+                       // indexers are ignored
                        //
-
-                       // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
-                       foreach (Indexer i in indexers) {
-                               if (i.InterfaceType != null) {
-                                       if (seen_normal_indexers)
-                                               throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
+                       foreach (var indexer in indexers) {
+                               //
+                               // FindMembers can return unfiltered full hierarchy names
+                               //
+                               if (indexer.DeclaringType != spec)
                                        continue;
-                               }
 
-                               seen_normal_indexers = true;
+                               has_normal_indexers = true;
 
                                if (class_indexer_name == null) {
-                                       class_indexer_name = i.ShortName;
-                                       continue;
-                               }
-
-                               if (i.ShortName != class_indexer_name)
-                                       Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
-                       }
-
-                       if (class_indexer_name != null)
-                               indexer_name = class_indexer_name;
-               }
-
-               void EmitIndexerName ()
-               {
-                       if (!seen_normal_indexers)
-                               return;
-
-                       var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
-                       if (ctor == null)
-                               return;
-
-                       var encoder = new AttributeEncoder ();
-                       encoder.Encode (GetAttributeDefaultMember ());
-                       encoder.EncodeEmptyNamedArguments ();
-
-                       TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
-               }
-
-               protected virtual void CheckEqualsAndGetHashCode ()
-               {
-                       if (methods == null)
-                               return;
-
-                       if (HasEquals && !HasGetHashCode) {
-                               Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
-                       }
-               }
-
-               // Indicated whether container has StructLayout attribute set Explicit
-               public bool HasExplicitLayout {
-                       get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
-                       set { caching_flags |= Flags.HasExplicitLayout; }
-               }
-
-               public bool HasStructLayout {
-                       get { return (caching_flags & Flags.HasStructLayout) != 0; }
-                       set { caching_flags |= Flags.HasStructLayout; }
-               }
+                                       indexer_name = class_indexer_name = indexer.Name;
+                                       continue;
+                               }
 
-               public MemberCache MemberCache {
-                       get {
-                               return spec.MemberCache;
+                               if (indexer.Name != class_indexer_name)
+                                       Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
+                                               "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
                        }
                }
 
-               void CheckMemberUsage (List<MemberCore> al, string member_type)
+               void EmitIndexerName ()
                {
-                       if (al == null)
+                       if (!has_normal_indexers)
                                return;
 
-                       foreach (MemberCore mc in al) {
-                               if ((mc.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE)
-                                       continue;
+                       var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
+                       if (ctor == null)
+                               return;
 
-                               if ((mc.ModFlags & Modifiers.PARTIAL) != 0)
-                                       continue;
+                       var encoder = new AttributeEncoder ();
+                       encoder.Encode (GetAttributeDefaultMember ());
+                       encoder.EncodeEmptyNamedArguments ();
 
-                               if (!mc.IsUsed && (mc.caching_flags & Flags.Excluded) == 0) {
-                                       Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
-                               }
-                       }
+                       TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
                }
 
-               public virtual void VerifyMembers ()
+               public override void VerifyMembers ()
                {
                        //
                        // Check for internal or private fields that were never assigned
                        //
-                       if (Report.WarningLevel >= 3) {
-                               if (Compiler.Settings.EnhancedWarnings) {
-                                       CheckMemberUsage (properties, "property");
-                                       CheckMemberUsage (methods, "method");
-                                       CheckMemberUsage (constants, "constant");
-                               }
-
-                               if (fields != null){
-                                       bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
-                                       foreach (FieldBase f in fields) {
-                                               if ((f.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
-                                                       if (is_type_exposed)
-                                                               continue;
-
-                                                       f.SetIsUsed ();
-                                               }                               
-                                               
-                                               if (!f.IsUsed){
-                                                       if ((f.caching_flags & Flags.IsAssigned) == 0)
-                                                               Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
-                                                       else {
-                                                               Report.Warning (414, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
-                                                                       f.GetSignatureForError ());
-                                                       }
-                                                       continue;
-                                               }
-                                               
-                                               if ((f.caching_flags & Flags.IsAssigned) != 0)
-                                                       continue;
-
+                       if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
+                               bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
+                               foreach (var member in members) {
+                                       if (member is Event) {
                                                //
-                                               // Only report 649 on level 4
+                                               // An event can be assigned from same class only, so we can report
+                                               // this warning for all accessibility modes
                                                //
-                                               if (Report.WarningLevel < 4)
-                                                       continue;
+                                               if (!member.IsUsed)
+                                                       Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
 
-                                               //
-                                               // Don't be pendatic over serializable attributes
-                                               //
-                                               if (f.OptAttributes != null || PartialContainer.HasStructLayout)
+                                               continue;
+                                       }
+
+                                       if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
+                                               if (is_type_exposed)
                                                        continue;
-                                               
-                                               Constant c = New.Constantify (f.MemberType, f.Location);
-                                               string value;
-                                               if (c != null) {
-                                                       value = c.GetValueAsLiteral ();
-                                               } else if (TypeSpec.IsReferenceType (f.MemberType)) {
-                                                       value = "null";
-                                               } else {
-                                                       // Ignore this warning for struct value fields (they are always initialized)
-                                                       if (f.MemberType.IsStruct)
-                                                               continue;
 
-                                                       value = null;
+                                               member.SetIsUsed ();
+                                       }
+
+                                       var f = member as Field;
+                                       if (f == null)
+                                               continue;
+
+                                       if (!member.IsUsed) {
+                                               if ((member.caching_flags & Flags.IsAssigned) == 0) {
+                                                       Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
+                                               } else {
+                                                       Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
+                                                               member.GetSignatureForError ());
                                                }
+                                               continue;
+                                       }
 
-                                               if (value != null)
-                                                       value = " `" + value + "'";
+                                       if ((f.caching_flags & Flags.IsAssigned) != 0)
+                                               continue;
+
+                                       //
+                                       // Only report 649 on level 4
+                                       //
+                                       if (Compiler.Settings.WarningLevel < 4)
+                                               continue;
+
+                                       //
+                                       // Don't be pedantic when type requires specific layout
+                                       //
+                                       if (f.OptAttributes != null || PartialContainer.HasStructLayout)
+                                               continue;
 
-                                               Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
-                                                       f.GetSignatureForError (), value);
+                                       Constant c = New.Constantify (f.MemberType, f.Location);
+                                       string value;
+                                       if (c != null) {
+                                               value = c.GetValueAsLiteral ();
+                                       } else if (TypeSpec.IsReferenceType (f.MemberType)) {
+                                               value = "null";
+                                       } else {
+                                               value = null;
                                        }
+
+                                       if (value != null)
+                                               value = " `" + value + "'";
+
+                                       Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
+                                               f.GetSignatureForError (), value);
                                }
                        }
+
+                       base.VerifyMembers ();
                }
 
                public override void Emit ()
                {
-                       if (!IsTopLevel) {
-                               MemberSpec candidate;
-                               bool overrides = false;
-                               var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
-                               if (conflict_symbol == null && candidate == null) {
-                                       if ((ModFlags & Modifiers.NEW) != 0)
-                                               Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
-                                                       GetSignatureForError ());
-                               } else {
-                                       if ((ModFlags & Modifiers.NEW) == 0) {
-                                               if (candidate == null)
-                                                       candidate = conflict_symbol;
+                       if (OptAttributes != null)
+                               OptAttributes.Emit ();
 
-                                               Report.SymbolRelatedToPreviousError (candidate);
-                                               Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
-                                                       GetSignatureForError (), candidate.GetSignatureForError ());
+                       if (!IsCompilerGenerated) {
+                               if (!IsTopLevel) {
+                                       MemberSpec candidate;
+                                       bool overrides = false;
+                                       var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
+                                       if (conflict_symbol == null && candidate == null) {
+                                               if ((ModFlags & Modifiers.NEW) != 0)
+                                                       Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+                                                               GetSignatureForError ());
+                                       } else {
+                                               if ((ModFlags & Modifiers.NEW) == 0) {
+                                                       if (candidate == null)
+                                                               candidate = conflict_symbol;
+
+                                                       Report.SymbolRelatedToPreviousError (candidate);
+                                                       Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+                                                               GetSignatureForError (), candidate.GetSignatureForError ());
+                                               }
                                        }
                                }
-                       }
 
-                       // Run constraints check on all possible generic types
-                       if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
+                               // Run constraints check on all possible generic types
                                if (base_type != null && base_type_expr != null) {
                                        ConstraintChecker.Check (this, base_type, base_type_expr.Location);
                                }
@@ -2055,120 +2090,44 @@ namespace Mono.CSharp
 #endif
 
                        base.Emit ();
-               }
-
-               // TODO: move to ClassOrStruct
-               void EmitConstructors ()
-               {
-                       if (instance_constructors == null)
-                               return;
-
-                       if (spec.IsAttribute && IsExposedFromAssembly () && Compiler.Settings.VerifyClsCompliance && IsClsComplianceRequired ()) {
-                               bool has_compliant_args = false;
 
-                               foreach (Constructor c in instance_constructors) {
-                                       try {
-                                               c.Emit ();
-                                       }
-                                       catch (Exception e) {
-                                               throw new InternalErrorException (c, e);
-                                       }
+                       for (int i = 0; i < members.Count; i++)
+                               members[i].Emit ();
 
-                                       if (has_compliant_args)
-                                               continue;
+                       EmitIndexerName ();
+                       CheckAttributeClsCompliance ();
 
-                                       has_compliant_args = c.HasCompliantArgs;
-                               }
-                               if (!has_compliant_args)
-                                       Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
-                       } else {
-                               foreach (Constructor c in instance_constructors) {
-                                       try {
-                                               c.Emit ();
-                                       }
-                                       catch (Exception e) {
-                                               throw new InternalErrorException (c, e);
-                                       }
-                               }
-                       }
+                       if (pending != null)
+                               pending.VerifyPendingMethods ();
                }
 
-               /// <summary>
-               ///   Emits the code, this step is performed after all
-               ///   the types, enumerations, constructors
-               /// </summary>
-               public virtual void EmitType ()
+
+               void CheckAttributeClsCompliance ()
                {
-                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                       if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
                                return;
 
-                       if (OptAttributes != null)
-                               OptAttributes.Emit ();
-
-                       Emit ();
-
-                       EmitConstructors ();
-
-                       if (constants != null)
-                               foreach (Const con in constants)
-                                       con.Emit ();
-
-                       if (default_static_constructor != null)
-                               default_static_constructor.Emit ();
-                       
-                       if (operators != null)
-                               foreach (Operator o in operators)
-                                       o.Emit ();
-
-                       if (properties != null)
-                               foreach (Property p in properties)
-                                       p.Emit ();
-
-                       if (indexers != null) {
-                               foreach (Indexer indx in indexers)
-                                       indx.Emit ();
-                               EmitIndexerName ();
-                       }
-
-                       if (events != null){
-                               foreach (Event e in Events)
-                                       e.Emit ();
-                       }
-
-                       if (methods != null) {
-                               for (int i = 0; i < methods.Count; ++i)
-                                       ((MethodOrOperator) methods [i]).Emit ();
-                       }
-                       
-                       if (fields != null)
-                               foreach (FieldBase f in fields)
-                                       f.Emit ();
+                       foreach (var m in members) {
+                               var c = m as Constructor;
+                               if (c == null)
+                                       continue;
 
-                       if (types != null) {
-                               foreach (TypeContainer t in types)
-                                       t.EmitType ();
+                               if (c.HasCompliantArgs)
+                                       return;
                        }
 
-                       if (pending != null)
-                               pending.VerifyPendingMethods ();
-
-                       if (Report.Errors > 0)
-                               return;
-
-                       if (compiler_generated != null) {
-                               for (int i = 0; i < compiler_generated.Count; ++i)
-                                       compiler_generated [i].EmitType ();
-                       }
+                       Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
                }
 
-               protected void Error_MissingPartialModifier (MemberCore type)
+               public sealed override void EmitContainer ()
                {
-                       Report.Error (260, type.Location,
-                               "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
-                               type.GetSignatureForError ());
+                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                               return;
+
+                       Emit ();
                }
 
-               public virtual void CloseType ()
+               public override void CloseContainer ()
                {
                        if ((caching_flags & Flags.CloseTypeCreated) != 0)
                                return;
@@ -2177,7 +2136,7 @@ namespace Mono.CSharp
                        if (spec.BaseType != null) {
                                var btype = spec.BaseType.MemberDefinition as TypeContainer;
                                if (btype != null) {
-                                       btype.CloseType ();
+                                       btype.CloseContainer ();
 
                                        if ((caching_flags & Flags.CloseTypeCreated) != 0)
                                                return;
@@ -2187,38 +2146,19 @@ namespace Mono.CSharp
                        try {
                                caching_flags |= Flags.CloseTypeCreated;
                                TypeBuilder.CreateType ();
-                       } catch (TypeLoadException){
+                       } catch (TypeLoadException) {
                                //
                                // This is fine, the code still created the type
                                //
-//                             Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
-//                             Console.WriteLine (e.Message);
                        } catch (Exception e) {
                                throw new InternalErrorException (this, e);
                        }
-                       
-                       if (Types != null){
-                               foreach (TypeContainer tc in Types)
-                                       tc.CloseType ();
-                       }
 
-                       if (compiler_generated != null)
-                               foreach (CompilerGeneratedClass c in compiler_generated)
-                                       c.CloseType ();
+                       base.CloseContainer ();
                        
-                       types = null;
+                       containers = null;
                        initialized_fields = null;
                        initialized_static_fields = null;
-                       constants = null;
-                       ordered_explicit_member_list = null;
-                       ordered_member_list = null;
-                       methods = null;
-                       events = null;
-                       indexers = null;
-                       operators = null;
-                       compiler_generated = null;
-                       default_constructor = null;
-                       default_static_constructor = null;
                        type_bases = null;
                        OptAttributes = null;
                }
@@ -2299,18 +2239,11 @@ namespace Mono.CSharp
                        return ok;
                }
 
-               public Constructor DefaultStaticConstructor {
-                       get { return default_static_constructor; }
-               }
-
                protected override bool VerifyClsCompliance ()
                {
                        if (!base.VerifyClsCompliance ())
                                return false;
 
-                       // Check this name against other containers
-                       NamespaceEntry.NS.VerifyClsCompliance ();
-
                        // Check all container names for user classes
                        if (Kind != MemberKind.Delegate)
                                MemberCache.VerifyClsCompliance (Definition, Report);
@@ -2364,6 +2297,14 @@ namespace Mono.CSharp
                        return false;
                }
 
+               public override bool IsClsComplianceRequired ()
+               {
+                       if (IsPartialPart)
+                               return PartialContainer.IsClsComplianceRequired ();
+
+                       return base.IsClsComplianceRequired ();
+               }
+
                bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
                {
                        return Module.DeclaringAssembly == assembly;
@@ -2408,15 +2349,8 @@ namespace Mono.CSharp
 
                                if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
                                        e = new TypeExpression (t, Location.Null);
-                               else if (Parent != null) {
+                               else {
                                        e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
-                               } else {
-                                       int errors = Report.Errors;
-
-                                       e = NamespaceEntry.LookupNamespaceOrType (name, arity, mode, loc);
-
-                                       if (errors != Report.Errors)
-                                               return e;
                                }
                        }
 
@@ -2429,21 +2363,12 @@ namespace Mono.CSharp
 
                TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
                {
-                       // TODO: GenericMethod only
-                       if (PartialContainer == null)
-                               return null;
-
                        // Has any nested type
                        // Does not work, because base type can have
                        //if (PartialContainer.Types == null)
                        //      return null;
 
                        var container = PartialContainer.CurrentType;
-
-                       // Is not Root container
-                       if (container == null)
-                               return null;
-
                        return MemberCache.FindNestedType (container, name, arity);
                }
 
@@ -2457,6 +2382,16 @@ namespace Mono.CSharp
                        cached_method |= CachedMethods.GetHashCode;
                }
 
+               public override void WriteDebugSymbol (MonoSymbolFile file)
+               {
+                       if (IsPartialPart)
+                               return;
+
+                       foreach (var m in members) {
+                               m.WriteDebugSymbol (file);
+                       }
+               }
+
                /// <summary>
                /// Method container contains Equals method
                /// </summary>
@@ -2492,23 +2427,43 @@ namespace Mono.CSharp
                }
        }
 
-       public abstract class ClassOrStruct : TypeContainer
+       public abstract class ClassOrStruct : TypeDefinition
        {
+               public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
+
                SecurityType declarative_security;
 
-               public ClassOrStruct (NamespaceContainer ns, TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
-                       : base (ns, parent, name, attrs, kind)
+               public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+                       : base (parent, name, attrs, kind)
                {
                }
 
-               protected override bool AddToContainer (MemberCore symbol, string name)
+               protected override TypeAttributes TypeAttr {
+                       get {
+                               TypeAttributes ta = base.TypeAttr;
+                               if (!has_static_constructor)
+                                       ta |= TypeAttributes.BeforeFieldInit;
+
+                               if (Kind == MemberKind.Class) {
+                                       ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
+                                       if (IsStatic)
+                                               ta |= StaticClassAttribute;
+                               } else {
+                                       ta |= TypeAttributes.SequentialLayout;
+                               }
+
+                               return ta;
+                       }
+               }
+
+               public override void AddNameToContainer (MemberCore symbol, string name)
                {
                        if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
                                if (symbol is TypeParameter) {
                                        Report.Error (694, symbol.Location,
                                                "Type parameter `{0}' has same name as containing type, or method",
                                                symbol.GetSignatureForError ());
-                                       return false;
+                                       return;
                                }
                        
                                InterfaceMemberBase imb = symbol as InterfaceMemberBase;
@@ -2516,30 +2471,11 @@ namespace Mono.CSharp
                                        Report.SymbolRelatedToPreviousError (this);
                                        Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
                                                symbol.GetSignatureForError ());
-                                       return false;
-                               }
-                       }
-
-                       return base.AddToContainer (symbol, name);
-               }
-
-               public override void VerifyMembers ()
-               {
-                       base.VerifyMembers ();
-
-                       if ((events != null) && Report.WarningLevel >= 3) {
-                               foreach (Event e in events){
-                                       // Note: The event can be assigned from same class only, so we can report
-                                       // this warning for all accessibility modes
-                                       if ((e.caching_flags & Flags.IsUsed) == 0)
-                                               Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
+                                       return;
                                }
                        }
 
-                       if (types != null) {
-                               foreach (var t in types)
-                                       t.VerifyMembers ();
-                       }
+                       base.AddNameToContainer (symbol, name);
                }
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
@@ -2566,7 +2502,7 @@ namespace Mono.CSharp
                /// <summary>
                /// Defines the default constructors 
                /// </summary>
-               protected void DefineDefaultConstructor (bool is_static)
+               protected virtual Constructor DefineDefaultConstructor (bool is_static)
                {
                        // The default instance constructor is public
                        // If the class is abstract, the default constructor is protected
@@ -2579,12 +2515,15 @@ namespace Mono.CSharp
                                mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
                        }
 
-                       Constructor c = new Constructor (this, MemberName.Name, mods,
-                               null, ParametersCompiled.EmptyReadOnlyParameters, Location);
+                       var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
                        c.Initializer = new GeneratedBaseInitializer (Location);
                        
-                       AddConstructor (c);
-                       c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
+                       AddConstructor (c, true);
+                       c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
+                               IsCompilerGenerated = true
+                       };
+
+                       return c;
                }
 
                protected override bool DoDefineMembers ()
@@ -2593,17 +2532,14 @@ namespace Mono.CSharp
 
                        base.DoDefineMembers ();
 
-                       if (default_static_constructor != null)
-                               default_static_constructor.Define ();
-
                        return true;
                }
 
                public override void Emit ()
                {
-                       if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer) {
-                               DefineDefaultConstructor (true);
-                               default_static_constructor.Define ();
+                       if (!has_static_constructor && HasStaticFieldInitializer) {
+                               var c = DefineDefaultConstructor (true);
+                               c.Define ();
                        }
 
                        base.Emit ();
@@ -2618,34 +2554,11 @@ namespace Mono.CSharp
                                }
                        }
                }
-
-               public override ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
-               {
-                       if (Parent != null) {
-                               var methods = NamespaceEntry.NS.LookupExtensionMethod (this, extensionType, name, arity);
-                               if (methods != null) {
-                                       return new ExtensionMethodCandidates (methods, NamespaceEntry, NamespaceEntry.NS) {
-                                               HasUninspectedMembers = true
-                                       };
-                               }
-                       }
-
-                       return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity);
-               }
-
-               protected override TypeAttributes TypeAttr {
-                       get {
-                               if (default_static_constructor == null)
-                                       return base.TypeAttr | TypeAttributes.BeforeFieldInit;
-
-                               return base.TypeAttr;
-                       }
-               }
        }
 
 
-       // TODO: should be sealed
-       public class Class : ClassOrStruct {
+       public sealed class Class : ClassOrStruct
+       {
                const Modifiers AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -2657,12 +2570,10 @@ namespace Mono.CSharp
                        Modifiers.STATIC |
                        Modifiers.UNSAFE;
 
-               public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
-
-               public Class (NamespaceContainer ns, TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
-                       : base (ns, parent, name, attrs, MemberKind.Class)
+               public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+                       : base (parent, name, attrs, MemberKind.Class)
                {
-                       var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+                       var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
                        this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
                        spec = new TypeSpec (Kind, null, this, null, ModFlags);
                }
@@ -2672,13 +2583,14 @@ namespace Mono.CSharp
                        visitor.Visit (this);
                }
 
-               public override void AddBasesForPart (TypeContainer part, List<FullNamedExpression> bases)
+               public override void AddBasesForPart (List<FullNamedExpression> bases)
                {
-                       var pmn = part.MemberName;
-                       if (pmn.Name == "Object" && pmn.Left != null && pmn.Left.Name == "System" && pmn.TypeParameters == null)
-                               Report.Error (537, part.Location,
+                       var pmn = MemberName;
+                       if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
+                               Report.Error (537, Location,
                                        "The class System.Object cannot have a base class or implement an interface.");
-                       base.AddBasesForPart (part, bases);
+
+                       base.AddBasesForPart (bases);
                }
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
@@ -2704,7 +2616,7 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       if (a.Type.IsConditionallyExcluded (Compiler, Location))
+                       if (a.Type.IsConditionallyExcluded (this, Location))
                                return;
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
@@ -2716,46 +2628,6 @@ namespace Mono.CSharp
                        }
                }
 
-               protected override void DefineContainerMembers (System.Collections.IList list)
-               {
-                       if (list == null)
-                               return;
-
-                       if (!IsStatic) {
-                               base.DefineContainerMembers (list);
-                               return;
-                       }
-
-                       foreach (MemberCore m in list) {
-                               if (m is Operator) {
-                                       Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
-                                       continue;
-                               }
-
-                               if (m is Destructor) {
-                                       Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
-                                       continue;
-                               }
-
-                               if (m is Indexer) {
-                                       Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
-                                       continue;
-                               }
-
-                               if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
-                                       continue;
-
-                               if (m is Constructor) {
-                                       Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
-                                       continue;
-                               }
-
-                               Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
-                       }
-
-                       base.DefineContainerMembers (list);
-               }
-
                protected override bool DoDefineMembers ()
                {
                        if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
@@ -2766,8 +2638,37 @@ namespace Mono.CSharp
                                Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
                        }
 
-                       if (InstanceConstructors == null && !IsStatic)
-                               DefineDefaultConstructor (false);
+                       if (IsStatic) {
+                               foreach (var m in Members) {
+                                       if (m is Operator) {
+                                               Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
+                                               continue;
+                                       }
+
+                                       if (m is Destructor) {
+                                               Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
+                                               continue;
+                                       }
+
+                                       if (m is Indexer) {
+                                               Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
+                                               continue;
+                                       }
+
+                                       if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
+                                               continue;
+
+                                       if (m is Constructor) {
+                                               Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
+                                               continue;
+                                       }
+
+                                       Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
+                               }
+                       } else {
+                               if (!PartialContainer.HasInstanceConstructor)
+                                       DefineDefaultConstructor (false);
+                       }
 
                        return base.DoDefineMembers ();
                }
@@ -2862,23 +2763,10 @@ namespace Mono.CSharp
                        caching_flags |= Flags.Excluded;
                        return conditions;
                }
-
-               //
-               // FIXME: How do we deal with the user specifying a different
-               // layout?
-               //
-               protected override TypeAttributes TypeAttr {
-                       get {
-                               TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
-                               if (IsStatic)
-                                       ta |= StaticClassAttribute;
-                               return ta;
-                       }
-               }
        }
 
-       public sealed class Struct : ClassOrStruct {
-
+       public sealed class Struct : ClassOrStruct
+       {
                bool is_unmanaged, has_unmanaged_check_done;
                bool InTransit;
 
@@ -2893,10 +2781,10 @@ namespace Mono.CSharp
                        Modifiers.UNSAFE    |
                        Modifiers.PRIVATE;
 
-               public Struct (NamespaceContainer ns, TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
-                       : base (ns, parent, name, attrs, MemberKind.Struct)
+               public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+                       : base (parent, name, attrs, MemberKind.Struct)
                {
-                       var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;                   
+                       var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;                      
                        this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
                        spec = new TypeSpec (Kind, null, this, null, ModFlags);
                }
@@ -2921,13 +2809,13 @@ namespace Mono.CSharp
                        // set CharSet, its value has to be propagated to compiler generated
                        // fixed types
                        //
-                       if (a.Type == pa.StructLayout && Fields != null) {
+                       if (a.Type == pa.StructLayout) {
                                var value = a.GetNamedValue ("CharSet");
                                if (value == null)
                                        return;
 
-                               for (int i = 0; i < Fields.Count; ++i) {
-                                       FixedField ff = Fields [i] as FixedField;
+                               for (int i = 0; i < Members.Count; ++i) {
+                                       FixedField ff = Members [i] as FixedField;
                                        if (ff == null)
                                                continue;
 
@@ -2936,16 +2824,17 @@ namespace Mono.CSharp
                        }
                }
 
-               bool CheckStructCycles (Struct s)
+               bool CheckStructCycles ()
                {
-                       if (s.Fields == null)
-                               return true;
-
-                       if (s.InTransit)
+                       if (InTransit)
                                return false;
 
-                       s.InTransit = true;
-                       foreach (FieldBase field in s.Fields) {
+                       InTransit = true;
+                       foreach (var member in Members) {
+                               var field = member as Field;
+                               if (field == null)
+                                       continue;
+
                                TypeSpec ftype = field.Spec.MemberType;
                                if (!ftype.IsStruct)
                                        continue;
@@ -2965,7 +2854,7 @@ namespace Mono.CSharp
                                //
                                // Static fields of exactly same type are allowed
                                //
-                               if (field.IsStatic && ftype == s.CurrentType)
+                               if (field.IsStatic && ftype == CurrentType)
                                        continue;
 
                                if (!CheckFieldTypeCycle (ftype)) {
@@ -2976,22 +2865,22 @@ namespace Mono.CSharp
                                }
                        }
 
-                       s.InTransit = false;
+                       InTransit = false;
                        return true;
                }
 
-               bool CheckFieldTypeCycle (TypeSpec ts)
+               static bool CheckFieldTypeCycle (TypeSpec ts)
                {
                        var fts = ts.MemberDefinition as Struct;
                        if (fts == null)
                                return true;
 
-                       return CheckStructCycles (fts);
+                       return fts.CheckStructCycles ();
                }
 
                public override void Emit ()
                {
-                       CheckStructCycles (this);
+                       CheckStructCycles ();
 
                        base.Emit ();
                }
@@ -3004,15 +2893,20 @@ namespace Mono.CSharp
                        if (requires_delayed_unmanagedtype_check)
                                return true;
 
-                       if (Parent != null && Parent.IsGenericOrParentIsGeneric) {
+                       var parent_def = Parent.PartialContainer;
+                       if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
                                has_unmanaged_check_done = true;
                                return false;
                        }
 
-                       if (fields != null) {
+                       if (first_nonstatic_field != null) {
                                requires_delayed_unmanagedtype_check = true;
 
-                               foreach (FieldBase f in fields) {
+                               foreach (var member in Members) {
+                                       var f = member as Field;
+                                       if (f == null)
+                                               continue;
+
                                        if (f.IsStatic)
                                                continue;
 
@@ -3044,16 +2938,6 @@ namespace Mono.CSharp
                        return ifaces;
                }
 
-               protected override TypeAttributes TypeAttr {
-                       get {
-                               const TypeAttributes DefaultTypeAttributes =
-                                       TypeAttributes.SequentialLayout |
-                                       TypeAttributes.Sealed;
-
-                               return base.TypeAttr | DefaultTypeAttributes;
-                       }
-               }
-
                public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
                {
                        if ((field.ModFlags & Modifiers.STATIC) == 0) {
@@ -3069,7 +2953,7 @@ namespace Mono.CSharp
        /// <summary>
        ///   Interfaces
        /// </summary>
-       public sealed class Interface : TypeContainer {
+       public sealed class Interface : TypeDefinition {
 
                /// <summary>
                ///   Modifiers allowed in a class declaration
@@ -3082,10 +2966,10 @@ namespace Mono.CSharp
                        Modifiers.UNSAFE    |
                        Modifiers.PRIVATE;
 
-               public Interface (NamespaceContainer ns, TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
-                       : base (ns, parent, name, attrs, MemberKind.Interface)
+               public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+                       : base (parent, name, attrs, MemberKind.Interface)
                {
-                       var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+                       var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
 
                        this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
                        spec = new TypeSpec (Kind, null, this, null, ModFlags);
@@ -3195,7 +3079,7 @@ namespace Mono.CSharp
                //
                // If true, this is an explicit interface implementation
                //
-               public bool IsExplicitImpl;
+               public readonly bool IsExplicitImpl;
 
                protected bool is_external_implementation;
 
@@ -3212,10 +3096,10 @@ namespace Mono.CSharp
                readonly Modifiers explicit_mod_flags;
                public MethodAttributes flags;
 
-               public InterfaceMemberBase (TypeContainer parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
+               public InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
                        : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
                {
-                       IsInterface = parent.PartialContainer.Kind == MemberKind.Interface;
+                       IsInterface = parent.Kind == MemberKind.Interface;
                        IsExplicitImpl = (MemberName.ExplicitInterface != null);
                        explicit_mod_flags = mod;
                }
@@ -3507,7 +3391,7 @@ namespace Mono.CSharp
                {
                        // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
                        // We are more strict than csc and report this as an error because SRE does not allow emit that
-                       if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
+                       if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
                                if (this is Constructor) {
                                        Report.Warning (824, 1, Location,
                                                "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
@@ -3615,18 +3499,32 @@ namespace Mono.CSharp
                        get { return IsExplicitImpl || base.IsUsed; }
                }
 
+               public override void SetConstraints (List<Constraints> constraints_list)
+               {
+                       if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
+                               Report.Error (460, Location,
+                                       "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
+                                       GetSignatureForError ());
+                       }
+
+                       base.SetConstraints (constraints_list);
+               }
        }
 
        public abstract class MemberBase : MemberCore
        {
                protected FullNamedExpression type_expr;
                protected TypeSpec member_type;
+               public new TypeDefinition Parent;
 
-               protected MemberBase (TypeContainer parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
+               protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
                        : base (parent, name, attrs)
                {
+                       this.Parent = parent;
                        this.type_expr = type;
-                       ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
+
+                       if (name != MemberName.Null)
+                               ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
                }
 
                #region Properties