2010-04-11 Veerapuram Varadhan <vvaradhan@novell.com>
[mono.git] / mcs / mcs / ecore.cs
index b71c51881078969a68356212e04cd7990761f1cc..336bd0be58b5ac78caaaeb36840a2634eedac569 100644 (file)
 //
 //
 
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using SLE = System.Linq.Expressions;
+using System.Linq;
+
 namespace Mono.CSharp {
-       using System;
-       using System.Collections;
-       using System.Diagnostics;
-       using System.Reflection;
-       using System.Reflection.Emit;
-       using System.Text;
 
        /// <remarks>
        ///   The ExprClass class contains the is used to pass the 
@@ -25,7 +28,7 @@ namespace Mono.CSharp {
        ///   nothing).
        /// </remarks>
        public enum ExprClass : byte {
-               Invalid,
+               Unresolved      = 0,
                
                Value,
                Variable,
@@ -59,17 +62,8 @@ namespace Mono.CSharp {
                // Mask of all the expression class flags.
                MaskExprClass = VariableOrValue | Type | MethodGroup | TypeParameter,
 
-               // Disable control flow analysis while resolving the expression.
-               // This is used when resolving the instance expression of a field expression.
-               DisableFlowAnalysis     = 1 << 10,
-
                // Set if this is resolving the first part of a MemberAccess.
                Intermediate            = 1 << 11,
-
-               // Disable control flow analysis _of struct_ while resolving the expression.
-               // This is used when resolving the instance expression of a field expression.
-               DisableStructFlowAnalysis       = 1 << 12,
-
        }
 
        //
@@ -145,7 +139,7 @@ namespace Mono.CSharp {
 
                public virtual bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
                {
-                       Attribute.Error_AttributeArgumentNotValid (loc);
+                       Attribute.Error_AttributeArgumentNotValid (ec, loc);
                        value = null;
                        return false;
                }
@@ -155,28 +149,26 @@ namespace Mono.CSharp {
                        return TypeManager.CSharpName (type);
                }
 
-               public static bool IsAccessorAccessible (Type invocation_type, MethodInfo mi, out bool must_do_cs1540_check)
+               public static bool IsAccessorAccessible (Type invocation_type, MethodSpec mi, out bool must_do_cs1540_check)
                {
-                       MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+                       var ma = mi.Modifiers & Modifiers.AccessibilityMask;
 
                        must_do_cs1540_check = false; // by default we do not check for this
 
-                       if (ma == MethodAttributes.Public)
+                       if (ma == Modifiers.PUBLIC)
                                return true;
                        
                        //
                        // If only accessible to the current class or children
                        //
-                       if (ma == MethodAttributes.Private)
+                       if (ma == Modifiers.PRIVATE)
                                return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
                                        TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
 
-                       if (TypeManager.IsThisOrFriendAssembly (mi.DeclaringType.Assembly)) {
-                               if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
-                                       return true;
-                       } else {
-                               if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamANDAssem)
-                                       return false;
+                       if ((ma & Modifiers.INTERNAL) != 0) {
+                               var b = TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly);
+                               if (b || ma == Modifiers.INTERNAL)
+                                       return b;
                        }
 
                        // Family and FamANDAssem require that we derive.
@@ -223,9 +215,9 @@ namespace Mono.CSharp {
                ///   to a valid type (this is the type of the
                ///   expression).
                /// </remarks>
-               public abstract Expression DoResolve (ResolveContext ec);
+               protected abstract Expression DoResolve (ResolveContext rc);
 
-               public virtual Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+               public virtual Expression DoResolveLValue (ResolveContext rc, Expression right_side)
                {
                        return null;
                }
@@ -237,9 +229,10 @@ namespace Mono.CSharp {
                public virtual FullNamedExpression ResolveAsTypeStep (IMemberContext rc,  bool silent)
                {
                        if (!silent) {
-                               Expression e = Resolve (new ResolveContext (rc));
+                               ResolveContext ec = new ResolveContext (rc);
+                               Expression e = Resolve (ec);
                                if (e != null)
-                                       e.Error_UnexpectedKind (ResolveFlags.Type, loc);
+                                       e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc);
                        }
 
                        return null;
@@ -268,7 +261,7 @@ namespace Mono.CSharp {
                        if (!silent) { // && !(te is TypeParameterExpr)) {
                                ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (te.Type);
                                if (obsolete_attr != null && !ec.IsObsolete) {
-                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location);
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
                                }
                        }
 
@@ -297,7 +290,7 @@ namespace Mono.CSharp {
        
                public TypeExpr ResolveAsBaseTerminal (IMemberContext ec, bool silent)
                {
-                       int errors = Report.Errors;
+                       int errors = ec.Compiler.Report.Errors;
 
                        FullNamedExpression fne = ResolveAsTypeStep (ec, silent);
 
@@ -306,14 +299,14 @@ namespace Mono.CSharp {
                                
                        TypeExpr te = fne as TypeExpr;                          
                        if (te == null) {
-                               if (!silent && errors == Report.Errors)
-                                       fne.Error_UnexpectedKind (null, "type", loc);
+                               if (!silent && errors == ec.Compiler.Report.Errors)
+                                       fne.Error_UnexpectedKind (ec.Compiler.Report, null, "type", loc);
                                return null;
                        }
 
                        if (!te.CheckAccessLevel (ec)) {
-                               Report.SymbolRelatedToPreviousError (te.Type);
-                               ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type));
+                               ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
+                               ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type), ec.Compiler.Report);
                                return null;
                        }
 
@@ -321,14 +314,14 @@ namespace Mono.CSharp {
                        return te;
                }
 
-               public static void ErrorIsInaccesible (Location loc, string name)
+               public static void ErrorIsInaccesible (Location loc, string name, Report Report)
                {
                        Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", name);
                }
 
-               protected static void Error_CannotAccessProtected (Location loc, MemberInfo m, Type qualifier, Type container)
+               protected static void Error_CannotAccessProtected (ResolveContext ec, Location loc, MemberInfo m, Type qualifier, Type container)
                {
-                       Report.Error (1540, loc, "Cannot access protected member `{0}' via a qualifier of type `{1}'."
+                       ec.Report.Error (1540, loc, "Cannot access protected member `{0}' via a qualifier of type `{1}'."
                                + " The qualifier must be of type `{2}' or derived from it", 
                                TypeManager.GetFullNameSignature (m),
                                TypeManager.CSharpName (qualifier),
@@ -336,24 +329,29 @@ namespace Mono.CSharp {
 
                }
 
-               public static void Error_InvalidExpressionStatement (Location loc)
+               public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name)
                {
-                       Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
-                                      "expressions can be used as a statement");
+                       rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
                }
-               
-               public void Error_InvalidExpressionStatement ()
+
+               public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, Type type, Location loc, string name)
                {
-                       Error_InvalidExpressionStatement (loc);
+                       rc.Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null",
+                               name, TypeManager.CSharpName (type));
                }
 
-               protected void Error_CannotAssign (string to, string roContext)
+               public static void Error_InvalidExpressionStatement (Report Report, Location loc)
+               {
+                       Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
+                                      "expressions can be used as a statement");
+               }
+               
+               public void Error_InvalidExpressionStatement (BlockContext ec)
                {
-                       Report.Error (1656, loc, "Cannot assign to `{0}' because it is a `{1}'",
-                               to, roContext);
+                       Error_InvalidExpressionStatement (ec.Report, loc);
                }
 
-               public static void Error_VoidInvalidInTheContext (Location loc)
+               public static void Error_VoidInvalidInTheContext (Location loc, Report Report)
                {
                        Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
                }
@@ -370,71 +368,84 @@ namespace Mono.CSharp {
                                return;
 
                        if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
-#if GMCS_SOURCE
                                string sig1 = type.DeclaringMethod == null ?
                                        TypeManager.CSharpName (type.DeclaringType) :
                                        TypeManager.CSharpSignature (type.DeclaringMethod);
                                string sig2 = target.DeclaringMethod == null ?
                                        TypeManager.CSharpName (target.DeclaringType) :
                                        TypeManager.CSharpSignature (target.DeclaringMethod);
-                               Report.ExtraInformation (loc,
+                               ec.Report.ExtraInformation (loc,
                                        String.Format (
                                                "The generic parameter `{0}' of `{1}' cannot be converted to the generic parameter `{0}' of `{2}' (in the previous ",
                                                Type.Name, sig1, sig2));
-#endif
                        } else if (Type.FullName == target.FullName){
-                               Report.ExtraInformation (loc,
+                               ec.Report.ExtraInformation (loc,
                                        String.Format (
                                        "The type `{0}' has two conflicting definitions, one comes from `{1}' and the other from `{2}' (in the previous ",
                                        Type.FullName, Type.Assembly.FullName, target.Assembly.FullName));
                        }
 
                        if (expl) {
-                               Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
+                               ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
                                        TypeManager.CSharpName (type), TypeManager.CSharpName (target));
                                return;
                        }
 
-                       Report.DisableReporting ();
+                       ec.Report.DisableReporting ();
                        bool expl_exists = Convert.ExplicitConversion (ec, this, target, Location.Null) != null;
-                       Report.EnableReporting ();
+                       ec.Report.EnableReporting ();
 
                        if (expl_exists) {
-                               Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
+                               ec.Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
                                              "An explicit conversion exists (are you missing a cast?)",
                                        TypeManager.CSharpName (Type), TypeManager.CSharpName (target));
                                return;
                        }
 
-                       Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
+                       ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
                                TypeManager.CSharpName (type),
                                TypeManager.CSharpName (target));
                }
 
-               public virtual void Error_VariableIsUsedBeforeItIsDeclared (string name)
+               public virtual void Error_VariableIsUsedBeforeItIsDeclared (Report Report, string name)
                {
                        Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", name);
                }
 
-               protected virtual void Error_TypeDoesNotContainDefinition (Type type, string name)
+               public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc)
                {
-                       Error_TypeDoesNotContainDefinition (loc, type, name);
+                       // Better message for possible generic expressions
+                       if (eclass == ExprClass.MethodGroup || eclass == ExprClass.Type) {
+                               if (this is TypeExpr)
+                                       report.SymbolRelatedToPreviousError (type);
+
+                               string name = eclass == ExprClass.Type ? ExprClassName : "method";
+                               report.Error (308, loc, "The non-generic {0} `{1}' cannot be used with the type arguments",
+                                       name, GetSignatureForError ());
+                       } else {
+                               report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+                                       ExprClassName, GetSignatureForError ());
+                       }
                }
 
-               public static void Error_TypeDoesNotContainDefinition (Location loc, Type type, string name)
+               protected virtual void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
                {
-                       Report.SymbolRelatedToPreviousError (type);
-                       Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'",
-                               TypeManager.CSharpName (type), name);
+                       Error_TypeDoesNotContainDefinition (ec, loc, type, name);
                }
 
-               protected static void Error_ValueAssignment (Location loc)
+               public static void Error_TypeDoesNotContainDefinition (ResolveContext ec, Location loc, Type type, string name)
                {
-                       Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
+                       ec.Report.SymbolRelatedToPreviousError (type);
+                       ec.Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'",
+                               TypeManager.CSharpName (type), name);
                }
 
-               ResolveFlags ExprClassToResolveFlags
+               protected static void Error_ValueAssignment (ResolveContext ec, Location loc)
                {
+                       ec.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
+               }
+
+               ResolveFlags ExprClassToResolveFlags {
                        get {
                                switch (eclass) {
                                case ExprClass.Type:
@@ -470,40 +481,26 @@ namespace Mono.CSharp {
                /// </remarks>
                public Expression Resolve (ResolveContext ec, ResolveFlags flags)
                {
-                       if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type) 
-                               return ResolveAsTypeStep (ec, false);
-
-                       bool do_flow_analysis = ec.DoFlowAnalysis;
-                       bool omit_struct_analysis = ec.OmitStructFlowAnalysis;
-                       if ((flags & ResolveFlags.DisableFlowAnalysis) != 0)
-                               do_flow_analysis = false;
-                       if ((flags & ResolveFlags.DisableStructFlowAnalysis) != 0)
-                               omit_struct_analysis = true;
+                       if (eclass != ExprClass.Unresolved)
+                               return this;
 
                        Expression e;
-                       using (ec.WithFlowAnalysis (do_flow_analysis, omit_struct_analysis)) {
-                               if (this is SimpleName) {
-                                       bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
-                                       e = ((SimpleName) this).DoResolve (ec, intermediate);
-                               } else {
-                                       e = DoResolve (ec);
-                               }
+                       if (this is SimpleName) {
+                               e = ((SimpleName) this).DoResolve (ec, (flags & ResolveFlags.Intermediate) != 0);
+                       } else {
+                               e = DoResolve (ec);
                        }
 
                        if (e == null)
                                return null;
 
                        if ((flags & e.ExprClassToResolveFlags) == 0) {
-                               e.Error_UnexpectedKind (flags, loc);
+                               e.Error_UnexpectedKind (ec, flags, loc);
                                return null;
                        }
 
-                       if (e.type == null && !(e is Namespace)) {
-                               throw new Exception (
-                                       "Expression " + e.GetType () +
-                                       " did not set its type after Resolve\n" +
-                                       "called from: " + this.GetType ());
-                       }
+                       if (e.type == null)
+                               throw new InternalErrorException ("Expression `{0}' didn't set its type in DoResolve", e.GetType ());
 
                        return e;
                }
@@ -511,33 +508,9 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Resolves an expression and performs semantic analysis on it.
                /// </summary>
-               public Expression Resolve (ResolveContext ec)
+               public Expression Resolve (ResolveContext rc)
                {
-                       Expression e = Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-
-                       if (e != null && e.eclass == ExprClass.MethodGroup && RootContext.Version == LanguageVersion.ISO_1) {
-                               ((MethodGroupExpr) e).ReportUsageError ();
-                               return null;
-                       }
-                       return e;
-               }
-
-               public Constant ResolveAsConstant (ResolveContext ec, MemberCore mc)
-               {
-                       Expression e = Resolve (ec);
-                       if (e == null)
-                               return null;
-
-                       Constant c = e as Constant;
-                       if (c != null)
-                               return c;
-
-                       if (type != null && TypeManager.IsReferenceType (type))
-                               Const.Error_ConstantCanBeInitializedWithNullOnly (type, loc, mc.GetSignatureForError ());
-                       else
-                               Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
-
-                       return null;
+                       return Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
                }
 
                /// <summary>
@@ -550,8 +523,8 @@ namespace Mono.CSharp {
                /// </remarks>
                public Expression ResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       int errors = Report.Errors;
-                       bool out_access = right_side == EmptyExpression.OutAccess;
+                       int errors = ec.Report.Errors;
+                       bool out_access = right_side == EmptyExpression.OutAccess.Instance;
 
                        Expression e = DoResolveLValue (ec, right_side);
 
@@ -565,16 +538,16 @@ namespace Mono.CSharp {
                        }
 
                        if (e == null) {
-                               if (errors == Report.Errors) {
+                               if (errors == ec.Report.Errors) {
                                        if (out_access)
-                                               Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
+                                               ec.Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
                                        else
-                                               Error_ValueAssignment (loc);
+                                               Error_ValueAssignment (ec, loc);
                                }
                                return null;
                        }
 
-                       if (e.eclass == ExprClass.Invalid)
+                       if (e.eclass == ExprClass.Unresolved)
                                throw new Exception ("Expression " + e + " ExprClass is Invalid after resolve");
 
                        if ((e.type == null) && !(e is GenericTypeExpr))
@@ -619,8 +592,6 @@ namespace Mono.CSharp {
 
                protected Expression ()
                {
-                       eclass = ExprClass.Invalid;
-                       type = null;
                }
 
                /// <summary>
@@ -630,14 +601,15 @@ namespace Mono.CSharp {
                public static Expression ExprClassFromMemberInfo (Type container_type, MemberInfo mi, Location loc)
                {
                        if (mi is EventInfo)
-                               return new EventExpr ((EventInfo) mi, loc);
+                               return new EventExpr (Import.CreateEvent ((EventInfo) mi), loc);
                        else if (mi is FieldInfo) {
                                FieldInfo fi = (FieldInfo) mi;
-                               if (fi.IsLiteral || (fi.IsInitOnly && fi.FieldType == TypeManager.decimal_type))
-                                       return new ConstantExpr (fi, loc);
-                               return new FieldExpr (fi, loc);
+                               var spec = Import.CreateField (fi);
+                               if (spec is ConstSpec)
+                                       return new ConstantExpr ((ConstSpec) spec, loc);
+                               return new FieldExpr (spec, loc);
                        } else if (mi is PropertyInfo)
-                               return new PropertyExpr (container_type, (PropertyInfo) mi, loc);
+                               return new PropertyExpr (container_type, Import.CreateProperty ((PropertyInfo) mi), loc);
                        else if (mi is Type) {
                                return new TypeExpression ((System.Type) mi, loc);
                        }
@@ -646,7 +618,7 @@ namespace Mono.CSharp {
                }
 
                // TODO: [Obsolete ("Can be removed")]
-               protected static ArrayList almost_matched_members = new ArrayList (4);
+               protected static IList<MemberInfo> almost_matched_members = new List<MemberInfo> (4);
 
                //
                // FIXME: Probably implement a cache for (t,name,current_access_set)?
@@ -676,10 +648,10 @@ namespace Mono.CSharp {
                // FIXME: Potential optimization, have a static ArrayList
                //
 
-               public static Expression MemberLookup (Type container_type, Type queried_type, string name,
+               public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type, string name,
                                                       MemberTypes mt, BindingFlags bf, Location loc)
                {
-                       return MemberLookup (container_type, null, queried_type, name, mt, bf, loc);
+                       return MemberLookup (ctx, container_type, null, queried_type, name, mt, bf, loc);
                }
 
                //
@@ -687,7 +659,7 @@ namespace Mono.CSharp {
                // `qualifier_type' or null to lookup members in the current class.
                //
 
-               public static Expression MemberLookup (Type container_type,
+               public static Expression MemberLookup (CompilerContext ctx, Type container_type,
                                                       Type qualifier_type, Type queried_type,
                                                       string name, MemberTypes mt,
                                                       BindingFlags bf, Location loc)
@@ -702,21 +674,21 @@ namespace Mono.CSharp {
 
                        if (mi.Length > 1) {
                                bool is_interface = qualifier_type != null && qualifier_type.IsInterface;
-                               ArrayList methods = new ArrayList (2);
-                               ArrayList non_methods = null;
+                               var methods = new List<MethodSpec> (2);
+                               List<MemberInfo> non_methods = null;
 
-                               foreach (MemberInfo m in mi) {
+                               foreach (var m in mi) {
                                        if (m is MethodBase) {
-                                               methods.Add (m);
+                                               methods.Add (Import.CreateMethod ((MethodBase) m));
                                                continue;
                                        }
 
                                        if (non_methods == null)
-                                               non_methods = new ArrayList (2);
+                                               non_methods = new List<MemberInfo> (2);
 
                                        bool is_candidate = true;
                                        for (int i = 0; i < non_methods.Count; ++i) {
-                                               MemberInfo n_m = (MemberInfo) non_methods [i];
+                                               MemberInfo n_m = non_methods [i];
                                                if (n_m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType)) {
                                                        non_methods.Remove (n_m);
                                                        --i;
@@ -732,11 +704,11 @@ namespace Mono.CSharp {
                                }
                                
                                if (methods.Count == 0 && non_methods != null && non_methods.Count > 1) {
-                                       Report.SymbolRelatedToPreviousError ((MemberInfo)non_methods [1]);
-                                       Report.SymbolRelatedToPreviousError ((MemberInfo)non_methods [0]);
-                                       Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
-                                               TypeManager.GetFullNameSignature ((MemberInfo)non_methods [1]),
-                                               TypeManager.GetFullNameSignature ((MemberInfo)non_methods [0]));
+                                       ctx.Report.SymbolRelatedToPreviousError (non_methods [1]);
+                                       ctx.Report.SymbolRelatedToPreviousError (non_methods [0]);
+                                       ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+                                               TypeManager.GetFullNameSignature (non_methods [1]),
+                                               TypeManager.GetFullNameSignature (non_methods [0]));
                                        return null;
                                }
 
@@ -744,23 +716,23 @@ namespace Mono.CSharp {
                                        return ExprClassFromMemberInfo (container_type, (MemberInfo)non_methods [0], loc);
 
                                if (non_methods != null && non_methods.Count > 0) {
-                                       MethodBase method = (MethodBase) methods [0];
+                                       var method = methods [0];
                                        MemberInfo non_method = (MemberInfo) non_methods [0];
                                        if (method.DeclaringType == non_method.DeclaringType) {
                                                // Cannot happen with C# code, but is valid in IL
-                                               Report.SymbolRelatedToPreviousError (method);
-                                               Report.SymbolRelatedToPreviousError (non_method);
-                                               Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+                                               ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+                                               ctx.Report.SymbolRelatedToPreviousError (non_method);
+                                               ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
                                                              TypeManager.GetFullNameSignature (non_method),
-                                                             TypeManager.CSharpSignature (method));
+                                                             TypeManager.CSharpSignature (method.MetaInfo));
                                                return null;
                                        }
 
                                        if (is_interface) {
-                                               Report.SymbolRelatedToPreviousError (method);
-                                               Report.SymbolRelatedToPreviousError (non_method);
-                                               Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
-                                                               TypeManager.CSharpSignature (method), TypeManager.GetFullNameSignature (non_method));
+                                               ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+                                               ctx.Report.SymbolRelatedToPreviousError (non_method);
+                                               ctx.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+                                                               TypeManager.CSharpSignature (method.MetaInfo), TypeManager.GetFullNameSignature (non_method));
                                        }
                                }
 
@@ -768,7 +740,7 @@ namespace Mono.CSharp {
                        }
 
                        if (mi [0] is MethodBase)
-                               return new MethodGroupExpr (mi, queried_type, loc);
+                               return new MethodGroupExpr (mi.Select (l => Import.CreateMethod ((MethodBase) l)).ToArray (), queried_type, loc);
 
                        return ExprClassFromMemberInfo (container_type, mi [0], loc);
                }
@@ -786,24 +758,24 @@ namespace Mono.CSharp {
                        BindingFlags.Static |
                        BindingFlags.Instance;
 
-               public static Expression MemberLookup (Type container_type, Type queried_type,
+               public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type,
                                                       string name, Location loc)
                {
-                       return MemberLookup (container_type, null, queried_type, name,
+                       return MemberLookup (ctx, container_type, null, queried_type, name,
                                             AllMemberTypes, AllBindingFlags, loc);
                }
 
-               public static Expression MemberLookup (Type container_type, Type qualifier_type,
+               public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type qualifier_type,
                                                       Type queried_type, string name, Location loc)
                {
-                       return MemberLookup (container_type, qualifier_type, queried_type,
+                       return MemberLookup (ctx, container_type, qualifier_type, queried_type,
                                             name, AllMemberTypes, AllBindingFlags, loc);
                }
 
-               public static MethodGroupExpr MethodLookup (Type container_type, Type queried_type,
+               public static MethodGroupExpr MethodLookup (CompilerContext ctx, Type container_type, Type queried_type,
                                                       string name, Location loc)
                {
-                       return (MethodGroupExpr)MemberLookup (container_type, null, queried_type, name,
+                       return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name,
                                             MemberTypes.Method, AllBindingFlags, loc);
                }
 
@@ -820,18 +792,18 @@ namespace Mono.CSharp {
                {
                        Expression e;
 
-                       int errors = Report.Errors;
-                       e = MemberLookup (ec.CurrentType, qualifier_type, queried_type, name, mt, bf, loc);
+                       int errors = ec.Report.Errors;
+                       e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, mt, bf, loc);
 
-                       if (e != null || errors != Report.Errors)
+                       if (e != null || errors != ec.Report.Errors)
                                return e;
 
                        // No errors were reported by MemberLookup, but there was an error.
-                       return Error_MemberLookupFailed (ec.CurrentType, qualifier_type, queried_type,
+                       return Error_MemberLookupFailed (ec, ec.CurrentType, qualifier_type, queried_type,
                                        name, null, mt, bf);
                }
 
-               protected virtual Expression Error_MemberLookupFailed (Type container_type, Type qualifier_type,
+               protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type container_type, Type qualifier_type,
                                                       Type queried_type, string name, string class_name,
                                                           MemberTypes mt, BindingFlags bf)
                {
@@ -844,7 +816,7 @@ namespace Mono.CSharp {
                                        name, null);
 
                                if (lookup != null) {
-                                       Expression e = Error_MemberLookupFailed (queried_type, lookup);
+                                       Expression e = Error_MemberLookupFailed (ec, queried_type, lookup);
 
                                        //
                                        // FIXME: This is still very wrong, it should be done inside
@@ -853,7 +825,7 @@ namespace Mono.CSharp {
                                        //
                                        if (e == null || (mt & (MemberTypes.Method | MemberTypes.Constructor)) == 0) {
                                                MemberInfo mi = lookup[0];
-                                               Report.SymbolRelatedToPreviousError (mi);
+                                               ec.Report.SymbolRelatedToPreviousError (mi);
                                                if (qualifier_type != null && container_type != null && qualifier_type != container_type &&
                                                        TypeManager.IsNestedFamilyAccessible (container_type, mi.DeclaringType)) {
                                                        // Although a derived class can access protected members of
@@ -861,9 +833,9 @@ namespace Mono.CSharp {
                                                        // base class (CS1540).  If the qualifier_type is a base of the
                                                        // ec.CurrentType and the lookup succeeds with the latter one,
                                                        // then we are in this situation.
-                                                       Error_CannotAccessProtected (loc, mi, qualifier_type, container_type);
+                                                       Error_CannotAccessProtected (ec, loc, mi, qualifier_type, container_type);
                                                } else {
-                                                       ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi));
+                                                       ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi), ec.Report);
                                                }
                                        }
 
@@ -877,10 +849,10 @@ namespace Mono.CSharp {
 
                        if (lookup == null) {
                                if (class_name != null) {
-                                       Report.Error (103, loc, "The name `{0}' does not exist in the current context",
+                                       ec.Report.Error (103, loc, "The name `{0}' does not exist in the current context",
                                                name);
                                } else {
-                                       Error_TypeDoesNotContainDefinition (queried_type, name);
+                                       Error_TypeDoesNotContainDefinition (ec, queried_type, name);
                                }
                                return null;
                        }
@@ -891,7 +863,7 @@ namespace Mono.CSharp {
                                if ((lookup.Length == 1) && (lookup [0] is Type)) {
                                        Type t = (Type) lookup [0];
 
-                                       Report.Error (305, loc,
+                                       ec.Report.Error (305, loc,
                                                      "Using the generic type `{0}' " +
                                                      "requires {1} type arguments",
                                                      TypeManager.CSharpName (t),
@@ -900,35 +872,38 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       return Error_MemberLookupFailed (queried_type, lookup);
+                       return Error_MemberLookupFailed (ec, queried_type, lookup);
                }
 
-               protected virtual Expression Error_MemberLookupFailed (Type type, MemberInfo[] members)
+               protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
                {
+                       List<MethodSpec> methods = new List<MethodSpec> ();
                        for (int i = 0; i < members.Length; ++i) {
                                if (!(members [i] is MethodBase))
                                        return null;
+
+                               methods.Add (Import.CreateMethod (members[i] as MethodBase));
                        }
 
                        // By default propagate the closest candidates upwards
-                       return new MethodGroupExpr (members, type, loc, true);
+                       return new MethodGroupExpr (methods.ToArray (), type, loc, true);
                }
 
-               protected virtual void Error_NegativeArrayIndex (Location loc)
+               protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
                {
                        throw new NotImplementedException ();
                }
 
-               protected void Error_PointerInsideExpressionTree ()
+               protected void Error_PointerInsideExpressionTree (ResolveContext ec)
                {
-                       Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
+                       ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
                }
 
                /// <summary>
                ///   Returns an expression that can be used to invoke operator true
                ///   on the expression if it exists.
                /// </summary>
-               static public Expression GetOperatorTrue (ResolveContext ec, Expression e, Location loc)
+               protected static Expression GetOperatorTrue (ResolveContext ec, Expression e, Location loc)
                {
                        return GetOperatorTrueOrFalse (ec, e, true, loc);
                }
@@ -946,7 +921,7 @@ namespace Mono.CSharp {
                {
                        MethodGroupExpr operator_group;
                        string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
-                       operator_group = MethodLookup (ec.CurrentType, e.Type, mname, loc) as MethodGroupExpr;
+                       operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, mname, loc) as MethodGroupExpr;
                        if (operator_group == null)
                                return null;
 
@@ -961,47 +936,12 @@ namespace Mono.CSharp {
                        return new UserOperatorCall (operator_group, arguments, null, loc);
                }
 
-               /// <summary>
-               ///   Resolves the expression `e' into a boolean expression: either through
-               ///   an implicit conversion, or through an `operator true' invocation
-               /// </summary>
-               public static Expression ResolveBoolean (ResolveContext ec, Expression e, Location loc)
-               {
-                       e = e.Resolve (ec);
-                       if (e == null)
-                               return null;
-
-                       if (e.Type == TypeManager.bool_type)
-                               return e;
-
-                       if (TypeManager.IsDynamicType (e.Type)) {
-                               Arguments args = new Arguments (1);
-                               args.Add (new Argument (e));
-                               return new DynamicUnaryConversion ("IsTrue", args, loc);
-                       }
-
-                       Expression converted = Convert.ImplicitConversion (ec, e, TypeManager.bool_type, Location.Null);
-
-                       if (converted != null)
-                               return converted;
-
-                       //
-                       // If no implicit conversion to bool exists, try using `operator true'
-                       //
-                       converted = Expression.GetOperatorTrue (ec, e, loc);
-                       if (converted == null){
-                               e.Error_ValueCannotBeConverted (ec, loc, TypeManager.bool_type, false);
-                               return null;
-                       }
-                       return converted;
-               }
-               
                public virtual string ExprClassName
                {
                        get {
                                switch (eclass){
-                               case ExprClass.Invalid:
-                                       return "Invalid";
+                               case ExprClass.Unresolved:
+                                       return "Unresolved";
                                case ExprClass.Value:
                                        return "value";
                                case ExprClass.Variable:
@@ -1030,12 +970,12 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Reports that we were expecting `expr' to be of class `expected'
                /// </summary>
-               public void Error_UnexpectedKind (MemberCore mc, string expected, Location loc)
+               public void Error_UnexpectedKind (Report r, MemberCore mc, string expected, Location loc)
                {
-                       Error_UnexpectedKind (mc, expected, ExprClassName, loc);
+                       Error_UnexpectedKind (r, mc, expected, ExprClassName, loc);
                }
 
-               public void Error_UnexpectedKind (MemberCore mc, string expected, string was, Location loc)
+               public void Error_UnexpectedKind (Report r, MemberCore mc, string expected, string was, Location loc)
                {
                        string name;
                        if (mc != null)
@@ -1043,11 +983,11 @@ namespace Mono.CSharp {
                        else
                                name = GetSignatureForError ();
 
-                       Report.Error (118, loc, "`{0}' is a `{1}' but a `{2}' was expected",
+                       r.Error (118, loc, "`{0}' is a `{1}' but a `{2}' was expected",
                              name, was, expected);
                }
 
-               public void Error_UnexpectedKind (ResolveFlags flags, Location loc)
+               public void Error_UnexpectedKind (ResolveContext ec, ResolveFlags flags, Location loc)
                {
                        string [] valid = new string [4];
                        int count = 0;
@@ -1076,11 +1016,16 @@ namespace Mono.CSharp {
                                sb.Append (valid [count - 1]);
                        }
 
-                       Report.Error (119, loc, 
+                       ec.Report.Error (119, loc, 
                                "Expression denotes a `{0}', where a `{1}' was expected", ExprClassName, sb.ToString ());
                }
                
-               public static void UnsafeError (Location loc)
+               public static void UnsafeError (ResolveContext ec, Location loc)
+               {
+                       UnsafeError (ec.Report, loc);
+               }
+
+               public static void UnsafeError (Report Report, Location loc)
                {
                        Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
                }
@@ -1186,29 +1131,23 @@ namespace Mono.CSharp {
                                return 0;
                }
 
-               protected void Error_CannotCallAbstractBase (string name)
+               protected void Error_CannotCallAbstractBase (ResolveContext ec, string name)
                {
-                       Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
+                       ec.Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
                }
                
                protected void Error_CannotModifyIntermediateExpressionValue (ResolveContext ec)
                {
-                       Report.SymbolRelatedToPreviousError (type);
+                       ec.Report.SymbolRelatedToPreviousError (type);
                        if (ec.CurrentInitializerVariable != null) {
-                               Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+                               ec.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
                                        TypeManager.CSharpName (type), GetSignatureForError ());
                        } else {
-                               Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
+                               ec.Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
                                        GetSignatureForError ());
                        }
                }
 
-               public void Error_ExpressionCannotBeGeneric (Location loc)
-               {
-                       Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
-                               ExprClassName, GetSignatureForError ());
-               }
-
                //
                // Converts `source' to an int, uint, long or ulong.
                //
@@ -1217,7 +1156,7 @@ namespace Mono.CSharp {
                        if (TypeManager.IsDynamicType (source.type)) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (source));
-                               return new DynamicConversion (TypeManager.int32_type, false, args, loc).Resolve (ec);
+                               return new DynamicConversion (TypeManager.int32_type, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
                        }
 
                        Expression converted;
@@ -1241,12 +1180,12 @@ namespace Mono.CSharp {
                        // Only positive constants are allowed at compile time
                        //
                        Constant c = converted as Constant;
-                       if (c != null) {
-                               if (c.IsNegative) {
-                                       Error_NegativeArrayIndex (source.loc);
-                               }
-                               return c;
-                       }
+                       if (c != null && c.IsNegative)
+                               Error_NegativeArrayIndex (ec, source.loc);
+
+                       // No conversion needed to array index
+                       if (converted.Type == TypeManager.int32_type)
+                               return converted;
 
                        return new ArrayIndexCast (converted).Resolve (ec);
                }
@@ -1289,26 +1228,26 @@ namespace Mono.CSharp {
                //
                public abstract Expression CreateExpressionTree (ResolveContext ec);
 
-               protected Expression CreateExpressionFactoryCall (string name, Arguments args)
+               protected Expression CreateExpressionFactoryCall (ResolveContext ec, string name, Arguments args)
                {
-                       return CreateExpressionFactoryCall (name, null, args, loc);
+                       return CreateExpressionFactoryCall (ec, name, null, args, loc);
                }
 
-               protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args)
+               protected Expression CreateExpressionFactoryCall (ResolveContext ec, string name, TypeArguments typeArguments, Arguments args)
                {
-                       return CreateExpressionFactoryCall (name, typeArguments, args, loc);
+                       return CreateExpressionFactoryCall (ec, name, typeArguments, args, loc);
                }
 
-               public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args, Location loc)
+               public static Expression CreateExpressionFactoryCall (ResolveContext ec, string name, TypeArguments typeArguments, Arguments args, Location loc)
                {
-                       return new Invocation (new MemberAccess (CreateExpressionTypeExpression (loc), name, typeArguments, loc), args);
+                       return new Invocation (new MemberAccess (CreateExpressionTypeExpression (ec, loc), name, typeArguments, loc), args);
                }
 
-               protected static TypeExpr CreateExpressionTypeExpression (Location loc)
+               protected static TypeExpr CreateExpressionTypeExpression (ResolveContext ec, Location loc)
                {
                        TypeExpr texpr = TypeManager.expression_type_expr;
                        if (texpr == null) {
-                               Type t = TypeManager.CoreLookupType ("System.Linq.Expressions", "Expression", Kind.Class, true);
+                               Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
                                if (t == null)
                                        return null;
 
@@ -1318,6 +1257,16 @@ namespace Mono.CSharp {
                        return texpr;
                }
 
+               //
+               // Implemented by all expressions which support conversion from
+               // compiler expression to invokable runtime expression. Used by
+               // dynamic C# binder.
+               //
+               public virtual SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       throw new NotImplementedException ("MakeExpression for " + GetType ());
+               }
+
                public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        // TODO: It should probably be type = storey.MutateType (type);
@@ -1341,7 +1290,7 @@ namespace Mono.CSharp {
 
                        ExpressionStatement es = e as ExpressionStatement;
                        if (es == null)
-                               Error_InvalidExpressionStatement ();
+                               Error_InvalidExpressionStatement (ec);
 
                        return es;
                }
@@ -1391,12 +1340,12 @@ namespace Mono.CSharp {
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
 
                        if (type.IsPointer || child.Type.IsPointer)
-                               Error_PointerInsideExpressionTree ();
+                               Error_PointerInsideExpressionTree (ec);
 
-                       return CreateExpressionFactoryCall (ec.HasSet (ResolveContext.Options.CheckedScope) ? "ConvertChecked" : "Convert", args);
+                       return CreateExpressionFactoryCall (ec, ec.HasSet (ResolveContext.Options.CheckedScope) ? "ConvertChecked" : "Convert", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        // This should never be invoked, we are born in fully
                        // initialized state.
@@ -1414,6 +1363,13 @@ namespace Mono.CSharp {
                        return child.GetAttributableValue (ec, value_type, out value);
                }
 
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       return ctx.HasSet (BuilderContext.Options.CheckedScope) ?
+                               SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type) :
+                               SLE.Expression.Convert (child.MakeExpression (ctx), type);
+               }
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        type = storey.MutateType (type);
@@ -1532,7 +1488,7 @@ namespace Mono.CSharp {
        /// </summary>
        public class CastFromDecimal : TypeCast
        {
-               static IDictionary operators;
+               static Dictionary<Type, MethodInfo> operators;
 
                public CastFromDecimal (Expression child, Type return_type)
                        : base (child, return_type)
@@ -1547,11 +1503,11 @@ namespace Mono.CSharp {
                public Expression Resolve ()
                {
                        if (operators == null) {
-                                MemberInfo[] all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
-                                       TypeManager.decimal_type, TypeManager.decimal_type, MemberTypes.Method,
-                                       BindingFlags.Static | BindingFlags.Public, "op_Explicit", null);
+                               MemberInfo[] all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
+                                  TypeManager.decimal_type, TypeManager.decimal_type, MemberTypes.Method,
+                                  BindingFlags.Static | BindingFlags.Public, "op_Explicit", null);
 
-                               operators = new System.Collections.Specialized.HybridDictionary ();
+                               operators = new Dictionary<Type, MethodInfo> (ReferenceEquality<Type>.Default);
                                foreach (MethodInfo oper in all_oper) {
                                        AParametersCollection pd = TypeManager.GetParameterData (oper);
                                        if (pd.Types [0] == TypeManager.decimal_type)
@@ -1559,7 +1515,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       return operators.Contains (type) ? this : null;
+                       return operators.ContainsKey (type) ? this : null;
                }
 
                public override void Emit (EmitContext ec)
@@ -1567,7 +1523,7 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        child.Emit (ec);
 
-                       ig.Emit (OpCodes.Call, (MethodInfo)operators [type]);
+                       ig.Emit (OpCodes.Call, operators [type]);
                }
        }
 
@@ -1579,13 +1535,16 @@ namespace Mono.CSharp {
        //
        public class EmptyConstantCast : Constant
        {
-               public readonly Constant child;
+               public Constant child;
 
-               public EmptyConstantCast(Constant child, Type type)
+               public EmptyConstantCast (Constant child, Type type)
                        : base (child.Location)
                {
-                       eclass = child.eclass;
+                       if (child == null)
+                               throw new ArgumentNullException ("child");
+
                        this.child = child;
+                       this.eclass = child.eclass;
                        this.type = type;
                }
 
@@ -1601,6 +1560,9 @@ namespace Mono.CSharp {
 
                public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
                {
+                       if (child.Type == target_type)
+                               return child;
+
                        // FIXME: check that 'type' can be converted to 'target_type' first
                        return child.ConvertExplicitly (in_checked_context, target_type);
                }
@@ -1612,14 +1574,9 @@ namespace Mono.CSharp {
                                new TypeOf (new TypeExpression (type, loc), loc));
 
                        if (type.IsPointer)
-                               Error_PointerInsideExpressionTree ();
-
-                       return CreateExpressionFactoryCall ("Convert", args);
-               }
+                               Error_PointerInsideExpressionTree (ec);
 
-               public override Constant Increment ()
-               {
-                       return child.Increment ();
+                       return CreateExpressionFactoryCall (ec, "Convert", args);
                }
 
                public override bool IsDefaultValue {
@@ -1633,10 +1590,19 @@ namespace Mono.CSharp {
                public override bool IsNull {
                        get { return child.IsNull; }
                }
+               
+               public override bool IsOneInteger {
+                       get { return child.IsOneInteger; }
+               }
 
                public override bool IsZeroInteger {
                        get { return child.IsZeroInteger; }
                }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       return this;
+               }
                
                public override void Emit (EmitContext ec)
                {
@@ -1647,11 +1613,9 @@ namespace Mono.CSharp {
                {
                        child.EmitBranchable (ec, label, on_true);
 
-#if GMCS_SOURCE
                        // Only to make verifier happy
                        if (TypeManager.IsGenericParameter (type) && child.IsNull)
                                ec.ig.Emit (OpCodes.Unbox_Any, type);
-#endif
                }
 
                public override void EmitSideEffect (EmitContext ec)
@@ -1659,12 +1623,12 @@ namespace Mono.CSharp {
                        child.EmitSideEffect (ec);
                }
 
-               public override Constant ConvertImplicitly (Type target_type)
+               public override Constant ConvertImplicitly (ResolveContext rc, Type target_type)
                {
                        // FIXME: Do we need to check user conversions?
                        if (!Convert.ImplicitStandardConversionExists (this, target_type))
                                return null;
-                       return child.ConvertImplicitly (target_type);
+                       return child.ConvertImplicitly (rc, target_type);
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -1673,26 +1637,29 @@ namespace Mono.CSharp {
                }
        }
 
-
        /// <summary>
        ///  This class is used to wrap literals which belong inside Enums
        /// </summary>
-       public class EnumConstant : Constant {
+       public class EnumConstant : Constant
+       {
                public Constant Child;
 
-               public EnumConstant (Constant child, Type enum_type):
-                       base (child.Location)
+               public EnumConstant (Constant child, Type enum_type)
+                       base (child.Location)
                {
-                       eclass = child.eclass;
                        this.Child = child;
-                       type = enum_type;
+                       this.type = enum_type;
                }
-               
-               public override Expression DoResolve (ResolveContext ec)
+
+               protected EnumConstant (Location loc)
+                       : base (loc)
                {
-                       // This should never be invoked, we are born in fully
-                       // initialized state.
+               }
 
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       Child = Child.Resolve (rc);
+                       this.eclass = ExprClass.Value;
                        return this;
                }
 
@@ -1742,7 +1709,7 @@ namespace Mono.CSharp {
                        //
                        // This works only sometimes
                        //
-                       if (type.Module == RootContext.ToplevelTypes.Builder)
+                       if (TypeManager.IsBeingCompiled (type))
                                return Child.GetValue ();
 #endif
 
@@ -1754,9 +1721,9 @@ namespace Mono.CSharp {
                        return Child.AsString ();
                }
 
-               public override Constant Increment()
+               public EnumConstant Increment()
                {
-                       return new EnumConstant (Child.Increment (), type);
+                       return new EnumConstant (((IntegralConstant) Child).Increment (), type);
                }
 
                public override bool IsDefaultValue {
@@ -1783,7 +1750,7 @@ namespace Mono.CSharp {
                        return Child.ConvertExplicitly (in_checked_context, target_type);
                }
 
-               public override Constant ConvertImplicitly (Type type)
+               public override Constant ConvertImplicitly (ResolveContext rc, Type type)
                {
                        Type this_type = TypeManager.DropGenericTypeArguments (Type);
                        type = TypeManager.DropGenericTypeArguments (type);
@@ -1795,7 +1762,7 @@ namespace Mono.CSharp {
 
                                Type child_type = TypeManager.DropGenericTypeArguments (Child.Type);
                                if (type.UnderlyingSystemType != child_type)
-                                       Child = Child.ConvertImplicitly (type.UnderlyingSystemType);
+                                       Child = Child.ConvertImplicitly (rc, type.UnderlyingSystemType);
                                return this;
                        }
 
@@ -1803,9 +1770,8 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       return Child.ConvertImplicitly(type);
+                       return Child.ConvertImplicitly (rc, type);
                }
-
        }
 
        /// <summary>
@@ -1822,7 +1788,7 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Value;
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        // This should never be invoked, we are born in fully
                        // initialized state.
@@ -1855,7 +1821,7 @@ namespace Mono.CSharp {
                {
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        // This should never be invoked, we are born in fully
                        // initialized state.
@@ -1866,7 +1832,7 @@ namespace Mono.CSharp {
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
                        if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
-                               Report.Error (445, loc, "Cannot modify the result of an unboxing conversion");
+                               ec.Report.Error (445, loc, "Cannot modify the result of an unboxing conversion");
                        return base.DoResolveLValue (ec, right_side);
                }
 
@@ -1875,13 +1841,7 @@ namespace Mono.CSharp {
                        base.Emit (ec);
 
                        ILGenerator ig = ec.ig;
-
-#if GMCS_SOURCE
                        ig.Emit (OpCodes.Unbox_Any, type);
-#else                  
-                       ig.Emit (OpCodes.Unbox, type);
-                       LoadFromPtr (ig, type);
-#endif                 
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -1906,11 +1866,12 @@ namespace Mono.CSharp {
                        U2_I1, U2_U1, U2_I2, U2_CH,
                        I4_I1, I4_U1, I4_I2, I4_U2, I4_U4, I4_U8, I4_CH,
                        U4_I1, U4_U1, U4_I2, U4_U2, U4_I4, U4_CH,
-                       I8_I1, I8_U1, I8_I2, I8_U2, I8_I4, I8_U4, I8_U8, I8_CH,
-                       U8_I1, U8_U1, U8_I2, U8_U2, U8_I4, U8_U4, U8_I8, U8_CH,
+                       I8_I1, I8_U1, I8_I2, I8_U2, I8_I4, I8_U4, I8_U8, I8_CH, I8_I,
+                       U8_I1, U8_U1, U8_I2, U8_U2, U8_I4, U8_U4, U8_I8, U8_CH, U8_I,
                        CH_I1, CH_U1, CH_I2,
                        R4_I1, R4_U1, R4_I2, R4_U2, R4_I4, R4_U4, R4_I8, R4_U8, R4_CH,
-                       R8_I1, R8_U1, R8_I2, R8_U2, R8_I4, R8_U4, R8_I8, R8_U8, R8_CH, R8_R4
+                       R8_I1, R8_U1, R8_I2, R8_U2, R8_I4, R8_U4, R8_I8, R8_U8, R8_CH, R8_R4,
+                       I_I8,
                }
 
                Mode mode;
@@ -1921,7 +1882,7 @@ namespace Mono.CSharp {
                        mode = m;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        // This should never be invoked, we are born in fully
                        // initialized state.
@@ -1986,6 +1947,7 @@ namespace Mono.CSharp {
                                case Mode.I8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
                                case Mode.I8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
                                case Mode.I8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I8_I: ig.Emit (OpCodes.Conv_Ovf_U); break;
 
                                case Mode.U8_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
                                case Mode.U8_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
@@ -1995,6 +1957,7 @@ namespace Mono.CSharp {
                                case Mode.U8_U4: ig.Emit (OpCodes.Conv_Ovf_U4_Un); break;
                                case Mode.U8_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
                                case Mode.U8_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+                               case Mode.U8_I: ig.Emit (OpCodes.Conv_Ovf_U_Un); break;
 
                                case Mode.CH_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
                                case Mode.CH_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
@@ -2020,6 +1983,8 @@ namespace Mono.CSharp {
                                case Mode.R8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
                                case Mode.R8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
                                case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
+
+                               case Mode.I_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
                                }
                        } else {
                                switch (mode){
@@ -2067,6 +2032,7 @@ namespace Mono.CSharp {
                                case Mode.I8_U4: ig.Emit (OpCodes.Conv_U4); break;
                                case Mode.I8_U8: /* nothing */ break;
                                case Mode.I8_CH: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I8_I: ig.Emit (OpCodes.Conv_U); break;
 
                                case Mode.U8_I1: ig.Emit (OpCodes.Conv_I1); break;
                                case Mode.U8_U1: ig.Emit (OpCodes.Conv_U1); break;
@@ -2076,6 +2042,7 @@ namespace Mono.CSharp {
                                case Mode.U8_U4: ig.Emit (OpCodes.Conv_U4); break;
                                case Mode.U8_I8: /* nothing */ break;
                                case Mode.U8_CH: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.U8_I: ig.Emit (OpCodes.Conv_U); break;
 
                                case Mode.CH_I1: ig.Emit (OpCodes.Conv_I1); break;
                                case Mode.CH_U1: ig.Emit (OpCodes.Conv_U1); break;
@@ -2101,6 +2068,8 @@ namespace Mono.CSharp {
                                case Mode.R8_U8: ig.Emit (OpCodes.Conv_U8); break;
                                case Mode.R8_CH: ig.Emit (OpCodes.Conv_U2); break;
                                case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
+
+                               case Mode.I_I8: ig.Emit (OpCodes.Conv_U8); break;
                                }
                        }
                }
@@ -2115,7 +2084,7 @@ namespace Mono.CSharp {
                        this.op = op;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        // This should never be invoked, we are born in fully
                        // initialized state.
@@ -2156,7 +2125,6 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
 
-#if GMCS_SOURCE
                        bool gen = TypeManager.IsGenericParameter (child.Type);
                        if (gen)
                                ec.ig.Emit (OpCodes.Box, child.Type);
@@ -2168,7 +2136,6 @@ namespace Mono.CSharp {
                        
                        if (gen && !forced)
                                return;
-#endif
                        
                        ec.ig.Emit (OpCodes.Castclass, type);
                }
@@ -2190,11 +2157,12 @@ namespace Mono.CSharp {
                                this.orig_expr = orig_expr;
                        }
 
-                       public override Constant ConvertImplicitly (Type target_type)
+                       public override Constant ConvertImplicitly (ResolveContext rc, Type target_type)
                        {
-                               Constant c = base.ConvertImplicitly (target_type);
+                               Constant c = base.ConvertImplicitly (rc, target_type);
                                if (c != null)
                                        c = new ReducedConstantExpression (c, orig_expr);
+
                                return c;
                        }
 
@@ -2209,7 +2177,7 @@ namespace Mono.CSharp {
                                // Even if resolved result is a constant original expression was not
                                // and attribute accepts constants only
                                //
-                               Attribute.Error_AttributeArgumentNotValid (orig_expr.Location);
+                               Attribute.Error_AttributeArgumentNotValid (ec, orig_expr.Location);
                                value = null;
                                return false;
                        }
@@ -2240,7 +2208,7 @@ namespace Mono.CSharp {
                                return orig_expr.CreateExpressionTree (ec);
                        }
 
-                       public override Expression DoResolve (ResolveContext ec)
+                       protected override Expression DoResolve (ResolveContext ec)
                        {
                                eclass = stm.eclass;
                                type = stm.Type;
@@ -2268,12 +2236,20 @@ namespace Mono.CSharp {
                private ReducedExpression (Expression expr, Expression orig_expr)
                {
                        this.expr = expr;
+                       this.eclass = expr.eclass;
+                       this.type = expr.Type;
                        this.orig_expr = orig_expr;
                        this.loc = orig_expr.Location;
                }
 
+               //
+               // Creates fully resolved expression switcher
+               //
                public static Constant Create (Constant expr, Expression original_expr)
                {
+                       if (expr.eclass == ExprClass.Unresolved)
+                               throw new ArgumentException ("Unresolved expression");
+
                        return new ReducedConstantExpression (expr, original_expr);
                }
 
@@ -2282,6 +2258,10 @@ namespace Mono.CSharp {
                        return new ReducedExpressionStatement (s, orig);
                }
 
+               //
+               // Creates unresolved reduce expression. The original expression has to be
+               // already resolved
+               //
                public static Expression Create (Expression expr, Expression original_expr)
                {
                        Constant c = expr as Constant;
@@ -2292,6 +2272,9 @@ namespace Mono.CSharp {
                        if (s != null)
                                return Create (s, original_expr);
 
+                       if (expr.eclass == ExprClass.Unresolved)
+                               throw new ArgumentException ("Unresolved expression");
+
                        return new ReducedExpression (expr, original_expr);
                }
 
@@ -2300,10 +2283,8 @@ namespace Mono.CSharp {
                        return orig_expr.CreateExpressionTree (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       eclass = expr.eclass;
-                       type = expr.Type;
                        return this;
                }
 
@@ -2317,12 +2298,101 @@ namespace Mono.CSharp {
                        expr.EmitBranchable (ec, target, on_true);
                }
 
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       return orig_expr.MakeExpression (ctx);
+               }
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        expr.MutateHoistedGenericType (storey);
                }
        }
 
+       //
+       // Standard composite pattern
+       //
+       public abstract class CompositeExpression : Expression
+       {
+               Expression expr;
+
+               protected CompositeExpression (Expression expr)
+               {
+                       this.expr = expr;
+                       this.loc = expr.Location;
+               }
+
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       return expr.CreateExpressionTree (ec);
+               }
+
+               public Expression Child {
+                       get { return expr; }
+               }
+
+               protected override Expression DoResolve (ResolveContext ec)
+               {
+                       expr = expr.Resolve (ec);
+                       if (expr != null) {
+                               type = expr.Type;
+                               eclass = expr.eclass;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       expr.Emit (ec);
+               }
+
+               public override bool IsNull {
+                       get { return expr.IsNull; }
+               }
+       }
+
+       //
+       // Base of expressions used only to narrow resolve flow
+       //
+       public abstract class ShimExpression : Expression
+       {
+               protected Expression expr;
+
+               protected ShimExpression (Expression expr)
+               {
+                       this.expr = expr;
+               }
+
+               protected override void CloneTo (CloneContext clonectx, Expression t)
+               {
+                       if (expr == null)
+                               return;
+
+                       ShimExpression target = (ShimExpression) t;
+                       target.expr = expr.Clone (clonectx);
+               }
+
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       throw new NotSupportedException ("ET");
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new InternalErrorException ("Missing Resolve call");
+               }
+
+               public Expression Expr {
+                       get { return expr; }
+               }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       throw new InternalErrorException ("Missing Resolve call");
+               }
+       }
+
        //
        // Unresolved type name expressions
        //
@@ -2392,9 +2462,8 @@ namespace Mono.CSharp {
        ///   SimpleName expressions are formed of a single word and only happen at the beginning 
        ///   of a dotted-name.
        /// </summary>
-       public class SimpleName : ATypeNameExpression {
-               bool in_transit;
-
+       public class SimpleName : ATypeNameExpression
+       {
                public SimpleName (string name, Location l)
                        : base (name, l)
                {
@@ -2449,11 +2518,11 @@ namespace Mono.CSharp {
                public static void Error_ObjectRefRequired (ResolveContext ec, Location l, string name)
                {
                        if (ec.HasSet (ResolveContext.Options.FieldInitializerScope))
-                               Report.Error (236, l,
+                               ec.Report.Error (236, l,
                                        "A field initializer cannot reference the nonstatic field, method, or property `{0}'",
                                        name);
                        else
-                               Report.Error (120, l,
+                               ec.Report.Error (120, l,
                                        "An object reference is required to access non-static member `{0}'",
                                        name);
                }
@@ -2465,7 +2534,7 @@ namespace Mono.CSharp {
                                (mc.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return SimpleNameResolve (ec, null, false);
                }
@@ -2474,7 +2543,6 @@ namespace Mono.CSharp {
                {
                        return SimpleNameResolve (ec, right_side, false);
                }
-               
 
                public Expression DoResolve (ResolveContext ec, bool intermediate)
                {
@@ -2493,17 +2561,14 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               FullNamedExpression ResolveNested (IMemberContext ec, Type t)
+               FullNamedExpression ResolveNested (Type t)
                {
                        if (!TypeManager.IsGenericTypeDefinition (t) && !TypeManager.IsGenericType (t))
                                return null;
 
-                       if (ec.CurrentType == null)
-                               return null;
-
-                       DeclSpace ds = ec.CurrentTypeDefinition;
-                       while (ds != null && !IsNestedChild (t, ds.TypeBuilder))
-                               ds = ds.Parent;
+                       Type ds = t;
+                       while (ds != null && !IsNestedChild (t, ds))
+                               ds = ds.DeclaringType;
 
                        if (ds == null)
                                return null;
@@ -2512,11 +2577,12 @@ namespace Mono.CSharp {
 
                        int arg_count = targs != null ? targs.Count : 0;
 
-                       for (; (ds != null) && ds.IsGeneric; ds = ds.Parent) {
-                               if (arg_count + ds.CountTypeParameters == gen_params.Length) {
+                       for (; (ds != null) && TypeManager.IsGenericType (ds); ds = ds.DeclaringType) {
+                               Type[] gargs = TypeManager.GetTypeArguments (ds);
+                               if (arg_count + gargs.Length == gen_params.Length) {
                                        TypeArguments new_args = new TypeArguments ();
-                                       foreach (TypeParameter param in ds.TypeParameters)
-                                               new_args.Add (new TypeParameterExpr (param, loc));
+                                       foreach (Type param in gargs)
+                                               new_args.Add (new TypeExpression (param, loc));
 
                                        if (targs != null)
                                                new_args.Add (targs);
@@ -2530,29 +2596,43 @@ namespace Mono.CSharp {
 
                public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
                {
-                       int errors = Report.Errors;
+                       int errors = ec.Compiler.Report.Errors;
                        FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
 
                        if (fne != null) {
                                if (fne.Type == null)
                                        return fne;
 
-                               FullNamedExpression nested = ResolveNested (ec, fne.Type);
+                               FullNamedExpression nested = ResolveNested (fne.Type);
                                if (nested != null)
                                        return nested.ResolveAsTypeStep (ec, false);
 
                                if (targs != null) {
-                                       GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
-                                       return ct.ResolveAsTypeStep (ec, false);
+                                       if (TypeManager.IsGenericType (fne.Type)) {
+                                               GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
+                                               return ct.ResolveAsTypeStep (ec, false);
+                                       }
+
+                                       fne.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
                                }
 
                                return fne;
                        }
 
-                       if (!HasTypeArguments && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3)
+                       if (!HasTypeArguments && Name == "dynamic" &&
+                               RootContext.Version > LanguageVersion.V_3 &&
+                               RootContext.MetadataCompatibilityVersion > MetadataVersion.v2) {
+
+                               if (!PredefinedAttributes.Get.Dynamic.IsDefined) {
+                                       ec.Compiler.Report.Error (1980, Location,
+                                               "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
+                                               PredefinedAttributes.Get.Dynamic.GetSignatureForError ());
+                               }
+
                                return new DynamicTypeExpr (loc);
+                       }
 
-                       if (silent || errors != Report.Errors)
+                       if (silent || errors != ec.Compiler.Report.Errors)
                                return null;
 
                        Error_TypeOrNamespaceNotFound (ec);
@@ -2565,7 +2645,7 @@ namespace Mono.CSharp {
                                if (ec.CurrentTypeDefinition != null) {
                                        MemberCore mc = ec.CurrentTypeDefinition.GetDefinition (Name);
                                        if (mc != null) {
-                                               Error_UnexpectedKind (mc, "type", GetMemberType (mc), loc);
+                                               Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
                                                return;
                                        }
                                }
@@ -2575,8 +2655,8 @@ namespace Mono.CSharp {
                                foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
                                        Type type = a.GetType (fullname);
                                        if (type != null) {
-                                               Report.SymbolRelatedToPreviousError (type);
-                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type));
+                                               ec.Compiler.Report.SymbolRelatedToPreviousError (type);
+                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
                                                return;
                                        }
                                }
@@ -2584,7 +2664,7 @@ namespace Mono.CSharp {
                                if (ec.CurrentTypeDefinition != null) {
                                        Type t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
                                        if (t != null) {
-                                               Namespace.Error_InvalidNumberOfTypeArguments (t, loc);
+                                               Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
                                                return;
                                        }
                                }
@@ -2593,12 +2673,12 @@ namespace Mono.CSharp {
                        if (targs != null) {
                                FullNamedExpression retval = ec.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
                                if (retval != null) {
-                                       Namespace.Error_TypeArgumentsCannotBeUsed (retval, loc);
+                                       retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
                                        return;
                                }
                        }
                                                
-                       NamespaceEntry.Error_NamespaceNotFound (loc, Name);
+                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
                }
 
                // TODO: I am still not convinced about this. If someone else will need it
@@ -2623,12 +2703,7 @@ namespace Mono.CSharp {
 
                Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
                {
-                       if (in_transit)
-                               return null;
-
-                       in_transit = true;
                        Expression e = DoSimpleNameResolve (ec, right_side, intermediate);
-                       in_transit = false;
 
                        if (e == null)
                                return null;
@@ -2667,23 +2742,37 @@ namespace Mono.CSharp {
                        if (current_block != null){
                                LocalInfo vi = current_block.GetLocalInfo (Name);
                                if (vi != null){
-                                       LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+                                       e = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+
                                        if (right_side != null) {
-                                               return var.ResolveLValue (ec, right_side);
+                                               e = e.ResolveLValue (ec, right_side);
                                        } else {
-                                               ResolveFlags rf = ResolveFlags.VariableOrValue;
-                                               if (intermediate)
-                                                       rf |= ResolveFlags.DisableFlowAnalysis;
-                                               return var.Resolve (ec, rf);
+                                               if (intermediate) {
+                                                       using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                                               e = e.Resolve (ec, ResolveFlags.VariableOrValue);
+                                                       }
+                                               } else {
+                                                       e = e.Resolve (ec, ResolveFlags.VariableOrValue);
+                                               }
                                        }
+
+                                       if (targs != null && e != null)
+                                               e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+
+                                       return e;
                                }
 
-                               Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
-                               if (expr != null) {
+                               e = current_block.Toplevel.GetParameterReference (Name, loc);
+                               if (e != null) {
                                        if (right_side != null)
-                                               return expr.ResolveLValue (ec, right_side);
+                                               e = e.ResolveLValue (ec, right_side);
+                                       else
+                                               e = e.Resolve (ec);
+
+                                       if (targs != null && e != null)
+                                               e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
 
-                                       return expr.Resolve (ec);
+                                       return e;
                                }
                        }
                        
@@ -2692,9 +2781,9 @@ namespace Mono.CSharp {
                        //
 
                        Type almost_matched_type = null;
-                       ArrayList almost_matched = null;
+                       IList<MemberInfo> almost_matched = null;
                        for (Type lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
-                               e = MemberLookup (ec.CurrentType, lookup_ds, Name, loc);
+                               e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, loc);
                                if (e != null) {
                                        PropertyExpr pe = e as PropertyExpr;
                                        if (pe != null) {
@@ -2718,14 +2807,14 @@ namespace Mono.CSharp {
 
                                if (almost_matched == null && almost_matched_members.Count > 0) {
                                        almost_matched_type = lookup_ds;
-                                       almost_matched = (ArrayList) almost_matched_members.Clone ();
+                                       almost_matched = new List<MemberInfo>(almost_matched_members);
                                }
                        }
 
                        if (e == null) {
                                if (almost_matched == null && almost_matched_members.Count > 0) {
                                        almost_matched_type = ec.CurrentType;
-                                       almost_matched = (ArrayList) almost_matched_members.Clone ();
+                                       almost_matched = new List<MemberInfo> (almost_matched_members);
                                }
                                e = ResolveAsTypeStep (ec, true);
                        }
@@ -2739,7 +2828,7 @@ namespace Mono.CSharp {
                                                if (li != null)
                                                        li.Used = true;
 
-                                               Error_VariableIsUsedBeforeItIsDeclared (Name);
+                                               Error_VariableIsUsedBeforeItIsDeclared (ec.Report, Name);
                                                return null;
                                        }
                                }
@@ -2747,7 +2836,7 @@ namespace Mono.CSharp {
                                if (RootContext.EvalMode){
                                        FieldInfo fi = Evaluator.LookupField (Name);
                                        if (fi != null)
-                                               return new FieldExpr (fi, loc).Resolve (ec);
+                                               return new FieldExpr (Import.CreateField (fi), loc).Resolve (ec);
                                }
 
                                if (almost_matched != null)
@@ -2756,7 +2845,7 @@ namespace Mono.CSharp {
                                        almost_matched_type = ec.CurrentType;
 
                                string type_name = ec.MemberContext.CurrentType == null ? null : ec.MemberContext.CurrentType.Name;
-                               return Error_MemberLookupFailed (ec.CurrentType, null, almost_matched_type, Name,
+                               return Error_MemberLookupFailed (ec, ec.CurrentType, null, almost_matched_type, Name,
                                        type_name, AllMemberTypes, AllBindingFlags);
                        }
 
@@ -2798,7 +2887,7 @@ namespace Mono.CSharp {
                                        if (!targs.Resolve (ec))
                                                return null;
 
-                                       me.SetTypeArguments (targs);
+                                       me.SetTypeArguments (ec, targs);
                                }
 
                                if (!me.IsStatic && (me.InstanceExpression != null && me.InstanceExpression != EmptyExpression.Null) &&
@@ -2806,14 +2895,14 @@ namespace Mono.CSharp {
                                    me.InstanceExpression.Type != me.DeclaringType &&
                                    !TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
                                    (!intermediate || !IdenticalNameAndTypeName (ec, e, loc))) {
-                                       Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
+                                       ec.Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
                                                TypeManager.CSharpName (me.DeclaringType), TypeManager.CSharpName (me.InstanceExpression.Type));
                                        return null;
                                }
 
                                return (right_side != null)
                                        ? me.DoResolveLValue (ec, right_side)
-                                       : me.DoResolve (ec);
+                                       : me.Resolve (ec);
                        }
 
                        return e;
@@ -2868,7 +2957,7 @@ namespace Mono.CSharp {
                        return t;
                }
 
-               override public Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return ResolveAsTypeTerminal (ec, false);
                }
@@ -2978,7 +3067,7 @@ namespace Mono.CSharp {
                        //
                        if (type == null) {
                                Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
-                               FullNamedExpression fne = ns.Lookup (name, loc);
+                               FullNamedExpression fne = ns.Lookup (ec.Compiler, name, loc);
                                if (fne != null)
                                        type = fne.Type;
                        }
@@ -3050,15 +3139,15 @@ namespace Mono.CSharp {
                /// </summary>
                public Expression InstanceExpression;
 
-               public static void error176 (Location loc, string name)
+               public static void error176 (ResolveContext ec, Location loc, string name)
                {
-                       Report.Error (176, loc, "Static member `{0}' cannot be accessed " +
+                       ec.Report.Error (176, loc, "Static member `{0}' cannot be accessed " +
                                      "with an instance reference, qualify it with a type name instead", name);
                }
 
-               public static void Error_BaseAccessInExpressionTree (Location loc)
+               public static void Error_BaseAccessInExpressionTree (ResolveContext ec, Location loc)
                {
-                       Report.Error (831, loc, "An expression tree may not contain a base access");
+                       ec.Report.Error (831, loc, "An expression tree may not contain a base access");
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -3086,7 +3175,7 @@ namespace Mono.CSharp {
                                // always do all necessary checks
                                ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (left.Type);
                                if (oa != null && !ec.IsObsolete) {
-                                       AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc);
+                                       AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc, ec.Report);
                                }
 
                                GenericTypeExpr ct = left as GenericTypeExpr;
@@ -3106,16 +3195,16 @@ namespace Mono.CSharp {
                                if (original != null && original.IdenticalNameAndTypeName (ec, left, loc))
                                        return this;
 
-                               return ResolveExtensionMemberAccess (left);
+                               return ResolveExtensionMemberAccess (ec, left);
                        }
 
                        InstanceExpression = left;
                        return this;
                }
 
-               protected virtual MemberExpr ResolveExtensionMemberAccess (Expression left)
+               protected virtual MemberExpr ResolveExtensionMemberAccess (ResolveContext ec, Expression left)
                {
-                       error176 (loc, GetSignatureForError ());
+                       error176 (ec, loc, GetSignatureForError ());
                        return this;
                }
 
@@ -3146,10 +3235,10 @@ namespace Mono.CSharp {
                                ec.ig.Emit (OpCodes.Dup);
                }
 
-               public virtual void SetTypeArguments (TypeArguments ta)
+               public virtual void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
                        // TODO: need to get correct member type
-                       Report.Error (307, loc, "The property `{0}' cannot be used with type arguments",
+                       ec.Report.Error (307, loc, "The property `{0}' cannot be used with type arguments",
                                GetSignatureForError ());
                }
        }
@@ -3163,7 +3252,7 @@ namespace Mono.CSharp {
                public Expression ExtensionExpression;
                Argument extension_argument;
 
-               public ExtensionMethodGroupExpr (ArrayList list, NamespaceEntry n, Type extensionType, Location l)
+               public ExtensionMethodGroupExpr (List<MethodSpec> list, NamespaceEntry n, Type extensionType, Location l)
                        : base (list, extensionType, l)
                {
                        this.namespace_entry = n;
@@ -3216,7 +3305,7 @@ namespace Mono.CSharp {
                                return base.OverloadResolve (ec, ref arguments, false, loc);
 
                        e.ExtensionExpression = ExtensionExpression;
-                       e.SetTypeArguments (type_arguments);                    
+                       e.SetTypeArguments (ec, type_arguments);                        
                        return e.ResolveOverloadExtensions (ec, ref arguments, e.namespace_entry, loc);
                }               
        }
@@ -3229,13 +3318,13 @@ namespace Mono.CSharp {
        {
                public interface IErrorHandler
                {
-                       bool AmbiguousCall (MethodBase ambiguous);
-                       bool NoExactMatch (ResolveContext ec, MethodBase method);
+                       bool AmbiguousCall (ResolveContext ec, MethodSpec ambiguous);
+                       bool NoExactMatch (ResolveContext ec, MethodSpec method);
                }
 
-               public IErrorHandler CustomErrorHandler;                
-               public MethodBase [] Methods;
-               MethodBase best_candidate;
+               public IErrorHandler CustomErrorHandler;
+               public MethodSpec [] Methods;
+               MethodSpec best_candidate;
                // TODO: make private
                public TypeArguments type_arguments;
                bool identical_type_name;
@@ -3243,31 +3332,31 @@ namespace Mono.CSharp {
                Type delegate_type;
                Type queried_type;
                
-               public MethodGroupExpr (MemberInfo [] mi, Type type, Location l)
+               public MethodGroupExpr (MethodSpec [] mi, Type type, Location l)
                        : this (type, l)
                {
-                       Methods = new MethodBase [mi.Length];
+                       Methods = new MethodSpec[mi.Length];
                        mi.CopyTo (Methods, 0);
                }
 
-               public MethodGroupExpr (MemberInfo[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
+               public MethodGroupExpr (MethodSpec[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
                        : this (mi, type, l)
                {
                        has_inaccessible_candidates_only = inacessibleCandidatesOnly;
                }
 
-               public MethodGroupExpr (ArrayList list, Type type, Location l)
+               public MethodGroupExpr (List<MethodSpec> list, Type type, Location l)
                        : this (type, l)
                {
                        try {
-                               Methods = (MethodBase[])list.ToArray (typeof (MethodBase));
+                               Methods = list.ToArray ();
                        } catch {
-                               foreach (MemberInfo m in list){
-                                       if (!(m is MethodBase)){
-                                               Console.WriteLine ("Name " + m.Name);
-                                               Console.WriteLine ("Found a: " + m.GetType ().FullName);
-                                       }
-                               }
+                               //foreach (MemberInfo m in list){
+                               //    if (!(m is MethodBase)){
+                               //        Console.WriteLine ("Name " + m.Name);
+                               //        Console.WriteLine ("Found a: " + m.GetType ().FullName);
+                               //    }
+                               //}
                                throw;
                        }
 
@@ -3288,6 +3377,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public MethodSpec BestCandidate {
+                       get {
+                               return best_candidate;
+                       }
+               }
+
                public Type DelegateType {
                        set {
                                delegate_type = value;
@@ -3303,9 +3398,9 @@ namespace Mono.CSharp {
                public override string GetSignatureForError ()
                {
                        if (best_candidate != null)
-                               return TypeManager.CSharpSignature (best_candidate);
+                               return TypeManager.CSharpSignature (best_candidate.MetaInfo);
                        
-                       return TypeManager.CSharpSignature (Methods [0]);
+                       return TypeManager.CSharpSignature (Methods [0].MetaInfo);
                }
 
                public override string Name {
@@ -3319,7 +3414,7 @@ namespace Mono.CSharp {
                                if (best_candidate != null)
                                        return !best_candidate.IsStatic;
 
-                               foreach (MethodBase mb in Methods)
+                               foreach (var mb in Methods)
                                        if (!mb.IsStatic)
                                                return true;
 
@@ -3332,22 +3427,17 @@ namespace Mono.CSharp {
                                if (best_candidate != null)
                                        return best_candidate.IsStatic;
 
-                               foreach (MethodBase mb in Methods)
+                               foreach (var mb in Methods)
                                        if (mb.IsStatic)
                                                return true;
 
                                return false;
                        }
                }
-               
-               public static explicit operator ConstructorInfo (MethodGroupExpr mg)
-               {
-                       return (ConstructorInfo)mg.best_candidate;
-               }
 
-               public static explicit operator MethodInfo (MethodGroupExpr mg)
+               public static explicit operator MethodSpec (MethodGroupExpr mg)
                {
-                       return (MethodInfo)mg.best_candidate;
+                       return mg.best_candidate;
                }
 
                //
@@ -3370,8 +3460,8 @@ namespace Mono.CSharp {
                                        q = TypeManager.GetTypeArguments (q) [0];
                                }
                                
-                               p = Delegate.GetInvokeMethod (null, p).ReturnType;
-                               q = Delegate.GetInvokeMethod (null, q).ReturnType;
+                               p = Delegate.GetInvokeMethod (ec.Compiler, null, p).ReturnType;
+                               q = Delegate.GetInvokeMethod (ec.Compiler, null, q).ReturnType;
                                if (p == TypeManager.void_type && q != TypeManager.void_type)
                                        return 2;
                                if (q == TypeManager.void_type && p != TypeManager.void_type)
@@ -3409,6 +3499,9 @@ namespace Mono.CSharp {
                                if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
                                        q == TypeManager.uint64_type)
                                        return 1;
+                       } else if (p == InternalType.Dynamic) {
+                               if (q == TypeManager.object_type)
+                                       return 2;
                        }
 
                        if (q == TypeManager.int32_type) {
@@ -3425,6 +3518,9 @@ namespace Mono.CSharp {
                                if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
                                        p == TypeManager.uint64_type)
                                        return 2;
+                       } else if (q == InternalType.Dynamic) {
+                               if (p == TypeManager.object_type)
+                                       return 1;
                        }
 
                        // TODO: this is expensive
@@ -3453,11 +3549,11 @@ namespace Mono.CSharp {
                ///     true  if candidate is better than the current best match
                /// </remarks>
                static bool BetterFunction (ResolveContext ec, Arguments args, int argument_count,
-                       MethodBase candidate, bool candidate_params,
-                       MethodBase best, bool best_params)
+                       MethodSpec candidate, bool candidate_params,
+                       MethodSpec best, bool best_params)
                {
-                       AParametersCollection candidate_pd = TypeManager.GetParameterData (candidate);
-                       AParametersCollection best_pd = TypeManager.GetParameterData (best);
+                       AParametersCollection candidate_pd = candidate.Parameters;
+                       AParametersCollection best_pd = best.Parameters;
                
                        bool better_at_least_one = false;
                        bool same = true;
@@ -3483,8 +3579,8 @@ namespace Mono.CSharp {
                                        bt = TypeManager.GetElementType (bt);
                                        --b_idx;
                                }
-
-                               if (ct.Equals (bt))
+                               
+                               if (TypeManager.IsEqual (ct, bt))
                                        continue;
 
                                same = false;
@@ -3519,10 +3615,10 @@ namespace Mono.CSharp {
                        //
                        // The two methods have equal parameter types.  Now apply tie-breaking rules
                        //
-                       if (TypeManager.IsGenericMethod (best)) {
-                               if (!TypeManager.IsGenericMethod (candidate))
+                       if (best.IsGenericMethod) {
+                               if (!candidate.IsGenericMethod)
                                        return true;
-                       } else if (TypeManager.IsGenericMethod (candidate)) {
+                       } else if (candidate.IsGenericMethod) {
                                return false;
                        }
 
@@ -3580,10 +3676,10 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               protected override MemberExpr ResolveExtensionMemberAccess (Expression left)
+               protected override MemberExpr ResolveExtensionMemberAccess (ResolveContext ec, Expression left)
                {
                        if (!IsStatic)
-                               return base.ResolveExtensionMemberAccess (left);
+                               return base.ResolveExtensionMemberAccess (ec, left);
 
                        //
                        // When left side is an expression and at least one candidate method is 
@@ -3606,22 +3702,24 @@ namespace Mono.CSharp {
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        if (best_candidate == null) {
-                               Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
+                               ec.Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
                                return null;
                        }
 
-                       IMethodData md = TypeManager.GetMethod (best_candidate);
+                       IMethodData md = TypeManager.GetMethod (best_candidate.MetaInfo);
                        if (md != null && md.IsExcluded ())
-                               Report.Error (765, loc,
+                               ec.Report.Error (765, loc,
                                        "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
                        
                        return new TypeOfMethod (best_candidate, loc);
                }
                
-               override public Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
+                       this.eclass = ExprClass.MethodGroup;
+
                        if (InstanceExpression != null) {
-                               InstanceExpression = InstanceExpression.DoResolve (ec);
+                               InstanceExpression = InstanceExpression.Resolve (ec);
                                if (InstanceExpression == null)
                                        return null;
                        }
@@ -3629,15 +3727,16 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public void ReportUsageError ()
+               public void ReportUsageError (ResolveContext ec)
                {
-                       Report.Error (654, loc, "Method `" + DeclaringType + "." +
+                       ec.Report.Error (654, loc, "Method `" + DeclaringType + "." +
                                      Name + "()' is referenced without parentheses");
                }
 
                override public void Emit (EmitContext ec)
                {
-                       ReportUsageError ();
+                       throw new NotSupportedException ();
+                       // ReportUsageError ();
                }
                
                public void EmitCall (EmitContext ec, Arguments arguments)
@@ -3645,42 +3744,42 @@ namespace Mono.CSharp {
                        Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);                   
                }
 
-               void Error_AmbiguousCall (MethodBase ambiguous)
+               void Error_AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
                {
-                       if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ambiguous))
+                       if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
                                return;
 
-                       Report.SymbolRelatedToPreviousError (best_candidate);
-                       Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
-                               TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate));
+                       ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                       ec.Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
+                               TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate.MetaInfo));
                }
 
-               protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodBase method,
+               protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodSpec method,
                                                                                                        Argument a, AParametersCollection expected_par, Type paramType)
                {
                        ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
 
                        if (a is CollectionElementInitializer.ElementInitializerArgument) {
-                               Report.SymbolRelatedToPreviousError (method);
+                               ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
                                if ((expected_par.FixedParameters [idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
-                                       Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
+                                       ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
                                                TypeManager.CSharpSignature (method));
                                        return;
                                }
-                               Report.Error (1950, loc, "The best overloaded collection initalizer method `{0}' has some invalid arguments",
+                               ec.Report.Error (1950, loc, "The best overloaded collection initalizer method `{0}' has some invalid arguments",
                                          TypeManager.CSharpSignature (method));
                        } else if (TypeManager.IsDelegateType (method.DeclaringType)) {
-                               Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
+                               ec.Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
                                        TypeManager.CSharpName (method.DeclaringType));
                        } else {
-                               Report.SymbolRelatedToPreviousError (method);
+                               ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
                                if (emg != null) {
-                                       Report.Error (1928, loc,
+                                       ec.Report.Error (1928, loc,
                                                "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
                                                emg.ExtensionExpression.GetSignatureForError (),
                                                emg.Name, TypeManager.CSharpSignature (method));
                                } else {
-                                       Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
+                                       ec.Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
                                                TypeManager.CSharpSignature (method));
                                }
                        }
@@ -3691,26 +3790,26 @@ namespace Mono.CSharp {
                        if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^
                                (a.Modifier & (Parameter.Modifier.REF | Parameter.Modifier.OUT))) != 0) {
                                if ((mod & Parameter.Modifier.ISBYREF) == 0)
-                                       Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
+                                       ec.Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (a.Modifier));
                                else
-                                       Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
+                                       ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (mod));
                        } else {
                                string p1 = a.GetSignatureForError ();
                                string p2 = TypeManager.CSharpName (paramType);
 
                                if (p1 == p2) {
-                                       Report.ExtraInformation (loc, "(equally named types possibly from different assemblies in previous ");
-                                       Report.SymbolRelatedToPreviousError (a.Expr.Type);
-                                       Report.SymbolRelatedToPreviousError (paramType);
+                                       ec.Report.ExtraInformation (loc, "(equally named types possibly from different assemblies in previous ");
+                                       ec.Report.SymbolRelatedToPreviousError (a.Expr.Type);
+                                       ec.Report.SymbolRelatedToPreviousError (paramType);
                                }
 
                                if (idx == 0 && emg != null) {
-                                       Report.Error (1929, loc,
+                                       ec.Report.Error (1929, loc,
                                                "Extension method instance type `{0}' cannot be converted to `{1}'", p1, p2);
                                } else {
-                                       Report.Error (1503, loc,
+                                       ec.Report.Error (1503, loc,
                                                "Argument `#{0}' cannot convert `{1}' expression to type `{2}'", index, p1, p2);
                                }
                        }
@@ -3718,17 +3817,17 @@ namespace Mono.CSharp {
 
                public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
                {
-                       Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
+                       ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
                                Name, TypeManager.CSharpName (target));
                }
 
-               void Error_ArgumentCountWrong (int arg_count)
+               void Error_ArgumentCountWrong (ResolveContext ec, int arg_count)
                {
-                       Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
+                       ec.Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
                                      Name, arg_count.ToString ());
                }
                
-               protected virtual int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
+               protected virtual int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
                {
                        return parameters.Count;
                }               
@@ -3747,11 +3846,11 @@ namespace Mono.CSharp {
                /// 0 = the best, int.MaxValue = the worst
                ///
                public int IsApplicable (ResolveContext ec,
-                                               ref Arguments arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
+                                               ref Arguments arguments, int arg_count, ref MethodSpec method, ref bool params_expanded_form)
                {
-                       MethodBase candidate = method;
+                       var candidate = method;
 
-                       AParametersCollection pd = TypeManager.GetParameterData (candidate);
+                       AParametersCollection pd = candidate.Parameters;
                        int param_count = GetApplicableParametersCount (candidate, pd);
                        int optional_count = 0;
 
@@ -3763,7 +3862,7 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               int args_gap = Math.Abs (arg_count - param_count);
+                               int args_gap = System.Math.Abs (arg_count - param_count);
                                if (optional_count != 0) {
                                        if (args_gap > optional_count)
                                                return int.MaxValue - 10000 + args_gap - optional_count;
@@ -3773,6 +3872,8 @@ namespace Mono.CSharp {
                                                optional_count--;
                                                if (arg_count < param_count)
                                                        param_count--;
+                                       } else if (arg_count > param_count) {
+                                               return int.MaxValue - 10000 + args_gap;
                                        }
                                } else if (arg_count != param_count) {
                                        if (!pd.HasParams)
@@ -3814,7 +3915,7 @@ namespace Mono.CSharp {
                                                        if (na == null)
                                                                break;
 
-                                                       int index = pd.GetParameterIndexByName (na.Name.Value);
+                                                       int index = pd.GetParameterIndexByName (na.Name);
 
                                                        // Named parameter not found or already reordered
                                                        if (index <= i)
@@ -3844,36 +3945,33 @@ namespace Mono.CSharp {
                                arg_count = arguments.Count;
                        }
 
-#if GMCS_SOURCE
                        //
                        // 1. Handle generic method using type arguments when specified or type inference
                        //
-                       if (TypeManager.IsGenericMethod (candidate)) {
+                       if (candidate.IsGenericMethod) {
                                if (type_arguments != null) {
                                        Type [] g_args = candidate.GetGenericArguments ();
                                        if (g_args.Length != type_arguments.Count)
-                                               return int.MaxValue - 20000 + Math.Abs (type_arguments.Count - g_args.Length);
+                                               return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args.Length);
 
-                                       // TODO: Don't create new method, create Parameters only
-                                       method = ((MethodInfo) candidate).MakeGenericMethod (type_arguments.Arguments);
+                                       method = candidate.Inflate (type_arguments.Arguments);
                                        candidate = method;
-                                       pd = TypeManager.GetParameterData (candidate);
+                                       pd = candidate.Parameters;
                                } else {
                                        int score = TypeManager.InferTypeArguments (ec, arguments, ref candidate);
                                        if (score != 0)
                                                return score - 20000;
 
-                                       if (TypeManager.IsGenericMethodDefinition (candidate))
+                                       if (TypeManager.IsGenericMethodDefinition (candidate.MetaInfo))
                                                throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
-                                                       TypeManager.CSharpSignature (candidate));
+                                                       TypeManager.CSharpSignature (candidate.MetaInfo));
 
-                                       pd = TypeManager.GetParameterData (candidate);
+                                       pd = candidate.Parameters;
                                }
                        } else {
                                if (type_arguments != null)
                                        return int.MaxValue - 15000;
                        }
-#endif
 
                        //
                        // 2. Each argument has to be implicitly convertible to method parameter
@@ -3940,11 +4038,19 @@ namespace Mono.CSharp {
                                if (TypeManager.HasElementType (a_type))
                                        a_type = TypeManager.GetElementType (a_type);
 
-                               if (a_type != parameter)
+                               if (a_type != parameter) {
+                                       if (TypeManager.IsDynamicType (a_type))
+                                               return 0;
+
                                        return 2;
+                               }
                        } else {
-                               if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+                               if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
+                                       if (TypeManager.IsDynamicType (argument.Type))
+                                               return 0;
+
                                        return 2;
+                               }
                        }
 
                        if (arg_mod != param_mod)
@@ -3988,10 +4094,10 @@ namespace Mono.CSharp {
 
                        if (mg2 == null)
                                return mg1;
-                       
-                       ArrayList all = new ArrayList (mg1.Methods);
-                       foreach (MethodBase m in mg2.Methods){
-                               if (!TypeManager.ArrayContainsMethod (mg1.Methods, m, false))
+
+                       var all = new List<MethodSpec> (mg1.Methods);
+                       foreach (var m in mg2.Methods){
+                               if (!TypeManager.ArrayContainsMethod (mg1.Methods.Select (l => l.MetaInfo).ToArray (), m.MetaInfo, false))
                                        all.Add (m);
                        }
 
@@ -4045,13 +4151,11 @@ namespace Mono.CSharp {
                {
                        base.MutateHoistedGenericType (storey);
 
-                       MethodInfo mi = best_candidate as MethodInfo;
-                       if (mi != null) {
-                               best_candidate = storey.MutateGenericMethod (mi);
-                               return;
+                       if (best_candidate.IsConstructor) {
+                               storey.MutateConstructor (best_candidate);
+                       } else {
+                               storey.MutateGenericMethod (best_candidate);                            
                        }
-
-                       best_candidate = storey.MutateConstructor ((ConstructorInfo) this);
                }
 
                /// <summary>
@@ -4075,8 +4179,8 @@ namespace Mono.CSharp {
                {
                        bool method_params = false;
                        Type applicable_type = null;
-                       ArrayList candidates = new ArrayList (2);
-                       ArrayList candidate_overrides = null;
+                       var candidates = new List<MethodSpec> (2);
+                       List<MethodSpec> candidate_overrides = null;
 
                        //
                        // Used to keep a map between the candidate
@@ -4085,15 +4189,15 @@ namespace Mono.CSharp {
                        //
                        // false is normal form, true is expanded form
                        //
-                       Hashtable candidate_to_form = null;
-                       Hashtable candidates_expanded = null;
+                       Dictionary<MethodSpec, MethodSpec> candidate_to_form = null;
+                       Dictionary<MethodSpec, Arguments> candidates_expanded = null;
                        Arguments candidate_args = Arguments;
 
                        int arg_count = Arguments != null ? Arguments.Count : 0;
 
                        if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
                                if (!may_fail)
-                                       Report.Error (1533, loc, "Invoke cannot be called directly on a delegate");
+                                       ec.Report.Error (1533, loc, "Invoke cannot be called directly on a delegate");
                                return null;
                        }
 
@@ -4111,16 +4215,20 @@ namespace Mono.CSharp {
                                // with non-C# libraries which change the visibility of overrides (#75636)
                                //
                                int j = 0;
+                               MethodBase mb = null;
                                for (int i = 0; i < Methods.Length; ++i) {
-                                       MethodBase m = Methods [i];
+                                       var m = Methods [i];
+                                       mb = m.MetaInfo;
                                        if (TypeManager.IsOverride (m)) {
                                                if (candidate_overrides == null)
-                                                       candidate_overrides = new ArrayList ();
+                                                       candidate_overrides = new List<MethodSpec> ();
                                                candidate_overrides.Add (m);
-                                               m = TypeManager.TryGetBaseDefinition (m);
+                                               mb = TypeManager.TryGetBaseDefinition (mb);
+                                               if (mb != null && Array.Exists (Methods, l => l.MetaInfo == mb))
+                                                       continue;
                                        }
-                                       if (m != null)
-                                               Methods [j++] = m;
+                                       if (mb != null)
+                                               Methods [j++] = Import.CreateMethod (mb);
                                }
                                nmethods = j;
                        }
@@ -4128,8 +4236,8 @@ namespace Mono.CSharp {
                        //
                        // Enable message recording, it's used mainly by lambda expressions
                        //
-                       Report.IMessageRecorder msg_recorder = new Report.MessageRecorder ();
-                       Report.IMessageRecorder prev_recorder = Report.SetMessageRecorder (msg_recorder);
+                       SessionReportPrinter msg_recorder = new SessionReportPrinter ();
+                       ReportPrinter prev_recorder = ec.Report.SetPrinter (msg_recorder);
 
                        //
                        // First we construct the set of applicable methods
@@ -4159,14 +4267,14 @@ namespace Mono.CSharp {
                                
                                if (params_expanded_form) {
                                        if (candidate_to_form == null)
-                                               candidate_to_form = new PtrHashtable ();
-                                       MethodBase candidate = Methods [i];
+                                               candidate_to_form = new Dictionary<MethodSpec, MethodSpec> (4, ReferenceEquality<MethodSpec>.Default);
+                                       var candidate = Methods [i];
                                        candidate_to_form [candidate] = candidate;
                                }
                                
                                if (candidate_args != Arguments) {
                                        if (candidates_expanded == null)
-                                               candidates_expanded = new Hashtable (2);
+                                               candidates_expanded = new Dictionary<MethodSpec, Arguments> (4, ReferenceEquality<MethodSpec>.Default);
 
                                        candidates_expanded.Add (Methods [i], candidate_args);
                                        candidate_args = Arguments;
@@ -4190,10 +4298,10 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       Report.SetMessageRecorder (prev_recorder);
+                       ec.Report.SetPrinter (prev_recorder);
                        if (msg_recorder != null && !msg_recorder.IsEmpty) {
                                if (!may_fail)
-                                       msg_recorder.PrintMessages ();
+                                       msg_recorder.Merge (prev_recorder);
 
                                return null;
                        }
@@ -4209,7 +4317,7 @@ namespace Mono.CSharp {
                                        ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, Name, loc);
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = InstanceExpression;
-                                               ex_method_lookup.SetTypeArguments (type_arguments);
+                                               ex_method_lookup.SetTypeArguments (ec, type_arguments);
                                                return ex_method_lookup.OverloadResolve (ec, ref Arguments, may_fail, loc);
                                        }
                                }
@@ -4225,72 +4333,30 @@ namespace Mono.CSharp {
                                        if (CustomErrorHandler != null && !has_inaccessible_candidates_only && CustomErrorHandler.NoExactMatch (ec, best_candidate))
                                                return null;
 
-                                       AParametersCollection pd = TypeManager.GetParameterData (best_candidate);
-                                       bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
-                                       if (arg_count == pd.Count || pd.HasParams) {
-                                               if (TypeManager.IsGenericMethodDefinition (best_candidate)) {
-                                                       if (type_arguments == null) {
-                                                               Report.Error (411, loc,
-                                                                       "The type arguments for method `{0}' cannot be inferred from " +
-                                                                       "the usage. Try specifying the type arguments explicitly",
-                                                                       TypeManager.CSharpSignature (best_candidate));
-                                                               return null;
-                                                       }
-
-                                                       Type[] g_args = TypeManager.GetGenericArguments (best_candidate);
-                                                       if (type_arguments.Count != g_args.Length) {
-                                                               Report.SymbolRelatedToPreviousError (best_candidate);
-                                                               Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
-                                                                       TypeManager.CSharpSignature (best_candidate),
-                                                                       g_args.Length.ToString ());
-                                                               return null;
-                                                       }
-                                               } else {
-                                                       if (type_arguments != null && !TypeManager.IsGenericMethod (best_candidate)) {
-                                                               Namespace.Error_TypeArgumentsCannotBeUsed (best_candidate, loc);
-                                                               return null;
-                                                       }
-                                               }
-
-                                               if (has_inaccessible_candidates_only) {
-                                                       if (InstanceExpression != null && type != ec.CurrentType && TypeManager.IsNestedFamilyAccessible (ec.CurrentType, best_candidate.DeclaringType)) {
-                                                               // Although a derived class can access protected members of
-                                                               // its base class it cannot do so through an instance of the
-                                                               // base class (CS1540).  If the qualifier_type is a base of the
-                                                               // ec.CurrentType and the lookup succeeds with the latter one,
-                                                               // then we are in this situation.
-                                                               Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.CurrentType);
-                                                       } else {
-                                                               Report.SymbolRelatedToPreviousError (best_candidate);
-                                                               ErrorIsInaccesible (loc, GetSignatureForError ());
-                                                       }
-                                               }
-
-                                               if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
-                                                       return null;
-
-                                               if (has_inaccessible_candidates_only)
-                                                       return null;
-
-                                               throw new InternalErrorException ("VerifyArgumentsCompat didn't find any problem with rejected candidate " + best_candidate);
-                                       }
+                                       if (NoExactMatch (ec, ref Arguments, candidate_to_form))
+                                               return null;
                                }
 
                                //
                                // We failed to find any method with correct argument count
                                //
                                if (Name == ConstructorInfo.ConstructorName) {
-                                       Report.SymbolRelatedToPreviousError (queried_type);
-                                       Report.Error (1729, loc,
+                                       ec.Report.SymbolRelatedToPreviousError (queried_type);
+                                       ec.Report.Error (1729, loc,
                                                "The type `{0}' does not contain a constructor that takes `{1}' arguments",
                                                TypeManager.CSharpName (queried_type), arg_count);
                                } else {
-                                       Error_ArgumentCountWrong (arg_count);
+                                       Error_ArgumentCountWrong (ec, arg_count);
                                }
                                 
                                return null;
                        }
 
+                       if (arg_count != 0 && Arguments.HasDynamic) {
+                               best_candidate = null;
+                               return this;
+                       }
+
                        if (!is_sorted) {
                                //
                                // At this point, applicable_type is _one_ of the most derived types
@@ -4313,7 +4379,7 @@ namespace Mono.CSharp {
                                        int j = finalized; // where to put the next finalized candidate
                                        int k = finalized; // where to put the next undiscarded candidate
                                        for (int i = finalized; i < candidate_top; ++i) {
-                                               MethodBase candidate = (MethodBase) candidates [i];
+                                               var candidate = candidates [i];
                                                Type decl_type = candidate.DeclaringType;
 
                                                if (decl_type == applicable_type) {
@@ -4346,25 +4412,25 @@ namespace Mono.CSharp {
                        // Now we actually find the best method
                        //
 
-                       best_candidate = (MethodBase) candidates [0];
-                       method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+                       best_candidate = candidates [0];
+                       method_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
 
                        //
                        // TODO: Broken inverse order of candidates logic does not work with optional
                        // parameters used for method overrides and I am not going to fix it for SRE
                        //
-                       if (candidates_expanded != null && candidates_expanded.Contains (best_candidate)) {
-                               candidate_args = (Arguments) candidates_expanded [best_candidate];
+                       if (candidates_expanded != null && candidates_expanded.ContainsKey (best_candidate)) {
+                               candidate_args = candidates_expanded [best_candidate];
                                arg_count = candidate_args.Count;
                        }
 
                        for (int ix = 1; ix < candidate_top; ix++) {
-                               MethodBase candidate = (MethodBase) candidates [ix];
+                               var candidate = candidates [ix];
 
-                               if (candidate == best_candidate)
+                               if (candidate.MetaInfo == best_candidate.MetaInfo)
                                        continue;
 
-                               bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+                               bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (candidate);
 
                                if (BetterFunction (ec, candidate_args, arg_count, 
                                        candidate, cand_params,
@@ -4377,26 +4443,26 @@ namespace Mono.CSharp {
                        // Now check that there are no ambiguities i.e the selected method
                        // should be better than all the others
                        //
-                       MethodBase ambiguous = null;
+                       MethodSpec ambiguous = null;
                        for (int ix = 1; ix < candidate_top; ix++) {
-                               MethodBase candidate = (MethodBase) candidates [ix];
+                               var candidate = candidates [ix];
 
-                               if (candidate == best_candidate)
+                               if (candidate.MetaInfo == best_candidate.MetaInfo)
                                        continue;
 
-                               bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+                               bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (candidate);
                                if (!BetterFunction (ec, candidate_args, arg_count,
                                        best_candidate, method_params,
                                        candidate, cand_params)) 
                                {
                                        if (!may_fail)
-                                               Report.SymbolRelatedToPreviousError (candidate);
+                                               ec.Report.SymbolRelatedToPreviousError (candidate.MetaInfo);
                                        ambiguous = candidate;
                                }
                        }
 
                        if (ambiguous != null) {
-                               Error_AmbiguousCall (ambiguous);
+                               Error_AmbiguousCall (ec, ambiguous);
                                return this;
                        }
 
@@ -4411,31 +4477,29 @@ namespace Mono.CSharp {
                                if (candidate_overrides != null) {
                                        Type[] gen_args = null;
                                        bool gen_override = false;
-                                       if (TypeManager.IsGenericMethod (best_candidate))
-                                               gen_args = TypeManager.GetGenericArguments (best_candidate);
+                                       if (best_candidate.IsGenericMethod)
+                                               gen_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
 
-                                       foreach (MethodBase candidate in candidate_overrides) {
-                                               if (TypeManager.IsGenericMethod (candidate)) {
+                                       foreach (var candidate in candidate_overrides) {
+                                               if (candidate.IsGenericMethod) {
                                                        if (gen_args == null)
                                                                continue;
 
-                                                       if (gen_args.Length != TypeManager.GetGenericArguments (candidate).Length)
+                                                       if (gen_args.Length != TypeManager.GetGenericArguments (candidate.MetaInfo).Length)
                                                                continue;
                                                } else {
                                                        if (gen_args != null)
                                                                continue;
                                                }
                                                
-                                               if (IsOverride (candidate, best_candidate)) {
+                                               if (IsOverride (candidate.MetaInfo, best_candidate.MetaInfo)) {
                                                        gen_override = true;
                                                        best_candidate = candidate;
                                                }
                                        }
 
                                        if (gen_override && gen_args != null) {
-#if GMCS_SOURCE
-                                               best_candidate = ((MethodInfo) best_candidate).MakeGenericMethod (gen_args);
-#endif                                         
+                                               best_candidate = best_candidate.Inflate (gen_args);
                                        }
                                }
                        }
@@ -4455,7 +4519,7 @@ namespace Mono.CSharp {
 
                        MethodBase the_method = TypeManager.DropGenericMethodArguments (best_candidate);
                        if (TypeManager.IsGenericMethodDefinition (the_method) &&
-                           !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate, loc))
+                           !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate.MetaInfo, loc))
                                return null;
 
                        //
@@ -4463,36 +4527,91 @@ namespace Mono.CSharp {
                        //
                        ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (the_method);
                        if (oa != null && !ec.IsObsolete)
-                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
 
                        IMethodData data = TypeManager.GetMethod (the_method);
                        if (data != null)
-                               data.SetMemberIsUsed ();
+                               data.SetIsUsed ();
 
                        Arguments = candidate_args;
                        return this;
                }
+
+               bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, IDictionary<MethodSpec, MethodSpec> candidate_to_form)
+               {
+                       AParametersCollection pd = best_candidate.Parameters;
+                       int arg_count = Arguments == null ? 0 : Arguments.Count;
+
+                       if (arg_count == pd.Count || pd.HasParams) {
+                               if (TypeManager.IsGenericMethodDefinition (best_candidate.MetaInfo)) {
+                                       if (type_arguments == null) {
+                                               ec.Report.Error (411, loc,
+                                                       "The type arguments for method `{0}' cannot be inferred from " +
+                                                       "the usage. Try specifying the type arguments explicitly",
+                                                       TypeManager.CSharpSignature (best_candidate.MetaInfo));
+                                               return true;
+                                       }
+
+                                       Type[] g_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
+                                       if (type_arguments.Count != g_args.Length) {
+                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                                               ec.Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
+                                                       TypeManager.CSharpSignature (best_candidate.MetaInfo),
+                                                       g_args.Length.ToString ());
+                                               return true;
+                                       }
+                               } else {
+                                       if (type_arguments != null && !best_candidate.IsGenericMethod) {
+                                               Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+                                               return true;
+                                       }
+                               }
+
+                               if (has_inaccessible_candidates_only) {
+                                       if (InstanceExpression != null && type != ec.CurrentType && TypeManager.IsNestedFamilyAccessible (ec.CurrentType, best_candidate.DeclaringType)) {
+                                               // Although a derived class can access protected members of
+                                               // its base class it cannot do so through an instance of the
+                                               // base class (CS1540).  If the qualifier_type is a base of the
+                                               // ec.CurrentType and the lookup succeeds with the latter one,
+                                               // then we are in this situation.
+                                               Error_CannotAccessProtected (ec, loc, best_candidate.MetaInfo, queried_type, ec.CurrentType);
+                                       } else {
+                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                                               ErrorIsInaccesible (loc, GetSignatureForError (), ec.Report);
+                                       }
+                               }
+
+                               bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
+                               if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, false, loc))
+                                       return true;
+
+                               if (has_inaccessible_candidates_only)
+                                       return true;
+                       }
+
+                       return false;
+               }
                
-               public override void SetTypeArguments (TypeArguments ta)
+               public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
                        type_arguments = ta;
                }
 
                public bool VerifyArgumentsCompat (ResolveContext ec, ref Arguments arguments,
-                                                         int arg_count, MethodBase method,
+                                                         int arg_count, MethodSpec method,
                                                          bool chose_params_expanded,
                                                          bool may_fail, Location loc)
                {
-                       AParametersCollection pd = TypeManager.GetParameterData (method);
+                       AParametersCollection pd = method.Parameters;
                        int param_count = GetApplicableParametersCount (method, pd);
 
-                       int errors = Report.Errors;
+                       int errors = ec.Report.Errors;
                        Parameter.Modifier p_mod = 0;
                        Type pt = null;
                        int a_idx = 0, a_pos = 0;
                        Argument a = null;
-                       ArrayList params_initializers = null;
-                       bool has_unsafe_arg = false;
+                       ArrayInitializer params_initializers = null;
+                       bool has_unsafe_arg = method.ReturnType.IsPointer;
 
                        for (; a_idx < arg_count; a_idx++, ++a_pos) {
                                a = arguments [a_idx];
@@ -4503,7 +4622,7 @@ namespace Mono.CSharp {
 
                                        if (p_mod == Parameter.Modifier.PARAMS) {
                                                if (chose_params_expanded) {
-                                                       params_initializers = new ArrayList (arg_count - a_idx);
+                                                       params_initializers = new ArrayInitializer (arg_count - a_idx, a.Expr.Location);
                                                        pt = TypeManager.GetElementType (pt);
                                                }
                                        }
@@ -4523,32 +4642,35 @@ namespace Mono.CSharp {
                                } else {
                                        NamedArgument na = a as NamedArgument;
                                        if (na != null) {
-                                               int name_index = pd.GetParameterIndexByName (na.Name.Value);
+                                               int name_index = pd.GetParameterIndexByName (na.Name);
                                                if (name_index < 0 || name_index >= param_count) {
                                                        if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType)) {
-                                                               Report.SymbolRelatedToPreviousError (DeclaringType);
-                                                               Report.Error (1746, na.Name.Location,
+                                                               ec.Report.SymbolRelatedToPreviousError (DeclaringType);
+                                                               ec.Report.Error (1746, na.Location,
                                                                        "The delegate `{0}' does not contain a parameter named `{1}'",
-                                                                       TypeManager.CSharpName (DeclaringType), na.Name.Value);
+                                                                       TypeManager.CSharpName (DeclaringType), na.Name);
                                                        } else {
-                                                               Report.SymbolRelatedToPreviousError (best_candidate);
-                                                               Report.Error (1739, na.Name.Location,
+                                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                                                               ec.Report.Error (1739, na.Location,
                                                                        "The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
-                                                                       TypeManager.CSharpSignature (method), na.Name.Value);
+                                                                       TypeManager.CSharpSignature (method.MetaInfo), na.Name);
                                                        }
                                                } else if (arguments[name_index] != a) {
                                                        if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
-                                                               Report.SymbolRelatedToPreviousError (DeclaringType);
+                                                               ec.Report.SymbolRelatedToPreviousError (DeclaringType);
                                                        else
-                                                               Report.SymbolRelatedToPreviousError (best_candidate);
+                                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
 
-                                                       Report.Error (1744, na.Name.Location,
+                                                       ec.Report.Error (1744, na.Location,
                                                                "Named argument `{0}' cannot be used for a parameter which has positional argument specified",
-                                                               na.Name.Value);
+                                                               na.Name);
                                                }
                                        }
                                }
 
+                               if (TypeManager.IsDynamicType (a.Expr.Type))
+                                       continue;
+
                                if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
                                        break;
 
@@ -4573,7 +4695,7 @@ namespace Mono.CSharp {
                        }
 
                        if (a_idx != arg_count) {
-                               if (!may_fail && Report.Errors == errors) {
+                               if (!may_fail && ec.Report.Errors == errors) {
                                        if (CustomErrorHandler != null)
                                                CustomErrorHandler.NoExactMatch (ec, best_candidate);
                                        else
@@ -4592,7 +4714,7 @@ namespace Mono.CSharp {
                                pt = pd.Types [param_count - 1];
                                pt = TypeManager.GetElementType (pt);
                                has_unsafe_arg |= pt.IsPointer;
-                               params_initializers = new ArrayList (0);
+                               params_initializers = new ArrayInitializer (0, loc);
                        }
 
                        //
@@ -4600,20 +4722,19 @@ namespace Mono.CSharp {
                        //
                        if (params_initializers != null) {
                                arguments.Add (new Argument (
-                                                      new ArrayCreation (new TypeExpression (pt, loc), "[]",
-                                                                         params_initializers, loc).Resolve (ec)));
+                                       new ArrayCreation (new TypeExpression (pt, loc), "[]", params_initializers, loc).Resolve (ec)));
                                arg_count++;
                        }
 
                        if (arg_count < param_count) {
                                if (!may_fail)
-                                       Error_ArgumentCountWrong (arg_count);
+                                       Error_ArgumentCountWrong (ec, arg_count);
                                return false;
                        }
 
                        if (has_unsafe_arg && !ec.IsUnsafe) {
                                if (!may_fail)
-                                       UnsafeError (loc);
+                                       UnsafeError (ec, loc);
                                return false;
                        }
 
@@ -4623,9 +4744,9 @@ namespace Mono.CSharp {
 
        public class ConstantExpr : MemberExpr
        {
-               FieldInfo constant;
+               ConstSpec constant;
 
-               public ConstantExpr (FieldInfo constant, Location loc)
+               public ConstantExpr (ConstSpec constant, Location loc)
                {
                        this.constant = constant;
                        this.loc = loc;
@@ -4640,47 +4761,33 @@ namespace Mono.CSharp {
                }
 
                public override bool IsStatic {
-                       get { return constant.IsStatic; }
+                       get { return true; }
                }
 
                public override Type DeclaringType {
                        get { return constant.DeclaringType; }
                }
 
-               public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc, SimpleName original)
-               {
-                       constant = TypeManager.GetGenericFieldDefinition (constant);
-
-                       IConstant ic = TypeManager.GetConstant (constant);
-                       if (ic == null) {
-                               if (constant.IsLiteral) {
-                                       ic = new ExternalConstant (constant);
-                               } else {
-                                       ic = ExternalConstant.CreateDecimal (constant);
-                                       // HACK: decimal field was not resolved as constant
-                                       if (ic == null)
-                                               return new FieldExpr (constant, loc).ResolveMemberAccess (ec, left, loc, original);
-                               }
-                               TypeManager.RegisterConstant (constant, ic);
-                       }
-
-                       return base.ResolveMemberAccess (ec, left, loc, original);
-               }
-
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        throw new NotSupportedException ("ET");
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext rc)
                {
-                       IConstant ic = TypeManager.GetConstant (constant);
-                       if (ic.ResolveValue ()) {
-                               if (!ec.IsObsolete)
-                                       ic.CheckObsoleteness (loc);
+                       constant.MemberDefinition.SetIsUsed ();
+
+                       if (!rc.IsObsolete) {
+                               var oa = constant.GetObsoleteAttribute ();
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant.MetaInfo), loc, rc.Report);
                        }
 
-                       return ic.CreateConstantReference (loc);
+                       // Constants are resolved on-demand
+                       var c = constant.Value.Resolve (rc) as Constant;
+
+                       // Creates reference expression to the constant value
+                       return Constant.CreateConstant (rc, c.Type, c.GetValue (), loc);
                }
 
                public override void Emit (EmitContext ec)
@@ -4690,15 +4797,15 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (constant);
+                       return TypeManager.GetFullNameSignature (constant.MetaInfo);
                }
        }
 
        /// <summary>
        ///   Fully resolved expression that evaluates to a Field
        /// </summary>
-       public class FieldExpr : MemberExpr, IAssignMethod, IMemoryLocation, IVariableReference {
-               public FieldInfo FieldInfo;
+       public class FieldExpr : MemberExpr, IDynamicAssign, IMemoryLocation, IVariableReference {
+               protected FieldSpec spec;
                readonly Type constructed_generic_type;
                VariableInfo variable_info;
                
@@ -4709,15 +4816,22 @@ namespace Mono.CSharp {
                {
                        loc = l;
                }
+
+               public FieldExpr (FieldSpec spec, Location loc)
+               {
+                       this.spec = spec;
+                       this.loc = loc;
+
+                       type = TypeManager.TypeToCoreType (spec.FieldType);
+               }
                
-               public FieldExpr (FieldInfo fi, Location l)
+               public FieldExpr (FieldBase fi, Location l)
+                       : this (fi.Spec, l)
                {
-                       FieldInfo = fi;
-                       type = TypeManager.TypeToCoreType (fi.FieldType);
                        loc = l;
                }
 
-               public FieldExpr (FieldInfo fi, Type genericType, Location l)
+               public FieldExpr (Field fi, Type genericType, Location l)
                        : this (fi, l)
                {
                        if (TypeManager.IsGenericTypeDefinition (genericType))
@@ -4727,31 +4841,37 @@ namespace Mono.CSharp {
 
                public override string Name {
                        get {
-                               return FieldInfo.Name;
+                               return spec.Name;
                        }
                }
 
                public override bool IsInstance {
                        get {
-                               return !FieldInfo.IsStatic;
+                               return !spec.IsStatic;
                        }
                }
 
                public override bool IsStatic {
                        get {
-                               return FieldInfo.IsStatic;
+                               return spec.IsStatic;
+                       }
+               }
+
+               public FieldSpec Spec {
+                       get {
+                               return spec;
                        }
                }
 
                public override Type DeclaringType {
                        get {
-                               return FieldInfo.DeclaringType;
+                               return spec.MetaInfo.DeclaringType;
                        }
                }
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (FieldInfo);
+                       return TypeManager.GetFullNameSignature (spec.MetaInfo);
                }
 
                public VariableInfo VariableInfo {
@@ -4763,11 +4883,11 @@ namespace Mono.CSharp {
                public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
                                                                SimpleName original)
                {
-                       FieldInfo fi = TypeManager.GetGenericFieldDefinition (FieldInfo);
+                       FieldInfo fi = TypeManager.GetGenericFieldDefinition (spec.MetaInfo);
                        Type t = fi.FieldType;
 
                        if (t.IsPointer && !ec.IsUnsafe) {
-                               UnsafeError (loc);
+                               UnsafeError (ec, loc);
                        }
 
                        return base.ResolveMemberAccess (ec, left, loc, original);
@@ -4793,22 +4913,22 @@ namespace Mono.CSharp {
                                instance,
                                CreateTypeOfExpression ());
 
-                       return CreateExpressionFactoryCall ("Field", args);
+                       return CreateExpressionFactoryCall (ec, "Field", args);
                }
 
                public Expression CreateTypeOfExpression ()
                {
-                       return new TypeOfField (GetConstructedFieldInfo (), loc);
+                       return new TypeOfField (Import.CreateField (GetConstructedFieldInfo ()), loc);
                }
 
-               override public Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return DoResolve (ec, false, false);
                }
 
                Expression DoResolve (ResolveContext ec, bool lvalue_instance, bool out_access)
                {
-                       if (!FieldInfo.IsStatic){
+                       if (!IsStatic){
                                if (InstanceExpression == null){
                                        //
                                        // This can happen when referencing an instance field using
@@ -4831,10 +4951,11 @@ namespace Mono.CSharp {
                                                        InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
                                        }
                                } else {
-                                       ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
-
-                                       if (InstanceExpression != EmptyExpression.Null)
-                                               InstanceExpression = InstanceExpression.Resolve (ec, rf);
+                                       if (InstanceExpression != EmptyExpression.Null) {
+                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                                       InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
+                                               }
+                                       }
                                }
 
                                if (InstanceExpression == null)
@@ -4845,36 +4966,32 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       // TODO: the code above uses some non-standard multi-resolve rules
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-
                        if (!ec.IsObsolete) {
-                               FieldBase f = TypeManager.GetField (FieldInfo);
+                               FieldBase f = TypeManager.GetField (spec.MetaInfo);
                                if (f != null) {
                                        f.CheckObsoleteness (loc);
                                } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
                                        if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
+                                               AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec.MetaInfo), loc, ec.Report);
                                }
                        }
 
-                       IFixedBuffer fb = AttributeTester.GetFixedBuffer (FieldInfo);
+                       var fb = spec as FixedFieldSpec;
                        IVariableReference var = InstanceExpression as IVariableReference;
                        
                        if (fb != null) {
                                IFixedExpression fe = InstanceExpression as IFixedExpression;
                                if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
-                                       Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
+                                       ec.Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
                                }
 
                                if (InstanceExpression.eclass != ExprClass.Variable) {
-                                       Report.SymbolRelatedToPreviousError (FieldInfo);
-                                       Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
-                                               TypeManager.GetFullNameSignature (FieldInfo));
+                                       ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+                                       ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
+                                               TypeManager.GetFullNameSignature (spec.MetaInfo));
                                } else if (var != null && var.IsHoisted) {
-                                       AnonymousMethodExpression.Error_AddressOfCapturedVar (var, loc);
+                                       AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc);
                                }
                                
                                return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
@@ -4887,11 +5004,10 @@ namespace Mono.CSharp {
                                return this;
 
                        VariableInfo vi = var.VariableInfo;
-                       if (!vi.IsFieldAssigned (ec, FieldInfo.Name, loc))
+                       if (!vi.IsFieldAssigned (ec, Name, loc))
                                return null;
 
-                       variable_info = vi.GetSubStruct (FieldInfo.Name);
-                       eclass = ExprClass.Variable;
+                       variable_info = vi.GetSubStruct (Name);
                        return this;
                }
 
@@ -4918,16 +5034,16 @@ namespace Mono.CSharp {
                };
 
                // The return value is always null.  Returning a value simplifies calling code.
-               Expression Report_AssignToReadonly (Expression right_side)
+               Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side)
                {
                        int i = 0;
-                       if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess)
+                       if (right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess)
                                i += 1;
                        if (IsStatic)
                                i += 2;
                        if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
                                i += 4;
-                       Report.Error (codes [i], loc, msgs [i], GetSignatureForError ());
+                       ec.Report.Error (codes [i], loc, msgs [i], GetSignatureForError ());
 
                        return null;
                }
@@ -4936,52 +5052,52 @@ namespace Mono.CSharp {
                {
                        IVariableReference var = InstanceExpression as IVariableReference;
                        if (var != null && var.VariableInfo != null)
-                               var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
+                               var.VariableInfo.SetFieldAssigned (ec, Name);
 
-                       bool lvalue_instance = !FieldInfo.IsStatic && TypeManager.IsValueType (FieldInfo.DeclaringType);
-                       bool out_access = right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess;
+                       bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.MetaInfo.DeclaringType);
+                       bool out_access = right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess;
 
                        Expression e = DoResolve (ec, lvalue_instance, out_access);
 
                        if (e == null)
                                return null;
 
-                       FieldBase fb = TypeManager.GetField (FieldInfo);
+                       FieldBase fb = TypeManager.GetField (spec.MetaInfo);
                        if (fb != null) {
                                fb.SetAssigned ();
 
-                               if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess) &&
+                               if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) &&
                                        (fb.ModFlags & Modifiers.VOLATILE) != 0) {
-                                       Report.Warning (420, 1, loc,
+                                       ec.Report.Warning (420, 1, loc,
                                                "`{0}': A volatile field references will not be treated as volatile",
                                                fb.GetSignatureForError ());
                                }
                        }
 
-                       if (FieldInfo.IsInitOnly) {
+                       if (spec.IsReadOnly) {
                                // InitOnly fields can only be assigned in constructors or initializers
                                if (!ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.ConstructorScope))
-                                       return Report_AssignToReadonly (right_side);
+                                       return Report_AssignToReadonly (ec, right_side);
 
                                if (ec.HasSet (ResolveContext.Options.ConstructorScope)) {
                                        Type ctype = ec.CurrentType;
 
                                        // InitOnly fields cannot be assigned-to in a different constructor from their declaring type
-                                       if (!TypeManager.IsEqual (ctype, FieldInfo.DeclaringType))
-                                               return Report_AssignToReadonly (right_side);
+                                       if (!TypeManager.IsEqual (ctype, DeclaringType))
+                                               return Report_AssignToReadonly (ec, right_side);
                                        // static InitOnly fields cannot be assigned-to in an instance constructor
                                        if (IsStatic && !ec.IsStatic)
-                                               return Report_AssignToReadonly (right_side);
+                                               return Report_AssignToReadonly (ec, right_side);
                                        // instance constructors can't modify InitOnly fields of other instances of the same type
                                        if (!IsStatic && !(InstanceExpression is This))
-                                               return Report_AssignToReadonly (right_side);
+                                               return Report_AssignToReadonly (ec, right_side);
                                }
                        }
 
-                       if (right_side == EmptyExpression.OutAccess &&
+                       if (right_side == EmptyExpression.OutAccess.Instance &&
                            !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
-                               Report.SymbolRelatedToPreviousError (DeclaringType);
-                               Report.Warning (197, 1, loc,
+                               ec.Report.SymbolRelatedToPreviousError (DeclaringType);
+                               ec.Report.Warning (197, 1, loc,
                                                "Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class",
                                                GetSignatureForError ());
                        }
@@ -4998,15 +5114,15 @@ namespace Mono.CSharp {
                public override void CheckMarshalByRefAccess (ResolveContext ec)
                {
                        if (is_marshal_by_ref () && !(InstanceExpression is This)) {
-                               Report.SymbolRelatedToPreviousError (DeclaringType);
-                               Report.Warning (1690, 1, loc, "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
+                               ec.Report.SymbolRelatedToPreviousError (DeclaringType);
+                               ec.Report.Warning (1690, 1, loc, "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
                                                GetSignatureForError ());
                        }
                }
 
                public override int GetHashCode ()
                {
-                       return FieldInfo.GetHashCode ();
+                       return spec.GetHashCode ();
                }
                
                public bool IsFixed {
@@ -5036,7 +5152,7 @@ namespace Mono.CSharp {
                        if (fe == null)
                                return false;
 
-                       if (FieldInfo != fe.FieldInfo)
+                       if (spec.MetaInfo != fe.spec.MetaInfo)
                                return false;
 
                        if (InstanceExpression == null || fe.InstanceExpression == null)
@@ -5050,15 +5166,15 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        bool is_volatile = false;
 
-                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       var f = TypeManager.GetField (spec.MetaInfo);
                        if (f != null){
                                if ((f.ModFlags & Modifiers.VOLATILE) != 0)
                                        is_volatile = true;
 
-                               f.SetMemberIsUsed ();
+                               f.SetIsUsed ();
                        }
                        
-                       if (FieldInfo.IsStatic){
+                       if (IsStatic){
                                if (is_volatile)
                                        ig.Emit (OpCodes.Volatile);
 
@@ -5068,10 +5184,10 @@ namespace Mono.CSharp {
                                        EmitInstance (ec, false);
 
                                // Optimization for build-in types
-                               if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType)) {
+                               if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType) && TypeManager.IsEqual (InstanceExpression.Type, type)) {
                                        LoadFromPtr (ig, type);
                                } else {
-                                       IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
+                                       var ff = spec as FixedFieldSpec;
                                        if (ff != null) {
                                                ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
                                                ig.Emit (OpCodes.Ldflda, ff.Element);
@@ -5086,7 +5202,7 @@ namespace Mono.CSharp {
 
                        if (leave_copy) {
                                ec.ig.Emit (OpCodes.Dup);
-                               if (!FieldInfo.IsStatic) {
+                               if (!IsStatic) {
                                        temp = new LocalTemporary (this.Type);
                                        temp.Store (ec);
                                }
@@ -5095,8 +5211,8 @@ namespace Mono.CSharp {
 
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       FieldAttributes fa = FieldInfo.Attributes;
-                       bool is_static = (fa & FieldAttributes.Static) != 0;
+                       //FieldAttributes fa = FieldInfo.Attributes;
+                       //bool is_static = (fa & FieldAttributes.Static) != 0;
                        ILGenerator ig = ec.ig;
 
                        prepared = prepare_for_load;
@@ -5105,13 +5221,13 @@ namespace Mono.CSharp {
                        source.Emit (ec);
                        if (leave_copy) {
                                ec.ig.Emit (OpCodes.Dup);
-                               if (!FieldInfo.IsStatic) {
+                               if (!IsStatic) {
                                        temp = new LocalTemporary (this.Type);
                                        temp.Store (ec);
                                }
                        }
 
-                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       FieldBase f = TypeManager.GetField (spec.MetaInfo);
                        if (f != null){
                                if ((f.ModFlags & Modifiers.VOLATILE) != 0)
                                        ig.Emit (OpCodes.Volatile);
@@ -5119,7 +5235,7 @@ namespace Mono.CSharp {
                                f.SetAssigned ();
                        }
 
-                       if (is_static)
+                       if (IsStatic)
                                ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ());
                        else
                                ig.Emit (OpCodes.Stfld, GetConstructedFieldInfo ());
@@ -5138,16 +5254,16 @@ namespace Mono.CSharp {
 
                public override void EmitSideEffect (EmitContext ec)
                {
-                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       FieldBase f = TypeManager.GetField (spec.MetaInfo);
                        bool is_volatile = f != null && (f.ModFlags & Modifiers.VOLATILE) != 0;
 
                        if (is_volatile || is_marshal_by_ref ())
                                base.EmitSideEffect (ec);
                }
 
-               public override void Error_VariableIsUsedBeforeItIsDeclared (string name)
+               public override void Error_VariableIsUsedBeforeItIsDeclared (Report r, string name)
                {
-                       Report.Error (844, loc,
+                       r.Error (844, loc,
                                "A local variable `{0}' cannot be used before it is declared. Consider renaming the local variable when it hides the field `{1}'",
                                name, GetSignatureForError ());
                }
@@ -5156,12 +5272,12 @@ namespace Mono.CSharp {
                {
                        ILGenerator ig = ec.ig;
 
-                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       FieldBase f = TypeManager.GetField (spec.MetaInfo);
                        if (f != null){                         
                                if ((mode & AddressOp.Store) != 0)
                                        f.SetAssigned ();
                                if ((mode & AddressOp.Load) != 0)
-                                       f.SetMemberIsUsed ();
+                                       f.SetIsUsed ();
                        }
 
                        //
@@ -5169,10 +5285,10 @@ namespace Mono.CSharp {
                        // get the address of the copy.
                        //
                        bool need_copy;
-                       if (FieldInfo.IsInitOnly){
+                       if (spec.IsReadOnly){
                                need_copy = true;
                                if (ec.HasSet (EmitContext.Options.ConstructorScope)){
-                                       if (FieldInfo.IsStatic){
+                                       if (IsStatic){
                                                if (ec.IsStatic)
                                                        need_copy = false;
                                        } else
@@ -5191,7 +5307,7 @@ namespace Mono.CSharp {
                        }
 
 
-                       if (FieldInfo.IsStatic){
+                       if (IsStatic){
                                ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ());
                        } else {
                                if (!prepared)
@@ -5203,17 +5319,24 @@ namespace Mono.CSharp {
                FieldInfo GetConstructedFieldInfo ()
                {
                        if (constructed_generic_type == null)
-                               return FieldInfo;
-#if GMCS_SOURCE
-                       return TypeBuilder.GetField (constructed_generic_type, FieldInfo);
-#else
-                       throw new NotSupportedException ();
-#endif                 
+                               return spec.MetaInfo;
+
+                       return TypeBuilder.GetField (constructed_generic_type, spec.MetaInfo);
+               }
+
+               public SLE.Expression MakeAssignExpression (BuilderContext ctx)
+               {
+                       return MakeExpression (ctx);
+               }
+
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.MetaInfo);
                }
                
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       FieldInfo = storey.MutateField (FieldInfo);
+                       storey.MutateField (spec);
                        base.MutateHoistedGenericType (storey);
                }               
        }
@@ -5226,31 +5349,30 @@ namespace Mono.CSharp {
        ///   This is not an LValue because we need to re-write the expression, we
        ///   can not take data from the stack and store it.  
        /// </summary>
-       public class PropertyExpr : MemberExpr, IAssignMethod {
-               public readonly PropertyInfo PropertyInfo;
-               MethodInfo getter, setter;
+       public class PropertyExpr : MemberExpr, IDynamicAssign
+       {
+               PropertySpec spec;
+               MethodSpec getter, setter;
                bool is_static;
 
-               bool resolved;
+               TypeArguments targs;
                
                LocalTemporary temp;
                bool prepared;
 
-               public PropertyExpr (Type container_type, PropertyInfo pi, Location l)
+               public PropertyExpr (Type container_type, PropertySpec spec, Location l)
                {
-                       PropertyInfo = pi;
-                       eclass = ExprClass.PropertyAccess;
-                       is_static = false;
+                       this.spec = spec;
                        loc = l;
 
-                       type = TypeManager.TypeToCoreType (pi.PropertyType);
+                       type = TypeManager.TypeToCoreType (spec.PropertyType);
 
                        ResolveAccessors (container_type);
                }
 
                public override string Name {
                        get {
-                               return PropertyInfo.Name;
+                               return spec.Name;
                        }
                }
 
@@ -5272,11 +5394,11 @@ namespace Mono.CSharp {
                        if (IsSingleDimensionalArrayLength ()) {
                                args = new Arguments (1);
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
-                               return CreateExpressionFactoryCall ("ArrayLength", args);
+                               return CreateExpressionFactoryCall (ec, "ArrayLength", args);
                        }
 
                        if (is_base) {
-                               Error_BaseAccessInExpressionTree (loc);
+                               Error_BaseAccessInExpressionTree (ec, loc);
                                return null;
                        }
 
@@ -5286,7 +5408,7 @@ namespace Mono.CSharp {
                        else
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
                        args.Add (new Argument (new TypeOfMethod (getter, loc)));
-                       return CreateExpressionFactoryCall ("Property", args);
+                       return CreateExpressionFactoryCall (ec, "Property", args);
                }
 
                public Expression CreateSetterTypeOfExpression ()
@@ -5296,13 +5418,13 @@ namespace Mono.CSharp {
 
                public override Type DeclaringType {
                        get {
-                               return PropertyInfo.DeclaringType;
+                               return spec.DeclaringType;
                        }
                }
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (PropertyInfo);
+                       return TypeManager.GetFullNameSignature (spec.MetaInfo);
                }
 
                void FindAccessors (Type invocation_type)
@@ -5311,11 +5433,11 @@ namespace Mono.CSharp {
                                BindingFlags.Static | BindingFlags.Instance |
                                BindingFlags.DeclaredOnly;
 
-                       Type current = PropertyInfo.DeclaringType;
+                       Type current = spec.DeclaringType;
                        for (; current != null; current = current.BaseType) {
                                MemberInfo[] group = TypeManager.MemberLookup (
                                        invocation_type, invocation_type, current,
-                                       MemberTypes.Property, flags, PropertyInfo.Name, null);
+                                       MemberTypes.Property, flags, spec.Name, null);
 
                                if (group == null)
                                        continue;
@@ -5326,13 +5448,19 @@ namespace Mono.CSharp {
 
                                PropertyInfo pi = (PropertyInfo) group [0];
 
-                               if (getter == null)
-                                       getter = pi.GetGetMethod (true);
+                               if (getter == null) {
+                                       var m = pi.GetGetMethod (true);
+                                       if (m != null)
+                                               getter = Import.CreateMethod (m);
+                               }
 
-                               if (setter == null)
-                                       setter = pi.GetSetMethod (true);
+                               if (setter == null) {
+                                       var m = pi.GetSetMethod (true);
+                                       if (m != null)
+                                               setter = Import.CreateMethod (m);
+                               }
 
-                               MethodInfo accessor = getter != null ? getter : setter;
+                               var accessor = getter != null ? getter : setter;
 
                                if (!accessor.IsVirtual)
                                        return;
@@ -5352,7 +5480,7 @@ namespace Mono.CSharp {
                                MethodBase the_getter = TypeManager.DropGenericMethodArguments (getter);
                                IMethodData md = TypeManager.GetMethod (the_getter);
                                if (md != null)
-                                       md.SetMemberIsUsed ();
+                                       md.SetIsUsed ();
 
                                is_static = getter.IsStatic;
                        }
@@ -5361,12 +5489,22 @@ namespace Mono.CSharp {
                                MethodBase the_setter = TypeManager.DropGenericMethodArguments (setter);
                                IMethodData md = TypeManager.GetMethod (the_setter);
                                if (md != null)
-                                       md.SetMemberIsUsed ();
+                                       md.SetIsUsed ();
 
                                is_static = setter.IsStatic;
                        }
                }
 
+               public SLE.Expression MakeAssignExpression (BuilderContext ctx)
+               {
+                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.MetaInfo);
+               }
+
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.MetaInfo);
+               }
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        if (InstanceExpression != null)
@@ -5374,9 +5512,15 @@ namespace Mono.CSharp {
 
                        type = storey.MutateType (type);
                        if (getter != null)
-                               getter = storey.MutateGenericMethod (getter);
+                               storey.MutateGenericMethod (getter);
                        if (setter != null)
-                               setter = storey.MutateGenericMethod (setter);
+                               storey.MutateGenericMethod (setter);
+               }
+
+               public PropertyInfo PropertyInfo {
+                       get {
+                               return spec.MetaInfo;
+                       }
                }
 
                bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
@@ -5391,7 +5535,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       InstanceExpression = InstanceExpression.DoResolve (ec);
+                       InstanceExpression = InstanceExpression.Resolve (ec);
                        if (lvalue_instance && InstanceExpression != null)
                                InstanceExpression = InstanceExpression.ResolveLValue (ec, EmptyExpression.LValueMemberAccess);
 
@@ -5404,38 +5548,38 @@ namespace Mono.CSharp {
                            !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
                            !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
                            !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
-                               Report.SymbolRelatedToPreviousError (PropertyInfo);
-                               Error_CannotAccessProtected (loc, PropertyInfo, InstanceExpression.Type, ec.CurrentType);
+                               ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+                               Error_CannotAccessProtected (ec, loc, spec.MetaInfo, InstanceExpression.Type, ec.CurrentType);
                                return false;
                        }
 
                        return true;
                }
 
-               void Error_PropertyNotFound (MethodInfo mi, bool getter)
+               void Error_PropertyNotFound (ResolveContext ec, MethodSpec mi, bool getter)
                {
                        // TODO: correctly we should compare arguments but it will lead to bigger changes
-                       if (mi is MethodBuilder) {
-                               Error_TypeDoesNotContainDefinition (loc, PropertyInfo.DeclaringType, Name);
+                       if (mi.MetaInfo is MethodBuilder) {
+                               Error_TypeDoesNotContainDefinition (ec, loc, spec.DeclaringType, Name);
                                return;
                        }
                        
                        StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
                        sig.Append ('.');
-                       AParametersCollection iparams = TypeManager.GetParameterData (mi);
+                       AParametersCollection iparams = mi.Parameters;
                        sig.Append (getter ? "get_" : "set_");
                        sig.Append (Name);
                        sig.Append (iparams.GetSignatureForError ());
 
-                       Report.SymbolRelatedToPreviousError (mi);
-                       Report.Error (1546, loc, "Property `{0}' is not supported by the C# language. Try to call the accessor method `{1}' directly",
+                       ec.Report.SymbolRelatedToPreviousError (mi.MetaInfo);
+                       ec.Report.Error (1546, loc, "Property `{0}' is not supported by the C# language. Try to call the accessor method `{1}' directly",
                                Name, sig.ToString ());
                }
 
                public bool IsAccessibleFrom (Type invocation_type, bool lvalue)
                {
                        bool dummy;
-                       MethodInfo accessor = lvalue ? setter : getter;
+                       var accessor = lvalue ? setter : getter;
                        if (accessor == null && lvalue)
                                accessor = getter;
                        return accessor != null && IsAccessorAccessible (invocation_type, accessor, out dummy);
@@ -5451,51 +5595,30 @@ namespace Mono.CSharp {
                        return t_name_len > 2 && t_name [t_name_len - 2] == '[';
                }
 
-               override public Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (resolved)
-                               return this;
-
-                       if (getter != null){
-                               if (TypeManager.GetParameterData (getter).Count != 0){
-                                       Error_PropertyNotFound (getter, true);
-                                       return null;
-                               }
-                       }
+                       eclass = ExprClass.PropertyAccess;
 
-                       if (getter == null){
-                               //
-                               // The following condition happens if the PropertyExpr was
-                               // created, but is invalid (ie, the property is inaccessible),
-                               // and we did not want to embed the knowledge about this in
-                               // the caller routine.  This only avoids double error reporting.
-                               //
-                               if (setter == null)
-                                       return null;
+                       bool must_do_cs1540_check = false;
+                       ec.Report.DisableReporting ();
+                       bool res = ResolveGetter (ec, ref must_do_cs1540_check);
+                       ec.Report.EnableReporting ();
 
-                               if (InstanceExpression != EmptyExpression.Null) {
-                                       Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks the `get' accessor",
-                                               TypeManager.GetFullNameSignature (PropertyInfo));
-                                       return null;
+                       if (!res) {
+                               if (InstanceExpression != null) {
+                                       Type expr_type = InstanceExpression.Type;
+                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
+                                       if (ex_method_lookup != null) {
+                                               ex_method_lookup.ExtensionExpression = InstanceExpression;
+                                               ex_method_lookup.SetTypeArguments (ec, targs);
+                                               return ex_method_lookup.Resolve (ec);
+                                       }
                                }
-                       } 
 
-                       bool must_do_cs1540_check = false;
-                       if (getter != null &&
-                           !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
-                               PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter) as PropertyBase.PropertyMethod;
-                               if (pm != null && pm.HasCustomAccessModifier) {
-                                       Report.SymbolRelatedToPreviousError (pm);
-                                       Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
-                                               TypeManager.CSharpSignature (getter));
-                               }
-                               else {
-                                       Report.SymbolRelatedToPreviousError (getter);
-                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter));
-                               }
+                               ResolveGetter (ec, ref must_do_cs1540_check);
                                return null;
                        }
-                       
+
                        if (!InstanceResolve (ec, false, must_do_cs1540_check))
                                return null;
 
@@ -5503,38 +5626,37 @@ namespace Mono.CSharp {
                        // Only base will allow this invocation to happen.
                        //
                        if (IsBase && getter.IsAbstract) {
-                               Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
+                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
                        }
 
-                       if (PropertyInfo.PropertyType.IsPointer && !ec.IsUnsafe){
-                               UnsafeError (loc);
+                       if (spec.PropertyType.IsPointer && !ec.IsUnsafe){
+                               UnsafeError (ec, loc);
                        }
 
                        if (!ec.IsObsolete) {
-                               PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+                               PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
                                if (pb != null) {
                                        pb.CheckObsoleteness (loc);
                                } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
                                        if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
                                }
                        }
 
-                       resolved = true;
-
                        return this;
                }
 
                override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       if (right_side == EmptyExpression.OutAccess) {
-                               if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
-                                       Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
-                                           PropertyInfo.Name);
+                       eclass = ExprClass.PropertyAccess;
+
+                       if (right_side == EmptyExpression.OutAccess.Instance) {
+                               if (ec.CurrentBlock.Toplevel.GetParameterReference (spec.Name, loc) is MemberAccess) {
+                                       ec.Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
+                                           spec.Name);
                                } else {
-                                       Report.Error (206, loc, "A property or indexer `{0}' may not be passed as `ref' or `out' parameter",
-                                             GetSignatureForError ());
+                                       right_side.DoResolveLValue (ec, this);
                                }
                                return null;
                        }
@@ -5553,58 +5675,63 @@ namespace Mono.CSharp {
                                if (getter == null)
                                        return null;
 
-                               if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
-                                       Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
-                                               PropertyInfo.Name);
+                               if (ec.CurrentBlock.Toplevel.GetParameterReference (spec.Name, loc) is MemberAccess) {
+                                       ec.Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
+                                               spec.Name);
                                } else {
-                                       Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read only)",
+                                       ec.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read only)",
                                                GetSignatureForError ());
                                }
                                return null;
                        }
 
-                       if (TypeManager.GetParameterData (setter).Count != 1){
-                               Error_PropertyNotFound (setter, false);
+                       if (targs != null) {
+                               base.SetTypeArguments (ec, targs);
+                               return null;
+                       }
+
+                       if (setter.Parameters.Count != 1){
+                               Error_PropertyNotFound (ec, setter, false);
                                return null;
                        }
 
                        bool must_do_cs1540_check;
                        if (!IsAccessorAccessible (ec.CurrentType, setter, out must_do_cs1540_check)) {
-                               PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter) as PropertyBase.PropertyMethod;
+                               PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter.MetaInfo) as PropertyBase.PropertyMethod;
                                if (pm != null && pm.HasCustomAccessModifier) {
-                                       Report.SymbolRelatedToPreviousError (pm);
-                                       Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
+                                       ec.Report.SymbolRelatedToPreviousError (pm);
+                                       ec.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
                                                TypeManager.CSharpSignature (setter));
                                }
                                else {
-                                       Report.SymbolRelatedToPreviousError (setter);
-                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter));
+                                       ec.Report.SymbolRelatedToPreviousError (setter.MetaInfo);
+                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter), ec.Report);
                                }
                                return null;
                        }
                        
-                       if (!InstanceResolve (ec, TypeManager.IsStruct (PropertyInfo.DeclaringType), must_do_cs1540_check))
+                       if (!InstanceResolve (ec, TypeManager.IsStruct (spec.DeclaringType), must_do_cs1540_check))
                                return null;
                        
                        //
                        // Only base will allow this invocation to happen.
                        //
                        if (IsBase && setter.IsAbstract){
-                               Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
+                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
                        }
 
-                       if (PropertyInfo.PropertyType.IsPointer && !ec.IsUnsafe) {
-                               UnsafeError (loc);
+                       if (spec.PropertyType.IsPointer && !ec.IsUnsafe) {
+                               UnsafeError (ec, loc);
                        }
 
                        if (!ec.IsObsolete) {
-                               PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+                               PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
                                if (pb != null) {
                                        pb.CheckObsoleteness (loc);
                                } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
                                        if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
                                }
                        }
 
@@ -5675,63 +5802,102 @@ namespace Mono.CSharp {
                                temp.Release (ec);
                        }
                }
+
+               bool ResolveGetter (ResolveContext ec, ref bool must_do_cs1540_check)
+               {
+                       if (targs != null) {
+                               base.SetTypeArguments (ec, targs);
+                               return false;
+                       }
+
+                       if (getter != null) {
+                               if (!getter.Parameters.IsEmpty) {
+                                       Error_PropertyNotFound (ec, getter, true);
+                                       return false;
+                               }
+                       }
+
+                       if (getter == null) {
+                               //
+                               // The following condition happens if the PropertyExpr was
+                               // created, but is invalid (ie, the property is inaccessible),
+                               // and we did not want to embed the knowledge about this in
+                               // the caller routine.  This only avoids double error reporting.
+                               //
+                               if (setter == null)
+                                       return false;
+
+                               if (InstanceExpression != EmptyExpression.Null) {
+                                       ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks the `get' accessor",
+                                               TypeManager.GetFullNameSignature (spec.MetaInfo));
+                                       return false;
+                               }
+                       }
+
+                       if (getter != null &&
+                               !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
+                               PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter.MetaInfo) as PropertyBase.PropertyMethod;
+                               if (pm != null && pm.HasCustomAccessModifier) {
+                                       ec.Report.SymbolRelatedToPreviousError (pm);
+                                       ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
+                                               TypeManager.CSharpSignature (getter.MetaInfo));
+                               } else {
+                                       ec.Report.SymbolRelatedToPreviousError (getter.MetaInfo);
+                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter.MetaInfo), ec.Report);
+                               }
+
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
+               {
+                       targs = ta;
+               }
        }
 
        /// <summary>
        ///   Fully resolved expression that evaluates to an Event
        /// </summary>
-       public class EventExpr : MemberExpr {
-               public readonly EventInfo EventInfo;
-
-               bool is_static;
-               MethodInfo add_accessor, remove_accessor;
+       public class EventExpr : MemberExpr
+       {
+               readonly EventSpec spec;
 
-               public EventExpr (EventInfo ei, Location loc)
+               public EventExpr (EventSpec spec, Location loc)
                {
-                       EventInfo = ei;
+                       this.spec = spec;
                        this.loc = loc;
-                       eclass = ExprClass.EventAccess;
-
-                       add_accessor = TypeManager.GetAddMethod (ei);
-                       remove_accessor = TypeManager.GetRemoveMethod (ei);
-                       if (add_accessor.IsStatic || remove_accessor.IsStatic)
-                               is_static = true;
-
-                       if (EventInfo is MyEventBuilder){
-                               MyEventBuilder eb = (MyEventBuilder) EventInfo;
-                               type = eb.EventType;
-                               eb.SetUsed ();
-                       } else
-                               type = EventInfo.EventHandlerType;
                }
 
                public override string Name {
                        get {
-                               return EventInfo.Name;
+                               return spec.Name;
                        }
                }
 
                public override bool IsInstance {
                        get {
-                               return !is_static;
+                               return !spec.IsStatic;
                        }
                }
 
                public override bool IsStatic {
                        get {
-                               return is_static;
+                               return spec.IsStatic;
                        }
                }
 
                public override Type DeclaringType {
                        get {
-                               return EventInfo.DeclaringType;
+                               return spec.DeclaringType;
                        }
                }
                
-               public void Error_AssignmentEventOnly ()
+               public void Error_AssignmentEventOnly (ResolveContext ec)
                {
-                       Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
+                       ec.Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
                                GetSignatureForError ());
                }
 
@@ -5742,18 +5908,21 @@ namespace Mono.CSharp {
                        // If the event is local to this class, we transform ourselves into a FieldExpr
                        //
 
-                       if (EventInfo.DeclaringType == ec.CurrentType ||
-                           TypeManager.IsNestedChildOf(ec.CurrentType, EventInfo.DeclaringType)) {
-                               EventField mi = TypeManager.GetEventField (EventInfo);
+                       if (spec.DeclaringType == ec.CurrentType ||
+                           TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
+                                       
+                               // TODO: Breaks dynamic binder as currect context fields are imported and not compiled
+                               EventField mi = TypeManager.GetEventField (spec.MetaInfo).MemberDefinition as EventField;
 
-                               if (mi != null) {
+                               if (mi != null && mi.HasBackingField) {
+                                       mi.SetIsUsed ();
                                        if (!ec.IsObsolete)
                                                mi.CheckObsoleteness (loc);
 
                                        if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
-                                               Error_AssignmentEventOnly ();
+                                               Error_AssignmentEventOnly (ec);
                                        
-                                       FieldExpr ml = new FieldExpr (mi.BackingField.FieldBuilder, loc);
+                                       FieldExpr ml = new FieldExpr (mi.BackingField, loc);
 
                                        InstanceExpression = null;
                                
@@ -5762,14 +5931,14 @@ namespace Mono.CSharp {
                        }
 
                        if (left is This && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))                        
-                               Error_AssignmentEventOnly ();
+                               Error_AssignmentEventOnly (ec);
 
                        return base.ResolveMemberAccess (ec, left, loc, original);
                }
 
                bool InstanceResolve (ResolveContext ec, bool must_do_cs1540_check)
                {
-                       if (is_static) {
+                       if (IsStatic) {
                                InstanceExpression = null;
                                return true;
                        }
@@ -5779,12 +5948,12 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       InstanceExpression = InstanceExpression.DoResolve (ec);
+                       InstanceExpression = InstanceExpression.Resolve (ec);
                        if (InstanceExpression == null)
                                return false;
 
-                       if (IsBase && add_accessor.IsAbstract) {
-                               Error_CannotCallAbstractBase(TypeManager.CSharpSignature(add_accessor));
+                       if (IsBase && spec.IsAbstract) {
+                               Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec.MetaInfo));
                                return false;
                        }
 
@@ -5798,8 +5967,8 @@ namespace Mono.CSharp {
                            !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
                            !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
                            !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
-                               Report.SymbolRelatedToPreviousError (EventInfo);
-                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
+                               ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
                                return false;
                        }
 
@@ -5809,8 +5978,8 @@ namespace Mono.CSharp {
                public bool IsAccessibleFrom (Type invocation_type)
                {
                        bool dummy;
-                       return IsAccessorAccessible (invocation_type, add_accessor, out dummy) &&
-                               IsAccessorAccessible (invocation_type, remove_accessor, out dummy);
+                       return IsAccessorAccessible (invocation_type, spec.AccessorAdd, out dummy) &&
+                               IsAccessorAccessible (invocation_type, spec.AccessorRemove, out dummy);
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -5821,17 +5990,19 @@ namespace Mono.CSharp {
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
                        // contexts where an LValue is valid have already devolved to FieldExprs
-                       Error_CannotAssign ();
+                       Error_CannotAssign (ec);
                        return null;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
+                       eclass = ExprClass.EventAccess;
+
                        bool must_do_cs1540_check;
-                       if (!(IsAccessorAccessible (ec.CurrentType, add_accessor, out must_do_cs1540_check) &&
-                             IsAccessorAccessible (ec.CurrentType, remove_accessor, out must_do_cs1540_check))) {
-                               Report.SymbolRelatedToPreviousError (EventInfo);
-                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
+                       if (!(IsAccessorAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) &&
+                             IsAccessorAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) {
+                               ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
                                return null;
                        }
 
@@ -5839,46 +6010,47 @@ namespace Mono.CSharp {
                                return null;
 
                        if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
-                               Error_CannotAssign ();
+                               Error_CannotAssign (ec);
                                return null;
                        }
 
                        if (!ec.IsObsolete) {
-                               EventField ev = TypeManager.GetEventField (EventInfo);
-                               if (ev != null) {
-                                       ev.CheckObsoleteness (loc);
-                               } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (EventInfo);
-                                       if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
-                               }
+                               var oa = spec.GetObsoleteAttribute ();
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
                        }
+
+                       spec.MemberDefinition.SetIsUsed ();
+                       type = spec.EventType;
                        
                        return this;
                }               
 
                public override void Emit (EmitContext ec)
                {
-                       Error_CannotAssign ();
+                       throw new NotSupportedException ();
+                       //Error_CannotAssign ();
                }
 
-               public void Error_CannotAssign ()
+               public void Error_CannotAssign (ResolveContext ec)
                {
-                       Report.Error (70, loc,
+                       ec.Report.Error (70, loc,
                                "The event `{0}' can only appear on the left hand side of += or -= when used outside of the type `{1}'",
-                               GetSignatureForError (), TypeManager.CSharpName (EventInfo.DeclaringType));
+                               GetSignatureForError (), TypeManager.CSharpName (spec.DeclaringType));
                }
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpSignature (EventInfo);
+                       return TypeManager.CSharpSignature (spec.MetaInfo);
                }
 
                public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
                {
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (source));
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, is_add ? add_accessor : remove_accessor, args, loc);
+                       Invocation.EmitCall (ec, IsBase, InstanceExpression,
+                               is_add ? spec.AccessorAdd : spec.AccessorRemove,
+                               args, loc);
                }
        }
 
@@ -5890,7 +6062,6 @@ namespace Mono.CSharp {
                {
                        this.type = type;
                        this.loc = loc;
-                       eclass = ExprClass.Variable;
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -5898,10 +6069,9 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (li != null)
-                               return this;
+                       eclass = ExprClass.Variable;
 
                        TypeExpr te = new TypeExpression (type, loc);
                        li = ec.CurrentBlock.AddTemporaryVariable (te, loc);
@@ -5922,7 +6092,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       return DoResolve (ec);
+                       return Resolve (ec);
                }
                
                public override void Emit (EmitContext ec)
@@ -5937,7 +6107,7 @@ namespace Mono.CSharp {
 
                public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
                {
-                       return li.HoistedVariableReference;
+                       return li.HoistedVariant;
                }
 
                public override bool IsFixed {
@@ -5973,16 +6143,17 @@ namespace Mono.CSharp {
        class VarExpr : SimpleName
        {
                // Used for error reporting only
-               ArrayList initializer;
+               int initializers_count;
 
                public VarExpr (Location loc)
                        : base ("var", loc)
                {
+                       initializers_count = 1;
                }
 
-               public ArrayList VariableInitializer {
+               public int VariableInitializersCount {
                        set {
-                               this.initializer = value;
+                               this.initializers_count = value;
                        }
                }
 
@@ -5992,8 +6163,8 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("An implicitly typed local variable could not be redefined");
                        
                        type = right_side.Type;
-                       if (type == TypeManager.null_type || type == TypeManager.void_type || type == InternalType.AnonymousMethod) {
-                               Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'",
+                       if (type == TypeManager.null_type || type == TypeManager.void_type || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) {
+                               ec.Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'",
                                              right_side.GetSignatureForError ());
                                return false;
                        }
@@ -6007,7 +6178,7 @@ namespace Mono.CSharp {
                        if (RootContext.Version < LanguageVersion.V_3)
                                base.Error_TypeOrNamespaceNotFound (ec);
                        else
-                               Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
+                               ec.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
                }
 
                public override TypeExpr ResolveAsContextualType (IMemberContext rc, bool silent)
@@ -6017,21 +6188,20 @@ namespace Mono.CSharp {
                                return te;
 
                        if (RootContext.Version < LanguageVersion.V_3)
-                               Report.FeatureIsNotAvailable (loc, "implicitly typed local variable");
+                               rc.Compiler.Report.FeatureIsNotAvailable (loc, "implicitly typed local variable");
 
-                       if (initializer == null)
+                       if (initializers_count == 1)
                                return null;
 
-                       if (initializer.Count > 1) {
-                               Location loc_init = ((CSharpParser.VariableDeclaration) initializer[1]).Location;
-                               Report.Error (819, loc_init, "An implicitly typed local variable declaration cannot include multiple declarators");
-                               initializer = null;
+                       if (initializers_count > 1) {
+                               rc.Compiler.Report.Error (819, loc, "An implicitly typed local variable declaration cannot include multiple declarators");
+                               initializers_count = 1;
                                return null;
                        }
 
-                       Expression variable_initializer = ((CSharpParser.VariableDeclaration) initializer[0]).expression_or_array_initializer;
-                       if (variable_initializer == null) {
-                               Report.Error (818, loc, "An implicitly typed local variable declarator must include an initializer");
+                       if (initializers_count == 0) {
+                               initializers_count = 1;
+                               rc.Compiler.Report.Error (818, loc, "An implicitly typed local variable declarator must include an initializer");
                                return null;
                        }