[xbuild] Add new reserved properties $(MSBuildThisFile*).
[mono.git] / mcs / mcs / ecore.cs
index 00ae02eb128d277a888ac26744176e05b02626d1..e0edcc0a7843027da1619faca9481a42d1e648ae 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;
 
+#if STATIC
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
+#else
+using System.Reflection;
+using System.Reflection.Emit;
+#endif
+
 namespace Mono.CSharp {
 
        /// <remarks>
@@ -129,11 +134,6 @@ namespace Mono.CSharp {
                        get { return loc; }
                }
 
-               // Not nice but we have broken hierarchy.
-               public virtual void CheckMarshalByRefAccess (ResolveContext ec)
-               {
-               }
-
                public virtual string GetSignatureForError ()
                {
                        return type.GetDefinition ().GetSignatureForError ();
@@ -195,15 +195,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               //
-               // C# 3.0 introduced contextual keywords (var) which behaves like a type if type with
-               // same name exists or as a keyword when no type was found
-               // 
-               public virtual TypeExpr ResolveAsContextualType (IMemberContext rc, bool silent)
-               {
-                       return ResolveAsTypeTerminal (rc, silent);
-               }               
-               
                //
                // This is used to resolve the expression as a type, a null
                // value will be returned if the expression is not a type
@@ -211,7 +202,8 @@ namespace Mono.CSharp {
                //
                public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent)
                {
-                       int errors = ec.Compiler.Report.Errors;
+                       // FIXME: THIS IS TOO SLOW and it should not be needed either
+                       int errors = ec.Module.Compiler.Report.Errors;
 
                        FullNamedExpression fne = ResolveAsTypeStep (ec, silent);
 
@@ -220,18 +212,23 @@ namespace Mono.CSharp {
                                
                        TypeExpr te = fne as TypeExpr;                          
                        if (te == null) {
-                               if (!silent && errors == ec.Compiler.Report.Errors)
-                                       fne.Error_UnexpectedKind (ec.Compiler.Report, null, "type", loc);
+                               if (!silent && errors == ec.Module.Compiler.Report.Errors)
+                                       fne.Error_UnexpectedKind (ec.Module.Compiler.Report, null, "type", loc);
                                return null;
                        }
 
-                       if (!te.CheckAccessLevel (ec)) {
-                               ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
+                       if (!te.type.IsAccessible (ec.CurrentType)) {
+                               ec.Module.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
                                ErrorIsInaccesible (ec, te.Type.GetSignatureForError (), loc);
                        }
 
                        te.loc = loc;
 
+                       var dep = te.type.GetMissingDependencies ();
+                       if (dep != null) {
+                               ImportedTypeDefinition.Error_MissingDependency (ec, dep, loc);
+                       }
+
                        //
                        // Obsolete checks cannot be done when resolving base context as they
                        // require type dependecies to be set but we are just resolving them
@@ -239,7 +236,7 @@ namespace Mono.CSharp {
                        if (!silent && !(ec is TypeContainer.BaseContext)) {
                                ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete ();
                                if (obsolete_attr != null && !ec.IsObsolete) {
-                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Module.Compiler.Report);
                                }
                        }
 
@@ -248,7 +245,7 @@ namespace Mono.CSharp {
        
                public static void ErrorIsInaccesible (IMemberContext rc, string member, Location loc)
                {
-                       rc.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member);
+                       rc.Module.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member);
                }
 
                public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name)
@@ -289,28 +286,16 @@ namespace Mono.CSharp {
                        if (type == InternalType.AnonymousMethod)
                                return;
 
-/*
-                       if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
-                               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);
-                               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));
-                       } else if (Type.MetaInfo.FullName == target.MetaInfo.FullName) {
-                               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.MetaInfo.FullName, Type.Assembly.FullName, target.Assembly.FullName));
+                       string from_type = type.GetSignatureForError ();
+                       string to_type = target.GetSignatureForError ();
+                       if (from_type == to_type) {
+                               from_type = string.Format ("{0} [{1}]", from_type, type.MemberDefinition.DeclaringAssembly.FullName);
+                               to_type = string.Format ("{0} [{1}]", to_type, target.MemberDefinition.DeclaringAssembly.FullName);
                        }
-*/
+
                        if (expl) {
                                ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
-                                       TypeManager.CSharpName (type), TypeManager.CSharpName (target));
+                                       from_type, to_type);
                                return;
                        }
 
@@ -319,19 +304,13 @@ namespace Mono.CSharp {
                        ec.Report.EnableReporting ();
 
                        if (expl_exists) {
-                               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;
+                               ec.Report.Error (266, loc,
+                                       "Cannot implicitly convert type `{0}' to `{1}'. An explicit conversion exists (are you missing a cast?)",
+                                       from_type, to_type);
+                       } else {
+                               ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
+                                       from_type, to_type);
                        }
-
-                       ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
-                               type.GetSignatureForError (), target.GetSignatureForError ());
-               }
-
-               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);
                }
 
                public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity)
@@ -380,6 +359,11 @@ namespace Mono.CSharp {
                        ec.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
                }
 
+               protected void Error_VoidPointerOperation (ResolveContext rc)
+               {
+                       rc.Report.Error (242, loc, "The operation in question is undefined on void pointers");
+               }
+
                public ResolveFlags ExprClassToResolveFlags {
                        get {
                                switch (eclass) {
@@ -440,7 +424,7 @@ namespace Mono.CSharp {
                                        throw;
 
                                ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
-                               return EmptyExpression.Null;
+                               return EmptyExpression.Null;    // TODO: Add location
                        }
                }
 
@@ -497,7 +481,7 @@ namespace Mono.CSharp {
 
                public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
-                       rc.Compiler.Report.Error (182, loc,
+                       rc.Module.Compiler.Report.Error (182, loc,
                                "An attribute argument must be a constant expression, typeof expression or array creation expression");
                }
 
@@ -562,7 +546,7 @@ namespace Mono.CSharp {
 
                protected static MethodSpec ConstructorLookup (ResolveContext rc, TypeSpec type, ref Arguments args, Location loc)
                {
-                       var ctors = MemberCache.FindMembers (type, ConstructorInfo.ConstructorName, true);
+                       var ctors = MemberCache.FindMembers (type, Constructor.ConstructorName, true);
                        if (ctors == null) {
                                rc.Report.SymbolRelatedToPreviousError (type);
                                if (type.IsStruct) {
@@ -580,11 +564,20 @@ namespace Mono.CSharp {
                        return r.ResolveMember<MethodSpec> (rc, ref args);
                }
 
+               [Flags]
+               public enum MemberLookupRestrictions
+               {
+                       None = 0,
+                       InvocableOnly = 1,
+                       ExactArity = 1 << 2,
+                       ReadAccess = 1 << 3
+               }
+
                //
                // Lookup type `queried_type' for code in class `container_type' with a qualifier of
                // `qualifier_type' or null to lookup members in the current class.
                //
-               public static Expression MemberLookup (ResolveContext rc, TypeSpec currentType, TypeSpec queried_type, string name, int arity, bool invocableOnly, Location loc)
+               public static Expression MemberLookup (ResolveContext rc, TypeSpec currentType, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc)
                {
                        var members = MemberCache.FindMembers (queried_type, name, false);
                        if (members == null)
@@ -601,13 +594,32 @@ namespace Mono.CSharp {
                                        if ((member.Modifiers & Modifiers.OVERRIDE) != 0 && member.Kind != MemberKind.Event)
                                                continue;
 
-                                       if (arity > 0 && member.Arity != arity)
+                                       if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity)
                                                continue;
 
-                                       if (rc != null && !member.IsAccessible (currentType))
-                                               continue;
+                                       if (rc != null) {
+                                               if (!member.IsAccessible (currentType))
+                                                       continue;
+
+                                               //
+                                               // With runtime binder we can have a situation where queried type is inaccessible
+                                               // because it came via dynamic object, the check about inconsisted accessibility
+                                               // had no effect as the type was unknown during compilation
+                                               //
+                                               // class A {
+                                               //              private class N { }
+                                               //
+                                               //              public dynamic Foo ()
+                                               //              {
+                                               //                      return new N ();
+                                               //              }
+                                               //      }
+                                               //
+                                               if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (currentType))
+                                                       continue;
+                                       }
 
-                                       if (invocableOnly) {
+                                       if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
                                                if (member is MethodSpec)
                                                        return new MethodGroupExpr (members, queried_type, loc);
 
@@ -669,7 +681,7 @@ namespace Mono.CSharp {
                ///   Returns an expression that can be used to invoke operator false
                ///   on the expression if it exists.
                /// </summary>
-               static public Expression GetOperatorFalse (ResolveContext ec, Expression e, Location loc)
+               protected static Expression GetOperatorFalse (ResolveContext ec, Expression e, Location loc)
                {
                        return GetOperatorTrueOrFalse (ec, e, false, loc);
                }
@@ -684,7 +696,7 @@ namespace Mono.CSharp {
                        Arguments arguments = new Arguments (1);
                        arguments.Add (new Argument (e));
 
-                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.NoBaseMembers, loc);
+                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.BaseMembersIncluded | OverloadResolver.Restrictions.NoBaseMembers, loc);
                        var oper = res.ResolveOperator (ec, ref arguments);
 
                        if (oper == null)
@@ -924,16 +936,11 @@ namespace Mono.CSharp {
 
                protected static TypeExpr CreateExpressionTypeExpression (ResolveContext ec, Location loc)
                {
-                       TypeExpr texpr = TypeManager.expression_type_expr;
-                       if (texpr == null) {
-                               TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
-                               if (t == null)
-                                       return null;
-
-                               TypeManager.expression_type_expr = texpr = new TypeExpression (t, Location.Null);
-                       }
+                       var t = ec.Module.PredefinedTypes.Expression.Resolve (loc);
+                       if (t == null)
+                               return null;
 
-                       return texpr;
+                       return new TypeExpression (t, loc);
                }
 
                //
@@ -1040,9 +1047,13 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
+#if STATIC
+                       return base.MakeExpression (ctx);
+#else
                        return ctx.HasSet (BuilderContext.Options.CheckedScope) ?
                                SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type.GetMetaInfo ()) :
                                SLE.Expression.Convert (child.MakeExpression (ctx), type.GetMetaInfo ());
+#endif
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -1214,16 +1225,6 @@ namespace Mono.CSharp {
                        this.type = type;
                }
 
-               public override string AsString ()
-               {
-                       return child.AsString ();
-               }
-
-               public override object GetValue ()
-               {
-                       return child.GetValue ();
-               }
-
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (child.Type == target_type)
@@ -1289,6 +1290,16 @@ namespace Mono.CSharp {
                        child.EmitSideEffect (ec);
                }
 
+               public override object GetValue ()
+               {
+                       return child.GetValue ();
+               }
+
+               public override string GetValueAsLiteral ()
+               {
+                       return child.GetValueAsLiteral ();
+               }
+
                public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
                {
                        // FIXME: Do we need to check user conversions?
@@ -1354,31 +1365,23 @@ namespace Mono.CSharp {
                        return Child.GetValue ();
                }
 
+#if !STATIC
                public override object GetTypedValue ()
                {
-                       // FIXME: runtime is not ready to work with just emited enums
-                       if (!RootContext.StdLib) {
-                               return Child.GetValue ();
-                       }
-
-#if MS_COMPATIBLE
-                       // Small workaround for big problem
+                       //
+                       // The method can be used in dynamic context only (on closed types)
+                       //
                        // System.Enum.ToObject cannot be called on dynamic types
                        // EnumBuilder has to be used, but we cannot use EnumBuilder
                        // because it does not properly support generics
                        //
-                       // This works only sometimes
-                       //
-                       if (type.MemberDefinition is TypeContainer)
-                               return Child.GetValue ();
-#endif
-
                        return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ());
                }
-               
-               public override string AsString ()
+#endif
+
+               public override string GetValueAsLiteral ()
                {
-                       return Child.AsString ();
+                       return Child.GetValueAsLiteral ();
                }
 
                public EnumConstant Increment()
@@ -1448,6 +1451,12 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
+                       // Only boxing to object type is supported
+                       if (targetType != TypeManager.object_type) {
+                               base.EncodeAttributeValue (rc, enc, targetType);
+                               return;
+                       }
+
                        enc.Encode (child.Type);
                        child.EncodeAttributeValue (rc, enc, child.Type);
                }
@@ -1485,13 +1494,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
-               {
-                       if (right_side == EmptyExpression.LValueMemberAccess || right_side == EmptyExpression.LValueMemberOutAccess)
-                               ec.Report.Error (445, loc, "Cannot modify the result of an unboxing conversion");
-                       return base.DoResolveLValue (ec, right_side);
-               }
-
                public override void Emit (EmitContext ec)
                {
                        base.Emit (ec);
@@ -1722,7 +1724,8 @@ namespace Mono.CSharp {
                }
        }
        
-       public class OpcodeCast : TypeCast {
+       class OpcodeCast : TypeCast
+       {
                readonly OpCode op;
                
                public OpcodeCast (Expression child, TypeSpec return_type, OpCode op)
@@ -1750,6 +1753,27 @@ namespace Mono.CSharp {
                }
        }
 
+       //
+       // Opcode casts expression with 2 opcodes but only
+       // single expression tree node
+       //
+       class OpcodeCastDuplex : OpcodeCast
+       {
+               readonly OpCode second;
+
+               public OpcodeCastDuplex (Expression child, TypeSpec returnType, OpCode first, OpCode second)
+                       : base (child, returnType, first)
+               {
+                       this.second = second;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       base.Emit (ec);
+                       ec.Emit (second);
+               }
+       }
+
        /// <summary>
        ///   This kind of cast is used to encapsulate a child and cast it
        ///   to the class requested
@@ -1873,6 +1897,16 @@ namespace Mono.CSharp {
                        this.loc = orig_expr.Location;
                }
 
+               #region Properties
+
+               public Expression OriginalExpression {
+                       get {
+                               return orig_expr;
+                       }
+               }
+
+               #endregion
+
                //
                // Creates fully resolved expression switcher
                //
@@ -1889,15 +1923,23 @@ namespace Mono.CSharp {
                        return new ReducedExpressionStatement (s, orig);
                }
 
+               public static Expression Create (Expression expr, Expression original_expr)
+               {
+                       return Create (expr, original_expr, true);
+               }
+
                //
                // Creates unresolved reduce expression. The original expression has to be
-               // already resolved
+               // already resolved. Created expression is constant based based on `expr'
+               // value unless canBeConstant is used
                //
-               public static Expression Create (Expression expr, Expression original_expr)
+               public static Expression Create (Expression expr, Expression original_expr, bool canBeConstant)
                {
-                       Constant c = expr as Constant;
-                       if (c != null)
-                               return Create (c, original_expr);
+                       if (canBeConstant) {
+                               Constant c = expr as Constant;
+                               if (c != null)
+                                       return Create (c, original_expr);
+                       }
 
                        ExpressionStatement s = expr as ExpressionStatement;
                        if (s != null)
@@ -1940,7 +1982,7 @@ namespace Mono.CSharp {
        //
        public abstract class CompositeExpression : Expression
        {
-               Expression expr;
+               protected Expression expr;
 
                protected CompositeExpression (Expression expr)
                {
@@ -2111,7 +2153,7 @@ namespace Mono.CSharp {
                        return Name;
                }
 
-               public abstract Expression LookupNameExpression (ResolveContext rc, bool readMode, bool invocableOnly);
+               public abstract Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restriction);
        }
        
        /// <summary>
@@ -2146,7 +2188,7 @@ namespace Mono.CSharp {
                                if (ec.CurrentMemberDefinition != null) {
                                        MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
                                        if (mc != null) {
-                                               Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+                                               Error_UnexpectedKind (ec.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc);
                                                return;
                                        }
                                }
@@ -2177,7 +2219,7 @@ namespace Mono.CSharp {
 
                        FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
                        if (retval != null) {
-                               Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc, retval.Type, Arity);
+                               Error_TypeArgumentsCannotBeUsed (ec.Module.Compiler.Report, loc, retval.Type, Arity);
 /*
                                var te = retval as TypeExpr;
                                if (HasTypeArguments && te != null && !te.Type.IsGeneric)
@@ -2188,7 +2230,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
+                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Module.Compiler.Report);
                }
 
                protected override Expression DoResolve (ResolveContext ec)
@@ -2203,7 +2245,7 @@ namespace Mono.CSharp {
 
                public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
                {
-                       int errors = ec.Compiler.Report.Errors;
+                       int errors = ec.Module.Compiler.Report.Errors;
                        FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
 
                        if (fne != null) {
@@ -2223,11 +2265,11 @@ namespace Mono.CSharp {
                                        return fne;
                        }
 
-                       if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) {
-                               if (!PredefinedAttributes.Get.Dynamic.IsDefined) {
-                                       ec.Compiler.Report.Error (1980, Location,
+                       if (Arity == 0 && Name == "dynamic" && ec.Module.Compiler.Settings.Version > LanguageVersion.V_3) {
+                               if (!ec.Module.PredefinedAttributes.Dynamic.IsDefined) {
+                                       ec.Module.Compiler.Report.Error (1980, Location,
                                                "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
-                                               PredefinedAttributes.Get.Dynamic.GetSignatureForError ());
+                                               ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
                                }
 
                                return new DynamicTypeExpr (loc);
@@ -2236,57 +2278,45 @@ namespace Mono.CSharp {
                        if (fne != null)
                                return fne;
 
-                       if (silent || errors != ec.Compiler.Report.Errors)
+                       if (silent || errors != ec.Module.Compiler.Report.Errors)
                                return null;
 
                        Error_TypeOrNamespaceNotFound (ec);
                        return null;
                }
 
-               public override Expression LookupNameExpression (ResolveContext rc, bool readMode, bool invocableOnly)
+               public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        int lookup_arity = Arity;
                        bool errorMode = false;
                        Expression e;
                        Block current_block = rc.CurrentBlock;
+                       INamedBlockVariable variable = null;
+                       bool variable_found = false;
 
                        while (true) {
                                //
                                // Stage 1: binding to local variables or parameters
                                //
+                               // LAMESPEC: It should take invocableOnly into account but that would break csc compatibility
+                               //
                                if (current_block != null && lookup_arity == 0) {
-                                       LocalInfo vi = current_block.GetLocalInfo (Name);
-                                       if (vi != null) {
-                                               // TODO: pass vi in to speed things up
-                                               e = new LocalVariableReference (rc.CurrentBlock, Name, loc);
-                                       } else {
-                                               e = current_block.Toplevel.GetParameterReference (Name, loc);
-                                       }
-
-                                       if (e != null) {
-                                               if (Arity > 0)
-                                                       Error_TypeArgumentsCannotBeUsed (rc.Report, "variable", Name, loc);
-
-                                               return e;
-                                       }
-
-                                       if (!errorMode)
-                                               current_block.CheckInvariantMeaningInBlock (Name, this, loc);
+                                       if (current_block.ParametersBlock.TopBlock.GetLocalName (Name, current_block.Original, ref variable)) {
+                                               if (!variable.IsDeclared) {
+                                                       // We found local name in accessible block but it's not
+                                                       // initialized yet, maybe the user wanted to bind to something else
+                                                       errorMode = true;
+                                                       variable_found = true;
+                                               } else {
+                                                       e = variable.CreateReferenceExpression (rc, loc);
+                                                       if (e != null) {
+                                                               if (Arity > 0)
+                                                                       Error_TypeArgumentsCannotBeUsed (rc.Report, "variable", Name, loc);
 
-/*
-                                       //if (errorMode) {
-                                               IKnownVariable ikv = current_block.Explicit.GetKnownVariable (Name);
-                                               if (ikv != null) {
-                                                       LocalInfo li = ikv as LocalInfo;
-                                                       // Supress CS0219 warning
-                                                       if (li != null)
-                                                               li.Used = true;
-
-                                                       Error_VariableIsUsedBeforeItIsDeclared (rc.Report, Name);
-                                                       return null;
+                                                               return e;
+                                                       }
                                                }
-                                       //}
-*/ 
+                                       }
                                }
 
                                //
@@ -2295,18 +2325,41 @@ namespace Mono.CSharp {
                                TypeSpec member_type = rc.CurrentType;
                                TypeSpec current_type = member_type;
                                for (; member_type != null; member_type = member_type.DeclaringType) {
-                                       var me = MemberLookup (errorMode ? null : rc, current_type, member_type, Name, lookup_arity, invocableOnly, loc) as MemberExpr;
-                                       if (me == null)
+                                       e = MemberLookup (errorMode ? null : rc, current_type, member_type, Name, lookup_arity, restrictions, loc);
+                                       if (e == null)
+                                               continue;
+
+                                       var me = e as MemberExpr;
+                                       if (me == null) {
+                                               // The name matches a type, defer to ResolveAsTypeStep
+                                               if (e is TypeExpr)
+                                                       break;
+
                                                continue;
+                                       }
 
                                        if (errorMode) {
-                                               if (me is MethodGroupExpr) {
+                                               if (variable != null) {
+                                                       if (me is FieldExpr || me is ConstantExpr || me is EventExpr || me is PropertyExpr) {
+                                                               rc.Report.Error (844, loc,
+                                                                       "A local variable `{0}' cannot be used before it is declared. Consider renaming the local variable when it hides the member `{1}'",
+                                                                       Name, me.GetSignatureForError ());
+                                                       } else {
+                                                               break;
+                                                       }
+                                               } else if (me is MethodGroupExpr) {
                                                        // Leave it to overload resolution to report correct error
                                                } else {
                                                        // TODO: rc.Report.SymbolRelatedToPreviousError ()
                                                        ErrorIsInaccesible (rc, me.GetSignatureForError (), loc);
                                                }
                                        } else {
+                                               // LAMESPEC: again, ignores InvocableOnly
+                                               if (variable != null) {
+                                                       rc.Report.SymbolRelatedToPreviousError (variable.Location, Name);
+                                                       rc.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", Name);
+                                               }
+
                                                //
                                                // MemberLookup does not check accessors availability, this is actually needed for properties only
                                                //
@@ -2314,7 +2367,7 @@ namespace Mono.CSharp {
                                                if (pe != null) {
 
                                                        // Break as there is no other overload available anyway
-                                                       if (readMode) {
+                                                       if ((restrictions & MemberLookupRestrictions.ReadAccess) != 0) {
                                                                if (!pe.PropertyInfo.HasGet || !pe.PropertyInfo.Get.IsAccessible (current_type))
                                                                        break;
 
@@ -2343,40 +2396,57 @@ namespace Mono.CSharp {
                                //
                                // Stage 3: Lookup nested types, namespaces and type parameters in the context
                                //
-                               if (!invocableOnly) {
+                               if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
                                        e = ResolveAsTypeStep (rc, lookup_arity == 0 || !errorMode);
-                                       if (e != null)
+                                       if (e != null) {
+                                               if (variable != null) {
+                                                       rc.Report.SymbolRelatedToPreviousError (variable.Location, Name);
+                                                       rc.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", Name);
+                                               }
+
                                                return e;
+                                       }
                                }
 
                                if (errorMode) {
-                                       rc.Report.Error (103, loc, "The name `{0}' does not exist in the current context", Name);
+                                       if (variable_found) {
+                                               rc.Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", Name);
+                                       } else {
+                                               rc.Report.Error (103, loc, "The name `{0}' does not exist in the current context", Name);
+                                       }
+
                                        return null;
                                }
 
-                               if (RootContext.EvalMode) {
-                                       var fi = Evaluator.LookupField (Name);
+                               if (rc.Module.Evaluator != null) {
+                                       var fi = rc.Module.Evaluator.LookupField (Name);
                                        if (fi != null)
                                                return new FieldExpr (fi.Item1, loc);
                                }
 
                                lookup_arity = 0;
-                               invocableOnly = false;
+                               restrictions &= ~MemberLookupRestrictions.InvocableOnly;
                                errorMode = true;
                        }
                }
-
+               
                Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
                {
-                       Expression e = LookupNameExpression (ec, right_side == null, false);
+                       Expression e = LookupNameExpression (ec, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None);
 
                        if (e == null)
                                return null;
 
-                       if (right_side != null)
+                       if (right_side != null) {
+                               if (e is TypeExpr) {
+                                   e.Error_UnexpectedKind (ec, ResolveFlags.VariableOrValue, loc);
+                                   return null;
+                               }
+
                                e = e.ResolveLValue (ec, right_side);
-                       else
+                       } else {
                                e = e.Resolve (ec);
+                       }
 
                        //if (ec.CurrentBlock == null || ec.CurrentBlock.CheckInvariantMeaningInBlock (Name, e, Location))
                        return e;
@@ -2431,15 +2501,6 @@ namespace Mono.CSharp {
                        return ResolveAsTypeTerminal (ec, false);
                }
 
-               public virtual bool CheckAccessLevel (IMemberContext mc)
-               {
-                       DeclSpace c = mc.CurrentMemberDefinition as DeclSpace;
-                       if (c == null)
-                               c = mc.CurrentMemberDefinition.Parent;
-
-                       return c.CheckAccessLevel (Type);
-               }
-
                protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec);
 
                public override bool Equals (object obj)
@@ -2571,11 +2632,11 @@ namespace Mono.CSharp {
                                        // get/set member expressions second call would fail to proxy because left expression
                                        // would be of 'this' and not 'base'
                                        if (rc.CurrentType.IsStruct)
-                                               InstanceExpression = rc.GetThis (loc);
+                                               InstanceExpression = new This (loc).Resolve (rc);
                                }
 
                                if (targs != null)
-                                       method = method.MakeGenericMethod (targs);
+                                       method = method.MakeGenericMethod (rc, targs);
                        }
 
                        //
@@ -2633,6 +2694,11 @@ namespace Mono.CSharp {
                                UnsafeError (rc, loc);
                        }
 
+                       var dep = member.GetMissingDependencies ();
+                       if (dep != null) {
+                               ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
+                       }
+
                        if (!rc.IsObsolete) {
                                ObsoleteAttribute oa = member.GetAttributeObsolete ();
                                if (oa != null)
@@ -2671,15 +2737,20 @@ namespace Mono.CSharp {
                        return left;
                }
 
-               public bool ResolveInstanceExpression (ResolveContext rc)
+               public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
                {
                        if (IsStatic) {
                                if (InstanceExpression != null) {
                                        if (InstanceExpression is TypeExpr) {
-                                               ObsoleteAttribute oa = InstanceExpression.Type.GetAttributeObsolete ();
-                                               if (oa != null && !rc.IsObsolete) {
-                                                       AttributeTester.Report_ObsoleteMessage (oa, InstanceExpression.GetSignatureForError (), loc, rc.Report);
-                                               }
+                                               var t = InstanceExpression.Type;
+                                               do {
+                                                       ObsoleteAttribute oa = t.GetAttributeObsolete ();
+                                                       if (oa != null && !rc.IsObsolete) {
+                                                               AttributeTester.Report_ObsoleteMessage (oa, t.GetSignatureForError (), loc, rc.Report);
+                                                       }
+
+                                                       t = t.DeclaringType;
+                                               } while (t != null);
                                        } else {
                                                var runtime_expr = InstanceExpression as RuntimeValueExpression;
                                                if (runtime_expr == null || !runtime_expr.IsSuggestionOnly) {
@@ -2715,13 +2786,21 @@ namespace Mono.CSharp {
                                                DeclaringType.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
                                }
 
-                               InstanceExpression = rc.GetThis (loc);
+                               InstanceExpression = new This (loc);
+                               if (this is FieldExpr && rc.CurrentType.IsStruct) {
+                                       using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
+                                               InstanceExpression = InstanceExpression.Resolve (rc);
+                                       }
+                               } else {
+                                       InstanceExpression = InstanceExpression.Resolve (rc);
+                               }
+
                                return false;
                        }
 
                        var me = InstanceExpression as MemberExpr;
                        if (me != null) {
-                               me.ResolveInstanceExpression (rc);
+                               me.ResolveInstanceExpression (rc, rhs);
 
                                var fe = me as FieldExpr;
                                if (fe != null && fe.IsMarshalByRefAccess ()) {
@@ -2730,6 +2809,29 @@ namespace Mono.CSharp {
                                                "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
                                                me.GetSignatureForError ());
                                }
+
+                               return true;
+                       }
+
+                       //
+                       // Run member-access postponed check once we know that
+                       // the expression is not field expression which is the only
+                       // expression which can use uninitialized this
+                       //
+                       if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentType.IsStruct) {
+                               ((This)InstanceExpression).CheckStructThisDefiniteAssignment (rc);
+                       }
+
+                       //
+                       // Additional checks for l-value member access
+                       //
+                       if (rhs != null) {
+                               //
+                               // TODO: It should be recursive but that would break csc compatibility
+                               //
+                               if (InstanceExpression is UnboxCast) {
+                                       rc.Report.Error (445, InstanceExpression.Location, "Cannot modify the result of an unboxing conversion");
+                               }
                        }
 
                        return true;
@@ -2832,7 +2934,7 @@ namespace Mono.CSharp {
 
                        var me = ExtensionExpression as MemberExpr;
                        if (me != null)
-                               me.ResolveInstanceExpression (ec);
+                               me.ResolveInstanceExpression (ec, null);
 
                        InstanceExpression = null;
                        return this;
@@ -2882,6 +2984,7 @@ namespace Mono.CSharp {
        {
                protected IList<MemberSpec> Methods;
                MethodSpec best_candidate;
+               TypeSpec best_candidate_return;
                protected TypeArguments type_arguments;
 
                SimpleName simple_name;
@@ -2910,6 +3013,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public TypeSpec BestCandidateReturnType {
+                       get {
+                               return best_candidate_return;
+                       }
+               }
+
                protected override TypeSpec DeclaringType {
                        get {
                                return queried_type;
@@ -2955,7 +3064,8 @@ namespace Mono.CSharp {
                public static MethodGroupExpr CreatePredefined (MethodSpec best, TypeSpec queriedType, Location loc)
                {
                        return new MethodGroupExpr (best, queriedType, loc) {
-                               best_candidate = best
+                               best_candidate = best,
+                               best_candidate_return = best.ReturnType
                        };
                }
 
@@ -3057,7 +3167,7 @@ namespace Mono.CSharp {
                        if (r.BestCandidateNewMethodGroup != null)
                                return r.BestCandidateNewMethodGroup;
 
-                       if (best_candidate.Kind == MemberKind.Method) {
+                       if (best_candidate.Kind == MemberKind.Method && (restr & OverloadResolver.Restrictions.ProbingOnly) == 0) {
                                if (InstanceExpression != null) {
                                        if (best_candidate.IsExtensionMethod && args[0].Expr == InstanceExpression) {
                                                InstanceExpression = null;
@@ -3070,17 +3180,19 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               ResolveInstanceExpression (ec);
+                               ResolveInstanceExpression (ec, null);
                                if (InstanceExpression != null)
                                        CheckProtectedMemberAccess (ec, best_candidate);
+                       }
 
-                               if (best_candidate.IsGeneric) {
-                                       ConstraintChecker.CheckAll (ec.MemberContext, best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments,
-                                               best_candidate.Constraints, loc);
-                               }
+                       var base_override = CandidateToBaseOverride (ec, best_candidate);
+                       if (base_override == best_candidate) {
+                               best_candidate_return = r.BestCandidateReturnType;
+                       } else {
+                               best_candidate = base_override;
+                               best_candidate_return = best_candidate.ReturnType;
                        }
 
-                       best_candidate = CandidateToBaseOverride (ec, best_candidate);
                        return this;
                }
 
@@ -3102,6 +3214,15 @@ namespace Mono.CSharp {
                        return baseType == null ? null : MemberCache.FindMembers (baseType, Methods [0].Name, false);
                }
 
+               public IParametersMember GetOverrideMemberParameters (MemberSpec member)
+               {
+                       if (queried_type == member.DeclaringType)
+                               return null;
+
+                       return MemberCache.FindMember (queried_type, new MemberFilter ((MethodSpec) member),
+                               BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as IParametersMember;
+               }
+
                //
                // Extension methods lookup after ordinary methods candidates failed to apply
                //
@@ -3136,13 +3257,15 @@ namespace Mono.CSharp {
                        None = 0,
                        DelegateInvoke = 1,
                        ProbingOnly     = 1 << 1,
-                       Covariant = 1 << 2,
-                       NoBaseMembers = 1 << 3
+                       CovariantDelegate = 1 << 2,
+                       NoBaseMembers = 1 << 3,
+                       BaseMembersIncluded = 1 << 4
                }
 
                public interface IBaseMembersProvider
                {
                        IList<MemberSpec> GetBaseMembers (TypeSpec baseType);
+                       IParametersMember GetOverrideMemberParameters (MemberSpec member);
                        MethodGroupExpr LookupExtensionMethod (ResolveContext rc);
                }
 
@@ -3163,6 +3286,11 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       public IParametersMember GetOverrideMemberParameters (MemberSpec member)
+                       {
+                               return null;
+                       }
+
                        public MethodGroupExpr LookupExtensionMethod (ResolveContext rc)
                        {
                                return null;
@@ -3173,10 +3301,12 @@ namespace Mono.CSharp {
                {
                        public readonly MemberSpec Member;
                        public readonly bool Expanded;
+                       public readonly AParametersCollection Parameters;
 
-                       public AmbiguousCandidate (MemberSpec member, bool expanded)
+                       public AmbiguousCandidate (MemberSpec member, AParametersCollection parameters, bool expanded)
                        {
                                Member = member;
+                               Parameters = parameters;
                                Expanded = expanded;
                        }
                }
@@ -3188,6 +3318,7 @@ namespace Mono.CSharp {
                IErrorHandler custom_errors;
                Restrictions restrictions;
                MethodGroupExpr best_candidate_extension_group;
+               TypeSpec best_candidate_return_type;
 
                SessionReportPrinter lambda_conv_msgs;
                ReportPrinter prev_recorder;
@@ -3235,6 +3366,15 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               // Return type can be different between best candidate and closest override
+               //
+               public TypeSpec BestCandidateReturnType {
+                       get {
+                               return best_candidate_return_type;
+                       }
+               }
+
                public IErrorHandler CustomErrors {
                        get {
                                return custom_errors;
@@ -3276,23 +3416,51 @@ namespace Mono.CSharp {
                static int BetterExpressionConversion (ResolveContext ec, Argument a, TypeSpec p, TypeSpec q)
                {
                        TypeSpec argument_type = a.Type;
-                       if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) {
+
+                       //
+                       // If argument is an anonymous function
+                       //
+                       if (argument_type == InternalType.AnonymousMethod && ec.Module.Compiler.Settings.Version > LanguageVersion.ISO_2) {
                                //
-                               // Uwrap delegate from Expression<T>
+                               // p and q are delegate types or expression tree types
                                //
-                               if (p.GetDefinition () == TypeManager.expression_type) {
+                               if (p.GetDefinition () == TypeManager.expression_type || q.GetDefinition () == TypeManager.expression_type) {
+                                       if (q.MemberDefinition != p.MemberDefinition) {
+                                               return 0;
+                                       }
+
+                                       //
+                                       // Uwrap delegate from Expression<T>
+                                       //
+                                       q = TypeManager.GetTypeArguments (q)[0];
                                        p = TypeManager.GetTypeArguments (p)[0];
                                }
-                               if (q.GetDefinition () == TypeManager.expression_type) {
-                                       q = TypeManager.GetTypeArguments (q)[0];
+
+                               var p_m = Delegate.GetInvokeMethod (p);
+                               var q_m = Delegate.GetInvokeMethod (q);
+
+                               //
+                               // With identical parameter lists
+                               //
+                               if (!TypeSpecComparer.Equals (p_m.Parameters.Types,q_m.Parameters.Types))
+                                       return 0;
+
+                               p = p_m.ReturnType;
+                               q = q_m.ReturnType;
+
+                               //
+                               // if p is void returning, and q has a return type Y, then C2 is the better conversion.
+                               //
+                               if (p == TypeManager.void_type) {
+                                       return q != TypeManager.void_type ? 2 : 0;
                                }
 
-                               p = Delegate.GetInvokeMethod (ec.Compiler, p).ReturnType;
-                               q = Delegate.GetInvokeMethod (ec.Compiler, q).ReturnType;
-                               if (p == TypeManager.void_type && q != TypeManager.void_type)
-                                       return 2;
-                               if (q == TypeManager.void_type && p != TypeManager.void_type)
-                                       return 1;
+                               //
+                               // if p has a return type Y, and q is void returning, then C1 is the better conversion.
+                               //
+                               if (q == TypeManager.void_type) {
+                                       return p != TypeManager.void_type ? 1: 0;
+                               }
                        } else {
                                if (argument_type == p)
                                        return 1;
@@ -3327,8 +3495,8 @@ namespace Mono.CSharp {
                                        q == TypeManager.uint64_type)
                                        return 1;
                        } else if (p == InternalType.Dynamic) {
-                               if (q == TypeManager.object_type)
-                                       return 2;
+                               // Dynamic is never better
+                               return 2;
                        }
 
                        if (q == TypeManager.int32_type) {
@@ -3346,10 +3514,12 @@ namespace Mono.CSharp {
                                        p == TypeManager.uint64_type)
                                        return 2;
                        } else if (q == InternalType.Dynamic) {
-                               if (p == TypeManager.object_type)
-                                       return 1;
+                               // Dynamic is never better
+                               return 1;
                        }
 
+                       // FIXME: handle lifted operators
+
                        // TODO: this is expensive
                        Expression p_tmp = new EmptyExpression (p);
                        Expression q_tmp = new EmptyExpression (q);
@@ -3375,8 +3545,8 @@ namespace Mono.CSharp {
                ///     false if candidate ain't better
                ///     true  if candidate is better than the current best match
                /// </remarks>
-               static bool BetterFunction (ResolveContext ec, Arguments args, MemberSpec candidate, bool candidate_params,
-                       MemberSpec best, bool best_params)
+               static bool BetterFunction (ResolveContext ec, Arguments args, MemberSpec candidate, AParametersCollection cparam, bool candidate_params,
+                       MemberSpec best, AParametersCollection bparam, bool best_params)
                {
                        AParametersCollection candidate_pd = ((IParametersMember) candidate).Parameters;
                        AParametersCollection best_pd = ((IParametersMember) best).Parameters;
@@ -3385,27 +3555,46 @@ namespace Mono.CSharp {
                        bool same = true;
                        int args_count = args == null ? 0 : args.Count;
                        int j = 0;
+                       Argument a = null;
+                       TypeSpec ct, bt;
                        for (int c_idx = 0, b_idx = 0; j < args_count; ++j, ++c_idx, ++b_idx) {
-                               Argument a = args[j];
+                               a = args[j];
 
                                // Default arguments are ignored for better decision
                                if (a.IsDefaultArgument)
                                        break;
 
-                               TypeSpec ct = candidate_pd.Types[c_idx];
-                               TypeSpec bt = best_pd.Types[b_idx];
+                               //
+                               // When comparing named argument the parameter type index has to be looked up
+                               // in original parameter set (override version for virtual members)
+                               //
+                               NamedArgument na = a as NamedArgument;
+                               if (na != null) {
+                                       int idx = cparam.GetParameterIndexByName (na.Name);
+                                       ct = candidate_pd.Types[idx];
+                                       if (candidate_params && candidate_pd.FixedParameters[idx].ModFlags == Parameter.Modifier.PARAMS)
+                                               ct = TypeManager.GetElementType (ct);
+
+                                       idx = bparam.GetParameterIndexByName (na.Name);
+                                       bt = best_pd.Types[idx];
+                                       if (best_params && best_pd.FixedParameters[idx].ModFlags == Parameter.Modifier.PARAMS)
+                                               bt = TypeManager.GetElementType (bt);
+                               } else {
+                                       ct = candidate_pd.Types[c_idx];
+                                       bt = best_pd.Types[b_idx];
 
-                               if (candidate_params && candidate_pd.FixedParameters[c_idx].ModFlags == Parameter.Modifier.PARAMS) {
-                                       ct = TypeManager.GetElementType (ct);
-                                       --c_idx;
-                               }
+                                       if (candidate_params && candidate_pd.FixedParameters[c_idx].ModFlags == Parameter.Modifier.PARAMS) {
+                                               ct = TypeManager.GetElementType (ct);
+                                               --c_idx;
+                                       }
 
-                               if (best_params && best_pd.FixedParameters[b_idx].ModFlags == Parameter.Modifier.PARAMS) {
-                                       bt = TypeManager.GetElementType (bt);
-                                       --b_idx;
+                                       if (best_params && best_pd.FixedParameters[b_idx].ModFlags == Parameter.Modifier.PARAMS) {
+                                               bt = TypeManager.GetElementType (bt);
+                                               --b_idx;
+                                       }
                                }
 
-                               if (ct == bt)
+                               if (TypeSpecComparer.IsEqual (ct, bt))
                                        continue;
 
                                same = false;
@@ -3434,7 +3623,7 @@ namespace Mono.CSharp {
                        // The call Add (3, 4, 5) should be ambiguous.  Without this check, the
                        // first candidate would've chosen as better.
                        //
-                       if (!same)
+                       if (!same && !a.IsDefaultArgument)
                                return false;
 
                        //
@@ -3450,6 +3639,7 @@ namespace Mono.CSharp {
                        // Prefer non-optional version
                        //
                        // LAMESPEC: Specification claims this should be done at last but the opposite is true
+                       //
                        if (candidate_params == best_params && candidate_pd.Count != best_pd.Count) {
                                if (candidate_pd.Count >= best_pd.Count)
                                        return false;
@@ -3494,9 +3684,16 @@ namespace Mono.CSharp {
                        var best_def_pd = ((IParametersMember) best.MemberDefinition).Parameters;
 
                        bool specific_at_least_once = false;
-                       for (j = 0; j < candidate_param_count; ++j) {
-                               var ct = candidate_def_pd.Types[j];
-                               var bt = best_def_pd.Types[j];
+                       for (j = 0; j < args_count; ++j) {
+                               NamedArgument na = args_count == 0 ? null : args [j] as NamedArgument;
+                               if (na != null) {
+                                       ct = candidate_def_pd.Types[cparam.GetParameterIndexByName (na.Name)];
+                                       bt = best_def_pd.Types[bparam.GetParameterIndexByName (na.Name)];
+                               } else {
+                                       ct = candidate_def_pd.Types[j];
+                                       bt = best_def_pd.Types[j];
+                               }
+
                                if (ct == bt)
                                        continue;
                                TypeSpec specific = MoreSpecific (ct, bt);
@@ -3509,9 +3706,6 @@ namespace Mono.CSharp {
                        if (specific_at_least_once)
                                return true;
 
-                       // FIXME: handle lifted operators
-                       // ...
-
                        return false;
                }
 
@@ -3522,17 +3716,27 @@ namespace Mono.CSharp {
                                type.GetSignatureForError (), argCount.ToString ());
                }
 
-               ///
-               /// Determines if the candidate method is applicable (section 14.4.2.1)
-               /// to the given set of arguments
-               /// A return value rates candidate method compatibility,
-               /// 0 = the best, int.MaxValue = the worst
-               ///
-               int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, ref bool params_expanded_form)
+               //
+               // Determines if the candidate method is applicable to the given set of arguments
+               // There could be two different set of parameters for same candidate where one
+               // is the closest override for default values and named arguments checks and second
+               // one being the virtual base for the parameter types and modifiers.
+               //
+               // A return value rates candidate method compatibility,
+               // 0 = the best, int.MaxValue = the worst
+               //
+               int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType)
                {
-                       AParametersCollection pd = ((IParametersMember) candidate).Parameters;
+                       // Parameters of most-derived type used mainly for named and optional parameters
+                       var pd = pm.Parameters;
+
+                       // Used for params modifier only, that's legacy of C# 1.0 which uses base type for
+                       // params modifier instead of most-derived type
+                       var cpd = ((IParametersMember) candidate).Parameters;
                        int param_count = pd.Count;
                        int optional_count = 0;
+                       int score;
+                       Arguments orig_args = arguments;
 
                        if (arg_count != param_count) {
                                for (int i = 0; i < pd.Count; ++i) {
@@ -3542,42 +3746,37 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               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;
-
                                        // Readjust expected number when params used
-                                       if (pd.HasParams) {
+                                       if (cpd.HasParams) {
                                                optional_count--;
                                                if (arg_count < param_count)
                                                        param_count--;
                                        } else if (arg_count > param_count) {
+                                               int args_gap = System.Math.Abs (arg_count - param_count);
                                                return int.MaxValue - 10000 + args_gap;
                                        }
                                } else if (arg_count != param_count) {
-                                       if (!pd.HasParams)
+                                       int args_gap = System.Math.Abs (arg_count - param_count);
+                                       if (!cpd.HasParams)
                                                return int.MaxValue - 10000 + args_gap;
                                        if (arg_count < param_count - 1)
                                                return int.MaxValue - 10000 + args_gap;
                                }
 
-                               // Initialize expanded form of a method with 1 params parameter
-                               params_expanded_form = param_count == 1 && pd.HasParams;
-
                                // Resize to fit optional arguments
                                if (optional_count != 0) {
-                                       Arguments resized;
                                        if (arguments == null) {
-                                               resized = new Arguments (optional_count);
+                                               arguments = new Arguments (optional_count);
                                        } else {
-                                               resized = new Arguments (param_count);
+                                               // Have to create a new container, so the next run can do same
+                                               var resized = new Arguments (param_count);
                                                resized.AddRange (arguments);
+                                               arguments = resized;
                                        }
 
                                        for (int i = arg_count; i < param_count; ++i)
-                                               resized.Add (null);
-                                       arguments = resized;
+                                               arguments.Add (null);
                                }
                        }
 
@@ -3597,20 +3796,36 @@ namespace Mono.CSharp {
 
                                                        int index = pd.GetParameterIndexByName (na.Name);
 
-                                                       // Named parameter not found or already reordered
-                                                       if (index <= i)
-                                                               break;
+                                                       // Named parameter not found
+                                                       if (index < 0)
+                                                               return (i + 1) * 3;
 
-                                                       // When using parameters which should not be available to the user
-                                                       if (index >= param_count)
+                                                       // already reordered
+                                                       if (index == i)
                                                                break;
 
+                                                       Argument temp;
+                                                       if (index >= param_count) {
+                                                               // When using parameters which should not be available to the user
+                                                               if ((cpd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
+                                                                       break;
+
+                                                               arguments.Add (null);
+                                                               ++arg_count;
+                                                               temp = null;
+                                                       } else {
+                                                               temp = arguments[index];
+
+                                                               // The slot has been taken by positional argument
+                                                               if (temp != null && !(temp is NamedArgument))
+                                                                       break;
+                                                       }
+
                                                        if (!arg_moved) {
-                                                               arguments.MarkReorderedArgument (na);
+                                                               arguments = arguments.MarkOrderedArgument (na);
                                                                arg_moved = true;
                                                        }
 
-                                                       Argument temp = arguments[index];
                                                        arguments[index] = arguments[i];
                                                        arguments[i] = temp;
 
@@ -3628,15 +3843,18 @@ namespace Mono.CSharp {
                        //
                        // 1. Handle generic method using type arguments when specified or type inference
                        //
+                       TypeSpec[] ptypes;
                        var ms = candidate as MethodSpec;
                        if (ms != null && ms.IsGeneric) {
+                               // Setup constraint checker for probing only
+                               ConstraintChecker cc = new ConstraintChecker (null);
+
                                if (type_arguments != null) {
                                        var g_args_count = ms.Arity;
                                        if (g_args_count != type_arguments.Count)
                                                return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count);
 
-                                       candidate = ms = ms.MakeGenericMethod (type_arguments.Arguments);
-                                       pd = ms.Parameters;
+                                       ms = ms.MakeGenericMethod (ec, type_arguments.Arguments);
                                } else {
                                        // TODO: It should not be here (we don't know yet whether any argument is lambda) but
                                        // for now it simplifies things. I should probably add a callback to ResolveContext
@@ -3645,18 +3863,50 @@ namespace Mono.CSharp {
                                                prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
                                        }
 
-                                       int score = TypeManager.InferTypeArguments (ec, arguments, ref ms);
+                                       var ti = new TypeInference (arguments);
+                                       TypeSpec[] i_args = ti.InferMethodArguments (ec, ms);
                                        lambda_conv_msgs.EndSession ();
 
-                                       if (score != 0)
-                                               return score - 20000;
+                                       if (i_args == null)
+                                               return ti.InferenceScore - 20000;
+
+                                       if (i_args.Length != 0) {
+                                               ms = ms.MakeGenericMethod (ec, i_args);
+                                       }
+
+                                       cc.IgnoreInferredDynamic = true;
+                               }
 
+                               //
+                               // Type arguments constraints have to match for the method to be applicable
+                               //
+                               if (!cc.CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc)) {
                                        candidate = ms;
-                                       pd = ms.Parameters;
+                                       return int.MaxValue - 25000;
+                               }
+
+                               //
+                               // We have a generic return type and at same time the method is override which
+                               // means we have to also inflate override return type in case the candidate is
+                               // best candidate and override return type is different to base return type.
+                               // 
+                               // virtual Foo<T, object> with override Foo<T, dynamic>
+                               //
+                               if (candidate != pm) {
+                                       MethodSpec override_ms = (MethodSpec) pm;
+                                       var inflator = new TypeParameterInflator (ec, ms.DeclaringType, override_ms.GenericDefinition.TypeParameters, ms.TypeArguments);
+                                       returnType = inflator.Inflate (returnType);
+                               } else {
+                                       returnType = ms.ReturnType;
                                }
+
+                               candidate = ms;
+                               ptypes = ms.Parameters.Types;
                        } else {
                                if (type_arguments != null)
                                        return int.MaxValue - 15000;
+
+                               ptypes = cpd.Types;
                        }
 
                        //
@@ -3664,64 +3914,153 @@ namespace Mono.CSharp {
                        //
                        Parameter.Modifier p_mod = 0;
                        TypeSpec pt = null;
+
                        for (int i = 0; i < arg_count; i++) {
                                Argument a = arguments[i];
                                if (a == null) {
-                                       if (!pd.FixedParameters[i].HasDefaultValue)
-                                               throw new InternalErrorException ();
+                                       if (!pd.FixedParameters[i].HasDefaultValue) {
+                                               arguments = orig_args;
+                                               return arg_count * 2 + 2;
+                                       }
 
-                                       Expression e = pd.FixedParameters[i].DefaultValue as Constant;
-                                       if (e == null || e.Type.IsGenericOrParentIsGeneric)
-                                               e = new DefaultValueExpression (new TypeExpression (pd.Types[i], loc), loc).Resolve (ec);
+                                       //
+                                       // Get the default value expression, we can use the same expression
+                                       // if the type matches
+                                       //
+                                       Expression e = pd.FixedParameters[i].DefaultValue;
+                                       if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric) {
+                                               //
+                                               // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
+                                               //
+                                               if (e == EmptyExpression.MissingValue && ptypes[i] == TypeManager.object_type || ptypes[i] == InternalType.Dynamic) {
+                                                       e = new MemberAccess (new MemberAccess (new MemberAccess (
+                                                               new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc);
+                                               } else {
+                                                       e = new DefaultValueExpression (new TypeExpression (ptypes [i], loc), loc);
+                                               }
+
+                                               e = e.Resolve (ec);
+                                       }
 
                                        arguments[i] = new Argument (e, Argument.AType.Default);
                                        continue;
                                }
 
                                if (p_mod != Parameter.Modifier.PARAMS) {
-                                       p_mod = pd.FixedParameters[i].ModFlags & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
-                                       pt = pd.Types[i];
-                               } else {
+                                       p_mod = (pd.FixedParameters[i].ModFlags & ~Parameter.Modifier.PARAMS) | (cpd.FixedParameters[i].ModFlags & Parameter.Modifier.PARAMS);
+                                       pt = ptypes [i];
+                               } else if (!params_expanded_form) {
                                        params_expanded_form = true;
+                                       pt = ((ElementTypeSpec) pt).Element;
+                                       i -= 2;
+                                       continue;
                                }
 
-                               Parameter.Modifier a_mod = a.Modifier & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
-                               int score = 1;
-                               if (!params_expanded_form)
-                                       score = IsArgumentCompatible (ec, a_mod, a, p_mod & ~Parameter.Modifier.PARAMS, pt);
+                               score = 1;
+                               if (!params_expanded_form) {
+                                       if (a.ArgType == Argument.AType.ExtensionType) {
+                                               //
+                                               // Indentity, implicit reference or boxing conversion must exist for the extension parameter
+                                               //
+                                               var at = a.Type;
+                                               if (at == pt || TypeSpecComparer.IsEqual (at, pt) ||
+                                                       Convert.ImplicitReferenceConversionExists (a.Expr, pt) ||
+                                                       Convert.ImplicitBoxingConversion (EmptyExpression.Null, at, pt) != null) {
+                                                       score = 0;
+                                                       continue;
+                                               }
+                                       } else {
+                                               score = IsArgumentCompatible (ec, a, p_mod & ~Parameter.Modifier.PARAMS, pt);
+
+                                               if (score < 0)
+                                                       dynamicArgument = true;
+                                       }
+                               }
 
                                //
                                // It can be applicable in expanded form (when not doing exact match like for delegates)
                                //
-                               if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && (restrictions & Restrictions.Covariant) == 0) {
-                                       score = IsArgumentCompatible (ec, a_mod, a, 0, TypeManager.GetElementType (pt));
-                                       if (score == 0)
+                               if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && (restrictions & Restrictions.CovariantDelegate) == 0) {
+                                       if (!params_expanded_form)
+                                               pt = ((ElementTypeSpec) pt).Element;
+
+                                       if (score > 0)
+                                               score = IsArgumentCompatible (ec, a, Parameter.Modifier.NONE, pt);
+
+                                       if (score == 0) {
                                                params_expanded_form = true;
+                                       } else if (score < 0) {
+                                               params_expanded_form = true;
+                                               dynamicArgument = true;
+                                       }
                                }
 
-                               if (score != 0) {
+                               if (score > 0) {
                                        if (params_expanded_form)
                                                ++score;
                                        return (arg_count - i) * 2 + score;
                                }
                        }
 
-                       if (arg_count != pd.Count)
+                       //
+                       // When params parameter has no argument it will be provided later if the method is the best candidate
+                       //
+                       if (arg_count + 1 == pd.Count && (cpd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
                                params_expanded_form = true;
 
+                       //
+                       // Restore original arguments for dynamic binder to keep the intention of original source code
+                       //
+                       if (dynamicArgument)
+                               arguments = orig_args;
+
                        return 0;
                }
 
-               int IsArgumentCompatible (ResolveContext ec, Parameter.Modifier arg_mod, Argument argument, Parameter.Modifier param_mod, TypeSpec parameter)
+               //
+               // Tests argument compatibility with the parameter
+               // The possible return values are
+               // 0 - success
+               // 1 - modifier mismatch
+               // 2 - type mismatch
+               // -1 - dynamic binding required
+               //
+               int IsArgumentCompatible (ResolveContext ec, Argument argument, Parameter.Modifier param_mod, TypeSpec parameter)
                {
                        //
-                       // Types have to be identical when ref or out modifer is used 
+                       // Types have to be identical when ref or out modifer
+                       // is used and argument is not of dynamic type
                        //
-                       if ((arg_mod | param_mod) != 0) {
-                               if (argument.Type != parameter && !TypeSpecComparer.IsEqual (argument.Type, parameter)) {
-                                       return 2;
+                       if ((argument.Modifier | param_mod) != 0) {
+                               if (argument.Type != parameter) {
+                                       //
+                                       // Do full equality check after quick path
+                                       //
+                                       if (!TypeSpecComparer.IsEqual (argument.Type, parameter)) {
+                                               //
+                                               // Using dynamic for ref/out parameter can still succeed at runtime
+                                               //
+                                               if (argument.Type == InternalType.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
+                                                       return -1;
+
+                                               return 2;
+                                       }
+                               }
+
+                               if (argument.Modifier != param_mod) {
+                                       //
+                                       // Using dynamic for ref/out parameter can still succeed at runtime
+                                       //
+                                       if (argument.Type == InternalType.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
+                                               return -1;
+
+                                       return 1;
                                }
+
                        } else {
+                               if (argument.Type == InternalType.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0)
+                                       return -1;
+
                                //
                                // Deploy custom error reporting for lambda methods. When probing lambda methods
                                // keep all errors reported in separate set and once we are done and no best
@@ -3740,16 +4079,10 @@ namespace Mono.CSharp {
                                                lambda_conv_msgs.EndSession ();
                                        }
 
-                                       if (argument.Type == InternalType.Dynamic)
-                                               return 0;
-
                                        return 2;
                                }
                        }
 
-                       if (arg_mod != param_mod)
-                               return 1;
-
                        return 0;
                }
 
@@ -3802,9 +4135,12 @@ namespace Mono.CSharp {
                        MemberSpec best_candidate;
                        Arguments best_candidate_args = null;
                        bool best_candidate_params = false;
+                       bool best_candidate_dynamic = false;
                        int best_candidate_rate;
+                       IParametersMember best_parameter_member = null;
 
                        int args_count = args != null ? args.Count : 0;
+
                        Arguments candidate_args = args;
                        bool error_mode = false;
                        var current_type = rc.CurrentType;
@@ -3829,10 +4165,16 @@ namespace Mono.CSharp {
                                                        if ((member.Modifiers & Modifiers.OVERRIDE) != 0)
                                                                continue;
 
-                                                       if (!member.IsAccessible (current_type) && !error_mode)
-                                                               continue;
+                                                       if (!error_mode) {
+                                                               if (!member.IsAccessible (current_type))
+                                                                       continue;
+
+                                                               if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (current_type))
+                                                                       continue;
+                                                       }
 
-                                                       if (!(member is IParametersMember)) {
+                                                       IParametersMember pm = member as IParametersMember;
+                                                       if (pm == null) {
                                                                //
                                                                // Will use it later to report ambiguity between best method and invocable member
                                                                //
@@ -3843,10 +4185,23 @@ namespace Mono.CSharp {
                                                        }
 
                                                        //
-                                                       // Check if candidate is applicable
+                                                       // Overload resolution is looking for base member but using parameter names
+                                                       // and default values from the closest member. That means to do expensive lookup
+                                                       // for the closest override for virtual or abstract members
+                                                       //
+                                                       if ((member.Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
+                                                               var override_params = base_provider.GetOverrideMemberParameters (member);
+                                                               if (override_params != null)
+                                                                       pm = override_params;
+                                                       }
+
+                                                       //
+                                                       // Check if the member candidate is applicable
                                                        //
                                                        bool params_expanded_form = false;
-                                                       int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, ref params_expanded_form);
+                                                       bool dynamic_argument = false;
+                                                       TypeSpec rt = pm.MemberType;
+                                                       int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt);
 
                                                        //
                                                        // How does it score compare to others
@@ -3856,18 +4211,65 @@ namespace Mono.CSharp {
                                                                best_candidate = member;
                                                                best_candidate_args = candidate_args;
                                                                best_candidate_params = params_expanded_form;
+                                                               best_candidate_dynamic = dynamic_argument;
+                                                               best_parameter_member = pm;
+                                                               best_candidate_return_type = rt;
                                                        } else if (candidate_rate == 0) {
-                                                               // Is new candidate better
-                                                               if (BetterFunction (rc, candidate_args, member, params_expanded_form, best_candidate, best_candidate_params)) {
+                                                               //
+                                                               // The member look is done per type for most operations but sometimes
+                                                               // it's not possible like for binary operators overload because they
+                                                               // are unioned between 2 sides
+                                                               //
+                                                               if ((restrictions & Restrictions.BaseMembersIncluded) != 0) {
+                                                                       if (TypeSpec.IsBaseClass (best_candidate.DeclaringType, member.DeclaringType, true))
+                                                                               continue;
+                                                               }
+
+                                                               bool is_better;
+                                                               if (best_candidate.DeclaringType.IsInterface && member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
+                                                                       //
+                                                                       // We pack all interface members into top level type which makes the overload resolution
+                                                                       // more complicated for interfaces. We compensate it by removing methods with same
+                                                                       // signature when building the cache hence this path should not really be hit often
+                                                                       //
+                                                                       // Example:
+                                                                       // interface IA { void Foo (int arg); }
+                                                                       // interface IB : IA { void Foo (params int[] args); }
+                                                                       //
+                                                                       // IB::Foo is the best overload when calling IB.Foo (1)
+                                                                       //
+                                                                       is_better = true;
+                                                                       if (ambiguous_candidates != null) {
+                                                                               foreach (var amb_cand in ambiguous_candidates) {
+                                                                                       if (member.DeclaringType.ImplementsInterface (best_candidate.DeclaringType, false)) {
+                                                                                               continue;
+                                                                                       }
+
+                                                                                       is_better = false;
+                                                                                       break;
+                                                                               }
+
+                                                                               if (is_better)
+                                                                                       ambiguous_candidates = null;
+                                                                       }
+                                                               } else {
+                                                                       // Is the new candidate better
+                                                                       is_better = BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params);
+                                                               }
+
+                                                               if (is_better) {
                                                                        best_candidate = member;
                                                                        best_candidate_args = candidate_args;
                                                                        best_candidate_params = params_expanded_form;
+                                                                       best_candidate_dynamic = dynamic_argument;
+                                                                       best_parameter_member = pm;
+                                                                       best_candidate_return_type = rt;
                                                                } else {
                                                                        // It's not better but any other found later could be but we are not sure yet
                                                                        if (ambiguous_candidates == null)
                                                                                ambiguous_candidates = new List<AmbiguousCandidate> ();
 
-                                                                       ambiguous_candidates.Add (new AmbiguousCandidate (member, params_expanded_form));
+                                                                       ambiguous_candidates.Add (new AmbiguousCandidate (member, pm.Parameters, params_expanded_form));
                                                                }
                                                        }
 
@@ -3916,16 +4318,15 @@ namespace Mono.CSharp {
                        // No best member match found, report an error
                        //
                        if (best_candidate_rate != 0 || error_mode) {
-                               ReportOverloadError (rc, best_candidate, best_candidate_args, best_candidate_params);
+                               ReportOverloadError (rc, best_candidate, best_parameter_member, best_candidate_args, best_candidate_params);
                                return null;
                        }
 
-                       // TODO: quite slow
-                       if (args_count != 0 && args.HasDynamic) {
-                               if (args [0].ArgType == Argument.AType.ExtensionType) {
+                       if (best_candidate_dynamic) {
+                               if (args[0].ArgType == Argument.AType.ExtensionType) {
                                        rc.Report.Error (1973, loc,
                                                "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' cannot be dynamically dispatched. Consider calling the method without the extension method syntax",
-                                               args [0].Type.GetSignatureForError (), best_candidate.Name, best_candidate.GetSignatureForError());
+                                               args [0].Type.GetSignatureForError (), best_candidate.Name, best_candidate.GetSignatureForError ());
                                }
 
                                BestCandidateIsDynamic = true;
@@ -3940,7 +4341,7 @@ namespace Mono.CSharp {
                                for (int ix = 0; ix < ambiguous_candidates.Count; ix++) {
                                        var candidate = ambiguous_candidates [ix];
 
-                                       if (!BetterFunction (rc, candidate_args, best_candidate, best_candidate_params, candidate.Member, candidate.Expanded)) {
+                                       if (!BetterFunction (rc, best_candidate_args, best_candidate, best_parameter_member.Parameters, best_candidate_params, candidate.Member, candidate.Parameters, candidate.Expanded)) {
                                                var ambiguous = candidate.Member;
                                                if (custom_errors == null || !custom_errors.AmbiguousCandidates (rc, best_candidate, ambiguous)) {
                                                        rc.Report.SymbolRelatedToPreviousError (best_candidate);
@@ -3967,7 +4368,7 @@ namespace Mono.CSharp {
                        // necessary etc. and return if everything is
                        // all right
                        //
-                       if (!VerifyArguments (rc, ref best_candidate_args, best_candidate, best_candidate_params))
+                       if (!VerifyArguments (rc, ref best_candidate_args, best_candidate, best_parameter_member, best_candidate_params))
                                return null;
 
                        if (best_candidate == null)
@@ -3980,6 +4381,11 @@ namespace Mono.CSharp {
                        if (oa != null && !rc.IsObsolete)
                                AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
 
+                       var dep = best_candidate.GetMissingDependencies ();
+                       if (dep != null) {
+                               ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
+                       }
+
                        best_candidate.MemberDefinition.SetIsUsed ();
 
                        args = best_candidate_args;
@@ -4044,7 +4450,7 @@ namespace Mono.CSharp {
                //
                // We have failed to find exact match so we return error info about the closest match
                //
-               void ReportOverloadError (ResolveContext rc, MemberSpec best_candidate, Arguments args, bool params_expanded)
+               void ReportOverloadError (ResolveContext rc, MemberSpec best_candidate, IParametersMember pm, Arguments args, bool params_expanded)
                {
                        int ta_count = type_arguments == null ? 0 : type_arguments.Count;
                        int arg_count = args == null ? 0 : args.Count;
@@ -4063,29 +4469,37 @@ namespace Mono.CSharp {
                        //
                        // For candidates which match on parameters count report more details about incorrect arguments
                        //
-                       var pm = best_candidate as IParametersMember;
                        if (pm != null) {
-                               int unexpanded_count = pm.Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count;
+                               int unexpanded_count = ((IParametersMember) best_candidate).Parameters.HasParams ? pm.Parameters.Count - 1 : pm.Parameters.Count;
                                if (pm.Parameters.Count == arg_count || params_expanded || unexpanded_count == arg_count) {
                                        // Reject any inaccessible member
-                                       if (!best_candidate.IsAccessible (rc.CurrentType)) {
+                                       if (!best_candidate.IsAccessible (rc.CurrentType) || !best_candidate.DeclaringType.IsAccessible (rc.CurrentType)) {
                                                rc.Report.SymbolRelatedToPreviousError (best_candidate);
                                                Expression.ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
                                                return;
                                        }
 
                                        var ms = best_candidate as MethodSpec;
-                                       if (ms != null && ms.IsGeneric && ta_count == 0) {
-                                               if (custom_errors != null && custom_errors.TypeInferenceFailed (rc, best_candidate))
-                                                       return;
+                                       if (ms != null && ms.IsGeneric) {
+                                               bool constr_ok = true;
+                                               if (ms.TypeArguments != null)
+                                                       constr_ok = new ConstraintChecker (rc.MemberContext).CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc);
+
+                                               if (ta_count == 0) {
+                                                       if (custom_errors != null && custom_errors.TypeInferenceFailed (rc, best_candidate))
+                                                               return;
+
+                                                       if (constr_ok) {
+                                                               rc.Report.Error (411, loc,
+                                                                       "The type arguments for method `{0}' cannot be inferred from the usage. Try specifying the type arguments explicitly",
+                                                                       ms.GetGenericMethodDefinition ().GetSignatureForError ());
+                                                       }
 
-                                               rc.Report.Error (411, loc,
-                                                       "The type arguments for method `{0}' cannot be inferred from the usage. Try specifying the type arguments explicitly",
-                                                       ms.GetGenericMethodDefinition ().GetSignatureForError ());
-                                               return;
+                                                       return;
+                                               }
                                        }
 
-                                       VerifyArguments (rc, ref args, best_candidate, params_expanded);
+                                       VerifyArguments (rc, ref args, best_candidate, pm, params_expanded);
                                        return;
                                }
                        }
@@ -4111,10 +4525,10 @@ namespace Mono.CSharp {
                        }
                }
 
-               bool VerifyArguments (ResolveContext ec, ref Arguments args, MemberSpec member, bool chose_params_expanded)
+               bool VerifyArguments (ResolveContext ec, ref Arguments args, MemberSpec member, IParametersMember pm, bool chose_params_expanded)
                {
-                       var pm = member as IParametersMember;
                        var pd = pm.Parameters;
+                       TypeSpec[] ptypes = ((IParametersMember) member).Parameters.Types;
 
                        Parameter.Modifier p_mod = 0;
                        TypeSpec pt = null;
@@ -4128,7 +4542,7 @@ namespace Mono.CSharp {
                                a = args[a_idx];
                                if (p_mod != Parameter.Modifier.PARAMS) {
                                        p_mod = pd.FixedParameters[a_idx].ModFlags;
-                                       pt = pd.Types[a_idx];
+                                       pt = ptypes[a_idx];
                                        has_unsafe_arg |= pt.IsPointer;
 
                                        if (p_mod == Parameter.Modifier.PARAMS) {
@@ -4182,12 +4596,24 @@ namespace Mono.CSharp {
                                if (a.Expr.Type == InternalType.Dynamic)
                                        continue;
 
-                               if ((restrictions & Restrictions.Covariant) != 0 && !Delegate.IsTypeCovariant (a.Expr, pt)) {
+                               if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (ec, a.Expr, pt)) {
                                        custom_errors.NoArgumentMatch (ec, member);
                                        return false;
                                }
 
-                               Expression conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
+                               Expression conv = null;
+                               if (a.ArgType == Argument.AType.ExtensionType) {
+                                       if (a.Expr.Type == pt || TypeSpecComparer.IsEqual (a.Expr.Type, pt)) {
+                                               conv = a.Expr;
+                                       } else {
+                                               conv = Convert.ImplicitReferenceConversion (a.Expr, pt, false);
+                                               if (conv == null)
+                                                       conv = Convert.ImplicitBoxingConversion (a.Expr, a.Expr.Type, pt);
+                                       }
+                               } else {
+                                       conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
+                               }
+
                                if (conv == null)
                                        break;
 
@@ -4219,7 +4645,7 @@ namespace Mono.CSharp {
                                if (args == null)
                                        args = new Arguments (1);
 
-                               pt = pd.Types[pd.Count - 1];
+                               pt = ptypes[pd.Count - 1];
                                pt = TypeManager.GetElementType (pt);
                                has_unsafe_arg |= pt.IsPointer;
                                params_initializers = new ArrayInitializer (0, loc);
@@ -4238,6 +4664,20 @@ namespace Mono.CSharp {
                                Expression.UnsafeError (ec, loc);
                        }
 
+                       //
+                       // We could infer inaccesible type arguments
+                       //
+                       if (type_arguments == null && member.IsGeneric) {
+                               var ms = (MethodSpec) member;
+                               foreach (var ta in ms.TypeArguments) {
+                                       if (!ta.IsAccessible (ec.CurrentType)) {
+                                               ec.Report.SymbolRelatedToPreviousError (ta);
+                                               Expression.ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
+                                               break;
+                                       }
+                               }
+                       }
+
                        return true;
                }
        }
@@ -4275,7 +4715,7 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       ResolveInstanceExpression (rc);
+                       ResolveInstanceExpression (rc, null);
                        DoBestMemberChecks (rc, constant);
 
                        var c = constant.GetConstant (rc);
@@ -4328,7 +4768,7 @@ namespace Mono.CSharp {
                {
                }
 
-#region Properties
+               #region Properties
 
                public override string Name {
                        get {
@@ -4418,18 +4858,22 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       return DoResolve (ec, false, false);
+                       return DoResolve (ec, null);
                }
 
-               Expression DoResolve (ResolveContext ec, bool lvalue_instance, bool out_access)
+               Expression DoResolve (ResolveContext ec, Expression rhs)
                {
-                       if (ResolveInstanceExpression (ec)) {
+                       bool lvalue_instance = rhs != null && IsInstance && spec.DeclaringType.IsStruct;
+
+                       if (ResolveInstanceExpression (ec, rhs)) {
                                // Resolve the field's instance expression while flow analysis is turned
                                // off: when accessing a field "a.b", we must check whether the field
                                // "a.b" is initialized, not whether the whole struct "a" is initialized.
 
                                if (lvalue_instance) {
                                        using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                               bool out_access = rhs == EmptyExpression.OutAccess.Instance || rhs == EmptyExpression.LValueMemberOutAccess;
+
                                                Expression right_side =
                                                        out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
 
@@ -4443,10 +4887,6 @@ namespace Mono.CSharp {
 
                                if (InstanceExpression == null)
                                        return null;
-
-                               using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
-                                       InstanceExpression.CheckMarshalByRefAccess (ec);
-                               }
                        }
 
                        DoBestMemberChecks (ec, spec);
@@ -4528,10 +4968,7 @@ namespace Mono.CSharp {
                
                override public Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       bool lvalue_instance = IsInstance && spec.DeclaringType.IsStruct;
-                       bool out_access = right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess;
-
-                       Expression e = DoResolve (ec, lvalue_instance, out_access);
+                       Expression e = DoResolve (ec, right_side);
 
                        if (e == null)
                                return null;
@@ -4629,7 +5066,7 @@ namespace Mono.CSharp {
                                        EmitInstance (ec, false);
 
                                // Optimization for build-in types
-                               if (TypeManager.IsStruct (type) && type == ec.MemberContext.CurrentType && InstanceExpression.Type == type) {
+                               if (TypeManager.IsStruct (type) && type == ec.CurrentType && InstanceExpression.Type == type) {
                                        ec.EmitLoadFromPtr (type);
                                } else {
                                        var ff = spec as FixedFieldSpec;
@@ -4656,7 +5093,7 @@ namespace Mono.CSharp {
 
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       prepared = prepare_for_load;
+                       prepared = prepare_for_load && !(source is DynamicExpressionStatement);
                        if (IsInstance)
                                EmitInstance (ec, prepared);
 
@@ -4699,13 +5136,6 @@ namespace Mono.CSharp {
                                base.EmitSideEffect (ec);
                }
 
-               public override void Error_VariableIsUsedBeforeItIsDeclared (Report r, string name)
-               {
-                       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 ());
-               }
-
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        if ((mode & AddressOp.Store) != 0)
@@ -4720,7 +5150,7 @@ namespace Mono.CSharp {
                        bool need_copy;
                        if (spec.IsReadOnly){
                                need_copy = true;
-                               if (ec.HasSet (EmitContext.Options.ConstructorScope)){
+                               if (ec.HasSet (EmitContext.Options.ConstructorScope) && spec.DeclaringType == ec.CurrentType) {
                                        if (IsStatic){
                                                if (ec.IsStatic)
                                                        need_copy = false;
@@ -4756,7 +5186,13 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.GetMetaInfo ());
+#if STATIC
+                       return base.MakeExpression (ctx);
+#else
+                       return SLE.Expression.Field (
+                               IsStatic ? null : InstanceExpression.MakeExpression (ctx),
+                               spec.GetMetaInfo ());
+#endif
                }
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
@@ -4846,12 +5282,20 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeAssignExpression (BuilderContext ctx, Expression source)
                {
+#if STATIC
+                       return base.MakeExpression (ctx);
+#else
                        return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) Setter.GetMetaInfo ());
+#endif
                }
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
+#if STATIC
+                       return base.MakeExpression (ctx);
+#else
                        return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) Getter.GetMetaInfo ());
+#endif
                }
 
                void Error_PropertyNotValid (ResolveContext ec)
@@ -4896,9 +5340,10 @@ namespace Mono.CSharp {
 
                public override void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       Expression my_source = source;
+                       Arguments args;
 
-                       if (prepare_for_load) {
+                       if (prepare_for_load && !(source is DynamicExpressionStatement)) {
+                               args = new Arguments (0);
                                prepared = true;
                                source.Emit (ec);
                                
@@ -4909,16 +5354,19 @@ namespace Mono.CSharp {
                                                temp.Store (ec);
                                        }
                                }
-                       } else if (leave_copy) {
-                               source.Emit (ec);
-                               temp = new LocalTemporary (this.Type);
-                               temp.Store (ec);
-                               my_source = temp;
+                       } else {
+                               args = new Arguments (1);
+
+                               if (leave_copy) {
+                                       source.Emit (ec);
+                                       temp = new LocalTemporary (this.Type);
+                                       temp.Store (ec);
+                                       args.Add (new Argument (temp));
+                               } else {
+                                       args.Add (new Argument (source));
+                               }
                        }
 
-                       Arguments args = new Arguments (1);
-                       args.Add (new Argument (my_source));
-                       
                        Invocation.EmitCall (ec, InstanceExpression, Setter, args, loc, false, prepared);
                        
                        if (temp != null) {
@@ -4935,9 +5383,14 @@ namespace Mono.CSharp {
                                Error_PropertyNotValid (rc);
                        }
 
-                       if (ResolveInstanceExpression (rc)) {
-                               if (right_side != null && best_candidate.DeclaringType.IsStruct)
-                                       InstanceExpression.DoResolveLValue (rc, EmptyExpression.LValueMemberAccess);
+                       ResolveInstanceExpression (rc, right_side);
+
+                       if ((best_candidate.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0 && best_candidate.DeclaringType != InstanceExpression.Type) {
+                               var filter = new MemberFilter (best_candidate.Name, 0, MemberKind.Property, null, null);
+                               var p = MemberCache.FindMember (InstanceExpression.Type, filter, BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as PropertySpec;
+                               if (p != null) {
+                                       type = p.MemberType;
+                               }
                        }
 
                        DoBestMemberChecks (rc, best_candidate);
@@ -4993,9 +5446,6 @@ namespace Mono.CSharp {
                                if (expr == null)
                                        return null;
 
-                               if (InstanceExpression != null)
-                                       InstanceExpression.CheckMarshalByRefAccess (ec);
-
                                if (expr != this)
                                        return expr.Resolve (ec);
                        }
@@ -5010,7 +5460,8 @@ namespace Mono.CSharp {
                {
                        if (right_side == EmptyExpression.OutAccess.Instance) {
                                // TODO: best_candidate can be null at this point
-                               if (best_candidate != null && ec.CurrentBlock.Toplevel.GetParameterReference (best_candidate.Name, loc) is MemberAccess) {
+                               INamedBlockVariable variable = null;
+                               if (best_candidate != null && ec.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, ec.CurrentBlock, ref variable) && variable is Linq.RangeVariable) {
                                        ec.Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
                                                best_candidate.Name);
                                } else {
@@ -5085,13 +5536,8 @@ namespace Mono.CSharp {
                bool ResolveSetter (ResolveContext rc)
                {
                        if (!best_candidate.HasSet) {
-                               if (rc.CurrentBlock.Toplevel.GetParameterReference (best_candidate.Name, loc) is MemberAccess) {
-                                       rc.Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
-                                               best_candidate.Name);
-                               } else {
-                                       rc.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read-only)",
-                                               GetSignatureForError ());
-                               }
+                               rc.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read-only)",
+                                       GetSignatureForError ());
                                return false;
                        }
 
@@ -5165,16 +5611,12 @@ namespace Mono.CSharp {
                public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
                {
                        //
-                       // If the event is local to this class, we transform ourselves into a FieldExpr
+                       // If the event is local to this class and we are not lhs of +=/-= we transform ourselves into a FieldExpr
                        //
+                       if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
+                               if (spec.BackingField != null &&
+                                       (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType.MemberDefinition))) {
 
-                       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 = spec.MemberDefinition as EventField;
-
-                               if (spec.BackingField != null) {
                                        spec.MemberDefinition.SetIsUsed ();
 
                                        if (!ec.IsObsolete) {
@@ -5183,20 +5625,17 @@ namespace Mono.CSharp {
                                                        AttributeTester.Report_ObsoleteMessage (oa, spec.GetSignatureForError (), loc, ec.Report);
                                        }
 
-                                       if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+                                       if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
                                                Error_AssignmentEventOnly (ec);
-                                       
+
                                        FieldExpr ml = new FieldExpr (spec.BackingField, loc);
 
                                        InstanceExpression = null;
-                               
+
                                        return ml.ResolveMemberAccess (ec, left, original);
                                }
                        }
 
-                       if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))                        
-                               Error_AssignmentEventOnly (ec);
-
                        return base.ResolveMemberAccess (ec, left, original);
                }
 
@@ -5227,10 +5666,10 @@ namespace Mono.CSharp {
                        eclass = ExprClass.EventAccess;
                        type = spec.MemberType;
 
-                       ResolveInstanceExpression (ec);
+                       ResolveInstanceExpression (ec, null);
 
                        if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
-                               Error_CannotAssign (ec);
+                               Error_AssignmentEventOnly (ec);
                        }
 
                        DoBestMemberChecks (ec, spec);
@@ -5264,15 +5703,15 @@ namespace Mono.CSharp {
 
                void Error_AssignmentEventOnly (ResolveContext ec)
                {
-                       ec.Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
-                               GetSignatureForError ());
-               }
-
-               public void Error_CannotAssign (ResolveContext ec)
-               {
-                       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 (spec.DeclaringType));
+                       if (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType.MemberDefinition)) {
+                               ec.Report.Error (79, loc,
+                                       "The event `{0}' can only appear on the left hand side of `+=' or `-=' operator",
+                                       GetSignatureForError ());
+                       } else {
+                               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 (), spec.DeclaringType.GetSignatureForError ());
+                       }
                }
 
                protected override void Error_CannotCallAbstractBase (ResolveContext rc, string name)
@@ -5292,16 +5731,58 @@ namespace Mono.CSharp {
                }
        }
 
-       public class TemporaryVariable : VariableReference
+       public class TemporaryVariableReference : VariableReference
        {
-               LocalInfo li;
+               public class Declarator : Statement
+               {
+                       TemporaryVariableReference variable;
+
+                       public Declarator (TemporaryVariableReference variable)
+                       {
+                               this.variable = variable;
+                               loc = variable.loc;
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               variable.li.CreateBuilder (ec);
+                       }
 
-               public TemporaryVariable (TypeSpec type, Location loc)
+                       protected override void CloneTo (CloneContext clonectx, Statement target)
+                       {
+                               // Nothing
+                       }
+               }
+
+               LocalVariable li;
+
+               public TemporaryVariableReference (LocalVariable li, Location loc)
                {
-                       this.type = type;
+                       this.li = li;
+                       this.type = li.Type;
                        this.loc = loc;
                }
 
+               public override bool IsLockedByStatement {
+                       get {
+                               return false;
+                       }
+                       set {
+                       }
+               }
+
+               public LocalVariable LocalInfo {
+                   get {
+                       return li;
+                   }
+               }
+
+               public static TemporaryVariableReference Create (TypeSpec type, Block block, Location loc)
+               {
+                       var li = LocalVariable.CreateCompilerGenerated (type, block, loc);
+                       return new TemporaryVariableReference (li, loc);
+               }
+
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        throw new NotSupportedException ("ET");
@@ -5311,11 +5792,6 @@ namespace Mono.CSharp {
                {
                        eclass = ExprClass.Variable;
 
-                       TypeExpr te = new TypeExpression (type, loc);
-                       li = ec.CurrentBlock.AddTemporaryVariable (te, loc);
-                       if (!li.Resolve (ec))
-                               return null;
-
                        //
                        // Don't capture temporary variables except when using
                        // iterator redirection
@@ -5335,11 +5811,15 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
+                       li.CreateBuilder (ec);
+
                        Emit (ec, false);
                }
 
                public void EmitAssign (EmitContext ec, Expression source)
                {
+                       li.CreateBuilder (ec);
+
                        EmitAssign (ec, source, false, false);
                }
 
@@ -5380,19 +5860,9 @@ namespace Mono.CSharp {
        /// 
        class VarExpr : SimpleName
        {
-               // Used for error reporting only
-               int initializers_count;
-
                public VarExpr (Location loc)
                        : base ("var", loc)
                {
-                       initializers_count = 1;
-               }
-
-               public int VariableInitializersCount {
-                       set {
-                               this.initializers_count = value;
-                       }
                }
 
                public bool InferType (ResolveContext ec, Expression right_side)
@@ -5414,37 +5884,10 @@ namespace Mono.CSharp {
 
                protected override void Error_TypeOrNamespaceNotFound (IMemberContext ec)
                {
-                       if (RootContext.Version < LanguageVersion.V_3)
+                       if (ec.Module.Compiler.Settings.Version < LanguageVersion.V_3)
                                base.Error_TypeOrNamespaceNotFound (ec);
                        else
-                               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)
-               {
-                       TypeExpr te = base.ResolveAsContextualType (rc, true);
-                       if (te != null)
-                               return te;
-
-                       if (RootContext.Version < LanguageVersion.V_3)
-                               rc.Compiler.Report.FeatureIsNotAvailable (loc, "implicitly typed local variable");
-
-                       if (initializers_count == 1)
-                               return 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;
-                       }
-
-                       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;
-                       }
-
-                       return null;
+                               ec.Module.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
                }
        }
 }