Don't report ambiguous property error when one of the candidates is not C# compatible
[mono.git] / mcs / mcs / ecore.cs
index 25b11ab66a3fb166153c8938aa6dcb9be53911ff..e4a1d2d9dcc87c368a204ead4c0a0f6d3d682294 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 ();
@@ -183,63 +183,19 @@ namespace Mono.CSharp {
                // This is used if the expression should be resolved as a type or namespace name.
                // the default implementation fails.   
                //
-               public virtual FullNamedExpression ResolveAsTypeStep (IMemberContext rc,  bool silent)
+               public virtual TypeSpec ResolveAsType (IMemberContext mc)
                {
-                       if (!silent) {
-                               ResolveContext ec = new ResolveContext (rc);
-                               Expression e = Resolve (ec);
-                               if (e != null)
-                                       e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc);
-                       }
+                       ResolveContext ec = new ResolveContext (mc);
+                       Expression e = Resolve (ec);
+                       if (e != null)
+                               e.Error_UnexpectedKind (ec, ResolveFlags.Type, loc);
 
                        return null;
                }
 
-               //
-               // This is used to resolve the expression as a type, a null
-               // value will be returned if the expression is not a type
-               // reference
-               //
-               public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent)
-               {
-                       int errors = ec.Compiler.Report.Errors;
-
-                       FullNamedExpression fne = ResolveAsTypeStep (ec, silent);
-
-                       if (fne == null)
-                               return null;
-                               
-                       TypeExpr te = fne as TypeExpr;                          
-                       if (te == null) {
-                               if (!silent && errors == ec.Compiler.Report.Errors)
-                                       fne.Error_UnexpectedKind (ec.Compiler.Report, null, "type", loc);
-                               return null;
-                       }
-
-                       if (!te.CheckAccessLevel (ec)) {
-                               ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
-                               ErrorIsInaccesible (ec, te.Type.GetSignatureForError (), loc);
-                       }
-
-                       te.loc = loc;
-
-                       //
-                       // Obsolete checks cannot be done when resolving base context as they
-                       // require type dependecies to be set but we are just resolving them
-                       //
-                       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);
-                               }
-                       }
-
-                       return te;
-               }
-       
                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)
@@ -280,28 +236,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 = type.GetSignatureForErrorIncludingAssemblyName ();
+                               to_type = target.GetSignatureForErrorIncludingAssemblyName ();
+                       }
+
                        if (expl) {
                                ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
-                                       TypeManager.CSharpName (type), TypeManager.CSharpName (target));
+                                       from_type, to_type);
                                return;
                        }
 
@@ -310,20 +254,20 @@ 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 void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity)
+               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, MemberSpec member, int arity, Location loc)
                {
                        // Better message for possible generic expressions
                        if (member != null && (member.Kind & MemberKind.GenericMask) != 0) {
+                               var report = context.Module.Compiler.Report;
                                report.SymbolRelatedToPreviousError (member);
                                if (member is TypeSpec)
                                        member = ((TypeSpec) member).GetDefinition ();
@@ -339,13 +283,13 @@ namespace Mono.CSharp {
                                                name, member.GetSignatureForError ());
                                }
                        } else {
-                               Error_TypeArgumentsCannotBeUsed (report, ExprClassName, GetSignatureForError (), loc);
+                               Error_TypeArgumentsCannotBeUsed (context, ExprClassName, GetSignatureForError (), loc);
                        }
                }
 
-               public void Error_TypeArgumentsCannotBeUsed (Report report, string exprType, string name, Location loc)
+               public void Error_TypeArgumentsCannotBeUsed (IMemberContext context, string exprType, string name, Location loc)
                {
-                       report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+                       context.Module.Compiler.Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
                                exprType, name);
                }
 
@@ -427,7 +371,7 @@ namespace Mono.CSharp {
 
                                return e;
                        } catch (Exception ex) {
-                               if (loc.IsNull || Report.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled)
+                               if (loc.IsNull || ec.Module.Compiler.Settings.DebugFlags > 0 || ex is CompletionResult || ec.Report.IsDisabled)
                                        throw;
 
                                ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
@@ -454,7 +398,7 @@ namespace Mono.CSharp {
                public Expression ResolveLValue (ResolveContext ec, Expression right_side)
                {
                        int errors = ec.Report.Errors;
-                       bool out_access = right_side == EmptyExpression.OutAccess.Instance;
+                       bool out_access = right_side == EmptyExpression.OutAccess;
 
                        Expression e = DoResolveLValue (ec, right_side);
 
@@ -488,7 +432,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");
                }
 
@@ -553,7 +497,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) {
@@ -568,7 +512,15 @@ namespace Mono.CSharp {
                        }
 
                        var r = new OverloadResolver (ctors, OverloadResolver.Restrictions.NoBaseMembers, loc);
-                       return r.ResolveMember<MethodSpec> (rc, ref args);
+                       var ctor = r.ResolveMember<MethodSpec> (rc, ref args);
+                       if (ctor == null)
+                               return null;
+
+                       if ((ctor.Modifiers & Modifiers.PROTECTED) != 0 && !rc.HasSet (ResolveContext.Options.BaseInitializer)) {
+                               MemberExpr.CheckProtectedMemberAccess (rc, ctor, ctor.DeclaringType, loc);
+                       }
+
+                       return ctor;
                }
 
                [Flags]
@@ -584,7 +536,7 @@ namespace Mono.CSharp {
                // 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, MemberLookupRestrictions restrictions, Location loc)
+               public static Expression MemberLookup (IMemberContext rc, bool errorMode, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc)
                {
                        var members = MemberCache.FindMembers (queried_type, name, false);
                        if (members == null)
@@ -592,7 +544,6 @@ namespace Mono.CSharp {
 
                        MemberSpec non_method = null;
                        MemberSpec ambig_non_method = null;
-                       currentType = currentType ?? InternalType.FakeInternalType;
                        do {
                                for (int i = 0; i < members.Count; ++i) {
                                        var member = members[i];
@@ -604,8 +555,27 @@ namespace Mono.CSharp {
                                        if ((arity > 0 || (restrictions & MemberLookupRestrictions.ExactArity) != 0) && member.Arity != arity)
                                                continue;
 
-                                       if (rc != null && !member.IsAccessible (currentType))
-                                               continue;
+                                       if (!errorMode) {
+                                               if (!member.IsAccessible (rc))
+                                                       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.Module.Compiler.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
+                                                       continue;
+                                       }
 
                                        if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
                                                if (member is MethodSpec)
@@ -615,18 +585,19 @@ namespace Mono.CSharp {
                                                        continue;
                                        }
 
-                                       if (non_method == null || member is MethodSpec) {
+                                       if (non_method == null || member is MethodSpec || non_method.IsNotCSharpCompatible) {
                                                non_method = member;
-                                       } else if (currentType != null) {
+                                       } else if (!errorMode && !member.IsNotCSharpCompatible) {
                                                ambig_non_method = member;
                                        }
                                }
 
                                if (non_method != null) {
                                        if (ambig_non_method != null && rc != null) {
-                                               rc.Report.SymbolRelatedToPreviousError (non_method);
-                                               rc.Report.SymbolRelatedToPreviousError (ambig_non_method);
-                                               rc.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+                                               var report = rc.Module.Compiler.Report;
+                                               report.SymbolRelatedToPreviousError (non_method);
+                                               report.SymbolRelatedToPreviousError (ambig_non_method);
+                                               report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
                                                        non_method.GetSignatureForError (), ambig_non_method.GetSignatureForError ());
                                        }
 
@@ -669,7 +640,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);
                }
@@ -787,34 +758,6 @@ namespace Mono.CSharp {
                        Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
                }
 
-       
-               //
-               // Returns the size of type `t' if known, otherwise, 0
-               //
-               public static int GetTypeSize (TypeSpec t)
-               {
-                       if (t == TypeManager.int32_type ||
-                           t == TypeManager.uint32_type ||
-                           t == TypeManager.float_type)
-                               return 4;
-                       else if (t == TypeManager.int64_type ||
-                                t == TypeManager.uint64_type ||
-                                t == TypeManager.double_type)
-                               return 8;
-                       else if (t == TypeManager.byte_type ||
-                                t == TypeManager.sbyte_type ||
-                                t == TypeManager.bool_type)    
-                               return 1;
-                       else if (t == TypeManager.short_type ||
-                                t == TypeManager.char_type ||
-                                t == TypeManager.ushort_type)
-                               return 2;
-                       else if (t == TypeManager.decimal_type)
-                               return 16;
-                       else
-                               return 0;
-               }
-       
                protected void Error_CannotModifyIntermediateExpressionValue (ResolveContext ec)
                {
                        ec.Report.SymbolRelatedToPreviousError (type);
@@ -832,25 +775,27 @@ namespace Mono.CSharp {
                //
                protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source)
                {
-                       if (source.type == InternalType.Dynamic) {
+                       var btypes = ec.BuiltinTypes;
+
+                       if (source.type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (source));
-                               return new DynamicConversion (TypeManager.int32_type, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
+                               return new DynamicConversion (btypes.Int, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
                        }
 
                        Expression converted;
                        
                        using (ec.Set (ResolveContext.Options.CheckedScope)) {
-                               converted = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, source.loc);
+                               converted = Convert.ImplicitConversion (ec, source, btypes.Int, source.loc);
                                if (converted == null)
-                                       converted = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, source.loc);
+                                       converted = Convert.ImplicitConversion (ec, source, btypes.UInt, source.loc);
                                if (converted == null)
-                                       converted = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, source.loc);
+                                       converted = Convert.ImplicitConversion (ec, source, btypes.Long, source.loc);
                                if (converted == null)
-                                       converted = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, source.loc);
+                                       converted = Convert.ImplicitConversion (ec, source, btypes.ULong, source.loc);
 
                                if (converted == null) {
-                                       source.Error_ValueCannotBeConverted (ec, source.loc, TypeManager.int32_type, false);
+                                       source.Error_ValueCannotBeConverted (ec, source.loc, btypes.Int, false);
                                        return null;
                                }
                        }
@@ -863,10 +808,10 @@ namespace Mono.CSharp {
                                Error_NegativeArrayIndex (ec, source.loc);
 
                        // No conversion needed to array index
-                       if (converted.Type == TypeManager.int32_type)
+                       if (converted.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
                                return converted;
 
-                       return new ArrayIndexCast (converted).Resolve (ec);
+                       return new ArrayIndexCast (converted, btypes.Int).Resolve (ec);
                }
 
                //
@@ -924,16 +869,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 ();
+                       if (t == null)
+                               return null;
 
-                       return texpr;
+                       return new TypeExpression (t, loc);
                }
 
                //
@@ -1017,7 +957,7 @@ namespace Mono.CSharp {
                {
                        Arguments args = new Arguments (2);
                        args.Add (new Argument (child.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+                       args.Add (new Argument (new TypeOf (type, loc)));
 
                        if (type.IsPointer || child.Type.IsPointer)
                                Error_PointerInsideExpressionTree (ec);
@@ -1040,9 +980,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)
@@ -1086,113 +1030,50 @@ namespace Mono.CSharp {
        }
 
        //
-       // Used for predefined class library user casts (no obsolete check, etc.)
+       // Used for predefined type user operator (no obsolete check, etc.)
        //
-       public class OperatorCast : TypeCast {
-               MethodSpec conversion_operator;
-                       
-               public OperatorCast (Expression child, TypeSpec target_type) 
-                       : this (child, target_type, false)
-               {
-               }
-
-               public OperatorCast (Expression child, TypeSpec target_type, bool find_explicit)
-                       : base (child, target_type)
-               {
-                       conversion_operator = GetConversionOperator (find_explicit);
-                       if (conversion_operator == null)
-                               throw new InternalErrorException ("Outer conversion routine is out of sync");
-               }
+       public class OperatorCast : TypeCast
+       {
+               readonly MethodSpec conversion_operator;
 
-               // Returns the implicit operator that converts from
-               // 'child.Type' to our target type (type)
-               MethodSpec GetConversionOperator (bool find_explicit)
+               public OperatorCast (Expression expr, TypeSpec target_type)
+                       : this (expr, target_type, target_type, false)
                {
-                       var op = find_explicit ? Operator.OpType.Explicit : Operator.OpType.Implicit;
-
-                       var mi = MemberCache.GetUserOperator (child.Type, op, true);
-                       if (mi == null){
-                               mi = MemberCache.GetUserOperator (type, op, true);
-                       }
-                       
-                       foreach (MethodSpec oper in mi) {
-                               if (oper.ReturnType != type)
-                                       continue;
-
-                               if (oper.Parameters.Types [0] == child.Type)
-                                       return oper;
-                       }
-
-                       return null;
                }
-
-               public override void Emit (EmitContext ec)
-               {
-                       child.Emit (ec);
-                       ec.Emit (OpCodes.Call, conversion_operator);
-               }
-       }
-       
-       /// <summary>
-       ///     This is a numeric cast to a Decimal
-       /// </summary>
-       public class CastToDecimal : OperatorCast {
-               public CastToDecimal (Expression child)
-                       : this (child, false)
-               {
-               }
-
-               public CastToDecimal (Expression child, bool find_explicit)
-                       : base (child, TypeManager.decimal_type, find_explicit)
+               
+               public OperatorCast (Expression expr, TypeSpec target_type, bool find_explicit)
+                       : this (expr, target_type, target_type, find_explicit)
                {
                }
-       }
-
-       /// <summary>
-       ///     This is an explicit numeric cast from a Decimal
-       /// </summary>
-       public class CastFromDecimal : TypeCast
-       {
-               static Dictionary<TypeSpec, MethodSpec> operators;
-
-               public CastFromDecimal (Expression child, TypeSpec return_type)
-                       : base (child, return_type)
+               
+               public OperatorCast (Expression expr, TypeSpec declaringType, TypeSpec returnType, bool isExplicit)
+                       : base (expr, returnType)
                {
-                       if (child.Type != TypeManager.decimal_type)
-                               throw new ArgumentException ("Expected decimal child " + child.Type.GetSignatureForError ());
-               }
+                       var op = isExplicit ? Operator.OpType.Explicit : Operator.OpType.Implicit;
+                       var mi = MemberCache.GetUserOperator (declaringType, op, true);
 
-               // Returns the explicit operator that converts from an
-               // express of type System.Decimal to 'type'.
-               public Expression Resolve ()
-               {
-                       if (operators == null) {
-                               var all_oper = MemberCache.GetUserOperator (TypeManager.decimal_type, Operator.OpType.Explicit, true);
+                       if (mi != null) {
+                               foreach (MethodSpec oper in mi) {
+                                       if (oper.ReturnType != returnType)
+                                               continue;
 
-                               operators = new Dictionary<TypeSpec, MethodSpec> ();
-                               foreach (MethodSpec oper in all_oper) {
-                                       AParametersCollection pd = oper.Parameters;
-                                       if (pd.Types [0] == TypeManager.decimal_type)
-                                               operators.Add (oper.ReturnType, oper);
+                                       if (oper.Parameters.Types[0] == expr.Type) {
+                                               conversion_operator = oper;
+                                               return;
+                                       }
                                }
                        }
 
-                       return operators.ContainsKey (type) ? this : null;
+                       throw new InternalErrorException ("Missing predefined user operator between `{0}' and `{1}'",
+                               returnType.GetSignatureForError (), expr.Type.GetSignatureForError ());
                }
 
                public override void Emit (EmitContext ec)
                {
                        child.Emit (ec);
-
-                       ec.Emit (OpCodes.Call, operators [type]);
-               }
-
-               public static void Reset ()
-               {
-                       operators = null;
+                       ec.Emit (OpCodes.Call, conversion_operator);
                }
        }
-
        
        //
        // Constant specialization of EmptyCast.
@@ -1201,7 +1082,7 @@ namespace Mono.CSharp {
        //
        public class EmptyConstantCast : Constant
        {
-               public Constant child;
+               public readonly Constant child;
 
                public EmptyConstantCast (Constant child, TypeSpec type)
                        : base (child.Location)
@@ -1214,16 +1095,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)
@@ -1237,7 +1108,7 @@ namespace Mono.CSharp {
                {
                        Arguments args = Arguments.CreateForExpressionTree (ec, null,
                                child.CreateExpressionTree (ec),
-                               new TypeOf (new TypeExpression (type, loc), loc));
+                               new TypeOf (type, loc));
 
                        if (type.IsPointer)
                                Error_PointerInsideExpressionTree (ec);
@@ -1265,11 +1136,6 @@ namespace Mono.CSharp {
                        get { return child.IsZeroInteger; }
                }
 
-               protected override Expression DoResolve (ResolveContext rc)
-               {
-                       return this;
-               }
-               
                public override void Emit (EmitContext ec)
                {
                        child.Emit (ec);                        
@@ -1289,12 +1155,31 @@ namespace Mono.CSharp {
                        child.EmitSideEffect (ec);
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
+               public override object GetValue ()
+               {
+                       return child.GetValue ();
+               }
+
+               public override string GetValueAsLiteral ()
+               {
+                       return child.GetValueAsLiteral ();
+               }
+
+               public override long GetValueAsLong ()
+               {
+                       return child.GetValueAsLong ();
+               }
+
+               public override Constant ConvertImplicitly (TypeSpec target_type)
                {
+                       if (type == target_type)
+                               return this;
+
                        // FIXME: Do we need to check user conversions?
                        if (!Convert.ImplicitStandardConversionExists (this, target_type))
                                return null;
-                       return child.ConvertImplicitly (rc, target_type);
+
+                       return child.ConvertImplicitly (target_type);
                }
        }
 
@@ -1309,6 +1194,8 @@ namespace Mono.CSharp {
                        : base (child.Location)
                {
                        this.Child = child;
+
+                       this.eclass = ExprClass.Value;
                        this.type = enum_type;
                }
 
@@ -1317,13 +1204,6 @@ namespace Mono.CSharp {
                {
                }
 
-               protected override Expression DoResolve (ResolveContext rc)
-               {
-                       Child = Child.Resolve (rc);
-                       this.eclass = ExprClass.Value;
-                       return this;
-               }
-
                public override void Emit (EmitContext ec)
                {
                        Child.Emit (ec);
@@ -1354,31 +1234,28 @@ 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 ();
+                       return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ());
+               }
 #endif
 
-                       return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ());
+               public override string GetValueAsLiteral ()
+               {
+                       return Child.GetValueAsLiteral ();
                }
-               
-               public override string AsString ()
+
+               public override long GetValueAsLong ()
                {
-                       return Child.AsString ();
+                       return Child.GetValueAsLong ();
                }
 
                public EnumConstant Increment()
@@ -1410,7 +1287,7 @@ namespace Mono.CSharp {
                        return Child.ConvertExplicitly (in_checked_context, target_type);
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
+               public override Constant ConvertImplicitly (TypeSpec type)
                {
                        if (this.type == type) {
                                return this;
@@ -1420,7 +1297,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       return Child.ConvertImplicitly (rc, type);
+                       return Child.ConvertImplicitly (type);
                }
        }
 
@@ -1448,6 +1325,12 @@ namespace Mono.CSharp {
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
+                       // Only boxing to object type is supported
+                       if (targetType.BuiltinType != BuiltinTypeSpec.Type.Object) {
+                               base.EncodeAttributeValue (rc, enc, targetType);
+                               return;
+                       }
+
                        enc.Encode (child.Type);
                        child.EncodeAttributeValue (rc, enc, child.Type);
                }
@@ -1463,8 +1346,8 @@ namespace Mono.CSharp {
                {
                        // boxing is side-effectful, since it involves runtime checks, except when boxing to Object or ValueType
                        // so, we need to emit the box+pop instructions in most cases
-                       if (TypeManager.IsStruct (child.Type) &&
-                           (type == TypeManager.object_type || type == TypeManager.value_type))
+                       if (child.Type.IsStruct &&
+                           (type.BuiltinType == BuiltinTypeSpec.Type.Object || type.BuiltinType == BuiltinTypeSpec.Type.ValueType))
                                child.EmitSideEffect (ec);
                        else
                                base.EmitSideEffect (ec);
@@ -1485,13 +1368,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);
@@ -1826,9 +1702,9 @@ namespace Mono.CSharp {
                                this.orig_expr = orig_expr;
                        }
 
-                       public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
+                       public override Constant ConvertImplicitly (TypeSpec target_type)
                        {
-                               Constant c = base.ConvertImplicitly (rc, target_type);
+                               Constant c = base.ConvertImplicitly (target_type);
                                if (c != null)
                                        c = new ReducedConstantExpression (c, orig_expr);
 
@@ -1858,6 +1734,9 @@ namespace Mono.CSharp {
                        {
                                this.orig_expr = orig;
                                this.stm = stm;
+                               this.eclass = stm.eclass;
+                               this.type = stm.Type;
+
                                this.loc = orig.Location;
                        }
 
@@ -1868,8 +1747,6 @@ namespace Mono.CSharp {
 
                        protected override Expression DoResolve (ResolveContext ec)
                        {
-                               eclass = stm.eclass;
-                               type = stm.Type;
                                return this;
                        }
 
@@ -1921,15 +1798,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)
@@ -1972,7 +1857,7 @@ namespace Mono.CSharp {
        //
        public abstract class CompositeExpression : Expression
        {
-               Expression expr;
+               protected Expression expr;
 
                protected CompositeExpression (Expression expr)
                {
@@ -1980,18 +1865,18 @@ namespace Mono.CSharp {
                        this.loc = expr.Location;
                }
 
-               public override Expression CreateExpressionTree (ResolveContext ec)
+               public override Expression CreateExpressionTree (ResolveContext rc)
                {
-                       return expr.CreateExpressionTree (ec);
+                       return expr.CreateExpressionTree (rc);
                }
 
                public Expression Child {
                        get { return expr; }
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext rc)
                {
-                       expr = expr.Resolve (ec);
+                       expr = expr.Resolve (rc);
                        if (expr != null) {
                                type = expr.Type;
                                eclass = expr.eclass;
@@ -2022,6 +1907,12 @@ namespace Mono.CSharp {
                        this.expr = expr;
                }
 
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        if (expr == null)
@@ -2041,9 +1932,6 @@ namespace Mono.CSharp {
                        throw new InternalErrorException ("Missing Resolve call");
                }
 
-               public Expression Expr {
-                       get { return expr; }
-               }
        }
 
        //
@@ -2172,77 +2060,57 @@ namespace Mono.CSharp {
                        return new SimpleName (Name, targs, loc);
                }
 
-               protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
+               {
+                       return SimpleNameResolve (ec, null, false);
+               }
+
+               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+               {
+                       return SimpleNameResolve (ec, right_side, false);
+               }
+
+               protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ctx)
                {
-                       if (ec.CurrentType != null) {
-                               if (ec.CurrentMemberDefinition != null) {
-                                       MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
+                       if (ctx.CurrentType != null) {
+                               if (ctx.CurrentMemberDefinition != null) {
+                                       MemberCore mc = ctx.CurrentMemberDefinition.Parent.GetDefinition (Name);
                                        if (mc != null) {
-                                               Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+                                               Error_UnexpectedKind (ctx.Module.Compiler.Report, mc, "type", GetMemberType (mc), loc);
                                                return;
                                        }
                                }
-
-                               /*
-                                                               // TODO MemberCache: Implement
-                                                               string ns = ec.CurrentType.Namespace;
-                                                               string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
-                                                               foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                                                                       var type = a.GetType (fullname);
-                                                                       if (type != null) {
-                                                                               ec.Compiler.Report.SymbolRelatedToPreviousError (type);
-                                                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
-                                                                               return;
-                                                                       }
-                                                               }
-
-                                                               if (ec.CurrentTypeDefinition != null) {
-                                                                       TypeSpec t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
-                                                                       if (t != null) {
-                                                                               Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
-                                                                               return;
-                                                                       }
-                                                               }
-                               */
                        }
 
-                       FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
+                       // MSAF
+                       var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
                        if (retval != null) {
-                               Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc, retval.Type, Arity);
-/*
-                               var te = retval as TypeExpr;
-                               if (HasTypeArguments && te != null && !te.Type.IsGeneric)
-                                       retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
-                               else
-                                       Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, retval.Type, loc);
-*/
+                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type);
+                               ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
                                return;
                        }
 
-                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
-               }
-
-               protected override Expression DoResolve (ResolveContext ec)
-               {
-                       return SimpleNameResolve (ec, null, false);
-               }
+                       retval = ctx.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
+                       if (retval != null) {
+                               Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, Arity, loc);
+                               return;
+                       }
 
-               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
-               {
-                       return SimpleNameResolve (ec, right_side, false);
+                       NamespaceContainer.Error_NamespaceNotFound (loc, Name, ctx.Module.Compiler.Report);
                }
 
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
                {
-                       int errors = ec.Compiler.Report.Errors;
-                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
+                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, LookupMode.Normal, loc);
 
                        if (fne != null) {
                                if (fne.Type != null && Arity > 0) {
                                        if (HasTypeArguments) {
                                                GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
-                                               return ct.ResolveAsTypeStep (ec, false);
+                                               if (ct.ResolveAsType (ec) == null)
+                                                       return null;
+
+                                               return ct;
                                        }
 
                                        return new GenericOpenTypeExpr (fne.Type, loc);
@@ -2255,26 +2123,29 @@ namespace Mono.CSharp {
                                        return fne;
                        }
 
-                       if (Arity == 0 && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3) {
-                               if (!ec.Compiler.PredefinedAttributes.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?",
-                                               ec.Compiler.PredefinedAttributes.Dynamic.GetSignatureForError ());
+                                               ec.Module.PredefinedAttributes.Dynamic.GetSignatureForError ());
                                }
 
-                               return new DynamicTypeExpr (loc);
+                               fne = new DynamicTypeExpr (loc);
+                               fne.ResolveAsType (ec);
                        }
 
                        if (fne != null)
                                return fne;
 
-                       if (silent || errors != ec.Compiler.Report.Errors)
-                               return null;
-
                        Error_TypeOrNamespaceNotFound (ec);
                        return null;
                }
 
+               public bool IsPossibleTypeOrNamespace (IMemberContext mc)
+               {
+                       return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) != null;
+               }
+
                public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        int lookup_arity = Arity;
@@ -2301,7 +2172,7 @@ namespace Mono.CSharp {
                                                        e = variable.CreateReferenceExpression (rc, loc);
                                                        if (e != null) {
                                                                if (Arity > 0)
-                                                                       Error_TypeArgumentsCannotBeUsed (rc.Report, "variable", Name, loc);
+                                                                       Error_TypeArgumentsCannotBeUsed (rc, "variable", Name, loc);
 
                                                                return e;
                                                        }
@@ -2313,9 +2184,8 @@ namespace Mono.CSharp {
                                // Stage 2: Lookup members if we are inside a type up to top level type for nested types
                                //
                                TypeSpec member_type = rc.CurrentType;
-                               TypeSpec current_type = member_type;
                                for (; member_type != null; member_type = member_type.DeclaringType) {
-                                       e = MemberLookup (errorMode ? null : rc, current_type, member_type, Name, lookup_arity, restrictions, loc);
+                                       e = MemberLookup (rc, errorMode, member_type, Name, lookup_arity, restrictions, loc);
                                        if (e == null)
                                                continue;
 
@@ -2358,12 +2228,12 @@ namespace Mono.CSharp {
 
                                                        // Break as there is no other overload available anyway
                                                        if ((restrictions & MemberLookupRestrictions.ReadAccess) != 0) {
-                                                               if (!pe.PropertyInfo.HasGet || !pe.PropertyInfo.Get.IsAccessible (current_type))
+                                                               if (!pe.PropertyInfo.HasGet || !pe.PropertyInfo.Get.IsAccessible (rc))
                                                                        break;
 
                                                                pe.Getter = pe.PropertyInfo.Get;
                                                        } else {
-                                                               if (!pe.PropertyInfo.HasSet || !pe.PropertyInfo.Set.IsAccessible (current_type))
+                                                               if (!pe.PropertyInfo.HasSet || !pe.PropertyInfo.Set.IsAccessible (rc))
                                                                        break;
 
                                                                pe.Setter = pe.PropertyInfo.Set;
@@ -2387,14 +2257,13 @@ namespace Mono.CSharp {
                                // Stage 3: Lookup nested types, namespaces and type parameters in the context
                                //
                                if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
-                                       e = ResolveAsTypeStep (rc, lookup_arity == 0 || !errorMode);
-                                       if (e != null) {
+                                       if (IsPossibleTypeOrNamespace (rc)) {
                                                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;
+                                               return ResolveAsTypeOrNamespace (rc);
                                        }
                                }
 
@@ -2402,20 +2271,62 @@ namespace Mono.CSharp {
                                        if (variable_found) {
                                                rc.Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", Name);
                                        } else {
+                                               if (Arity > 0) {
+                                                       TypeParameter[] tparams = rc.CurrentTypeParameters;
+                                                       if (tparams != null) {
+                                                               foreach (var ctp in tparams) {
+                                                                       if (ctp.Name == Name) {
+                                                                               Error_TypeArgumentsCannotBeUsed (rc, "type parameter", Name, loc);
+                                                                               return null;
+                                                                       }
+                                                               }
+                                                       }
+
+                                                       var ct = rc.CurrentType;
+                                                       do {
+                                                               if (ct.MemberDefinition.TypeParametersCount > 0) {
+                                                                       foreach (var ctp in ct.MemberDefinition.TypeParameters) {
+                                                                               if (ctp.Name == Name) {
+                                                                                       Error_TypeArgumentsCannotBeUsed (rc, "type parameter", Name, loc);
+                                                                                       return null;
+                                                                               }
+                                                                       }
+                                                               }
+
+                                                               ct = ct.DeclaringType;
+                                                       } while (ct != null);
+                                               }
+
+                                               if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0) {
+                                                       e = rc.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
+                                                       if (e != null) {
+                                                               rc.Report.SymbolRelatedToPreviousError (e.Type);
+                                                               ErrorIsInaccesible (rc, e.GetSignatureForError (), loc);
+                                                               return e;
+                                                       }
+                                               }
+
+                                               e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
+                                               if (e != null) {
+                                                       if (!(e is TypeExpr) || (restrictions & MemberLookupRestrictions.InvocableOnly) == 0 || !e.Type.IsDelegate) {
+                                                               Error_TypeArgumentsCannotBeUsed (rc, e.Type, Arity, loc);
+                                                               return e;
+                                                       }
+                                               }
+
                                                rc.Report.Error (103, loc, "The name `{0}' does not exist in the current context", Name);
                                        }
 
-                                       return null;
+                                       return ErrorExpression.Instance;
                                }
 
-                               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;
-                               restrictions &= ~MemberLookupRestrictions.InvocableOnly;
                                errorMode = true;
                        }
                }
@@ -2460,11 +2371,50 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+               public abstract FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc);
+
+               //
+               // This is used to resolve the expression as a type, a null
+               // value will be returned if the expression is not a type
+               // reference
+               //
+               public override TypeSpec ResolveAsType (IMemberContext mc)
                {
-                       return this;
+                       FullNamedExpression fne = ResolveAsTypeOrNamespace (mc);
+
+                       if (fne == null)
+                               return null;
+
+                       TypeExpr te = fne as TypeExpr;
+                       if (te == null) {
+                               fne.Error_UnexpectedKind (mc.Module.Compiler.Report, null, "type", loc);
+                               return null;
+                       }
+
+                       te.loc = loc;
+
+                       type = te.Type;
+
+                       var dep = type.GetMissingDependencies ();
+                       if (dep != null) {
+                               ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc);
+                       }
+
+                       //
+                       // Obsolete checks cannot be done when resolving base context as they
+                       // require type dependencies to be set but we are in process of resolving them
+                       //
+                       if (!(mc is TypeContainer.BaseContext)) {
+                               ObsoleteAttribute obsolete_attr = type.GetAttributeObsolete ();
+                               if (obsolete_attr != null && !mc.IsObsolete) {
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, mc.Module.Compiler.Report);
+                               }
+                       }
+
+                       return type;
                }
 
+
                public override void Emit (EmitContext ec)
                {
                        throw new InternalErrorException ("FullNamedExpression `{0}' found in resolved tree",
@@ -2475,33 +2425,20 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Expression that evaluates to a type
        /// </summary>
-       public abstract class TypeExpr : FullNamedExpression {
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
-               {
-                       TypeExpr t = DoResolveAsTypeStep (ec);
-                       if (t == null)
-                               return null;
-
-                       eclass = ExprClass.Type;
-                       return t;
-               }
-
-               protected override Expression DoResolve (ResolveContext ec)
+       public abstract class TypeExpr : FullNamedExpression
+       {
+               public sealed override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
                {
-                       return ResolveAsTypeTerminal (ec, false);
+                       ResolveAsType (mc);
+                       return this;
                }
 
-               public virtual bool CheckAccessLevel (IMemberContext mc)
+               protected sealed override Expression DoResolve (ResolveContext ec)
                {
-                       DeclSpace c = mc.CurrentMemberDefinition as DeclSpace;
-                       if (c == null)
-                               c = mc.CurrentMemberDefinition.Parent;
-
-                       return c.CheckAccessLevel (Type);
+                       ResolveAsType (ec);
+                       return this;
                }
 
-               protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec);
-
                public override bool Equals (object obj)
                {
                        TypeExpr tobj = obj as TypeExpr;
@@ -2520,7 +2457,8 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Fully resolved Expression that already evaluated to a type
        /// </summary>
-       public class TypeExpression : TypeExpr {
+       public class TypeExpression : TypeExpr
+       {
                public TypeExpression (TypeSpec t, Location l)
                {
                        Type = t;
@@ -2528,14 +2466,9 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
+               public sealed override TypeSpec ResolveAsType (IMemberContext ec)
                {
-                       return this;
-               }
-
-               public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
-               {
-                       return this;
+                       return type;
                }
        }
 
@@ -2579,7 +2512,6 @@ namespace Mono.CSharp {
                        get;
                }
 
-               // TODO: Not needed
                protected abstract TypeSpec DeclaringType {
                        get;
                }
@@ -2599,7 +2531,7 @@ namespace Mono.CSharp {
                        // Overload resulution works on virtual or non-virtual members only (no overrides). That
                        // means for base.member access we have to find the closest match after we found best candidate
                        //
-                       if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.STATIC)) != Modifiers.STATIC) {
+                       if ((method.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
                                //
                                // The method could already be what we are looking for
                                //
@@ -2631,11 +2563,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);
                        }
 
                        //
@@ -2653,18 +2585,26 @@ namespace Mono.CSharp {
                        if (InstanceExpression == null)
                                return;
 
-                       if ((member.Modifiers & Modifiers.AccessibilityMask) == Modifiers.PROTECTED && !(InstanceExpression is This)) {
-                               var ct = rc.CurrentType;
-                               var expr_type = InstanceExpression.Type;
-                               if (ct != expr_type) {
-                                       expr_type = expr_type.GetDefinition ();
-                                       if (ct != expr_type && !IsSameOrBaseQualifier (ct, expr_type)) {
-                                               rc.Report.SymbolRelatedToPreviousError (member);
-                                               rc.Report.Error (1540, loc,
-                                                       "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it",
-                                                       member.GetSignatureForError (), expr_type.GetSignatureForError (), ct.GetSignatureForError ());
-                                       }
-                               }
+                       if ((member.Modifiers & Modifiers.PROTECTED) != 0 && !(InstanceExpression is This)) {
+                               CheckProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+                       }
+               }
+
+               public static void CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier, Location loc) where T : MemberSpec
+               {
+                       var ct = rc.CurrentType;
+                       if (ct == qualifier)
+                               return;
+
+                       if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly))
+                               return;
+
+                       qualifier = qualifier.GetDefinition ();
+                       if (ct != qualifier && !IsSameOrBaseQualifier (ct, qualifier)) {
+                               rc.Report.SymbolRelatedToPreviousError (member);
+                               rc.Report.Error (1540, loc,
+                                       "Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it",
+                                       member.GetSignatureForError (), qualifier.GetSignatureForError (), ct.GetSignatureForError ());
                        }
                }
 
@@ -2693,6 +2633,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)
@@ -2721,9 +2666,7 @@ namespace Mono.CSharp {
                        // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name
 
                        if (left is MemberExpr || left is VariableReference) {
-                               rc.Report.DisableReporting ();
-                               Expression identical_type = rc.LookupNamespaceOrType (name.Name, 0, loc, true) as TypeExpr;
-                               rc.Report.EnableReporting ();
+                               var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr;
                                if (identical_type != null && identical_type.Type == left.Type)
                                        return identical_type;
                        }
@@ -2731,15 +2674,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) {
@@ -2775,21 +2723,52 @@ 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 ()) {
+                               if (fe != null && fe.IsMarshalByRefAccess (rc)) {
                                        rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
                                        rc.Report.Warning (1690, 1, loc,
                                                "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
                                                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;
@@ -2797,7 +2776,7 @@ namespace Mono.CSharp {
 
                public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
                {
-                       if (left != null && left.IsNull && TypeManager.IsReferenceType (left.Type)) {
+                       if (left != null && left.IsNull && TypeSpec.IsReferenceType (left.Type)) {
                                ec.Report.Warning (1720, 1, left.Location,
                                        "Expression will always cause a `{0}'", "System.NullReferenceException");
                        }
@@ -2809,9 +2788,9 @@ namespace Mono.CSharp {
                protected void EmitInstance (EmitContext ec, bool prepare_for_load)
                {
                        TypeSpec instance_type = InstanceExpression.Type;
-                       if (TypeManager.IsValueType (instance_type)) {
+                       if (TypeSpec.IsValueType (instance_type)) {
                                if (InstanceExpression is IMemoryLocation) {
-                                       ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore);
+                                       ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.Load);
                                } else {
                                        LocalTemporary t = new LocalTemporary (instance_type);
                                        InstanceExpression.Emit (ec);
@@ -2822,7 +2801,7 @@ namespace Mono.CSharp {
                                InstanceExpression.Emit (ec);
 
                                // Only to make verifier happy
-                               if (instance_type.IsGenericParameter && !(InstanceExpression is This) && TypeManager.IsReferenceType (instance_type))
+                               if (instance_type.IsGenericParameter && !(InstanceExpression is This) && TypeSpec.IsReferenceType (instance_type))
                                        ec.Emit (OpCodes.Box, instance_type);
                        }
 
@@ -2838,10 +2817,10 @@ namespace Mono.CSharp {
        // 
        class ExtensionMethodGroupExpr : MethodGroupExpr, OverloadResolver.IErrorHandler
        {
-               NamespaceEntry namespace_entry;
+               NamespaceContainer namespace_entry;
                public readonly Expression ExtensionExpression;
 
-               public ExtensionMethodGroupExpr (IList<MethodSpec> list, NamespaceEntry n, Expression extensionExpr, Location l)
+               public ExtensionMethodGroupExpr (IList<MethodSpec> list, NamespaceContainer n, Expression extensionExpr, Location l)
                        : base (list.Cast<MemberSpec>().ToList (), extensionExpr.Type, l)
                {
                        this.namespace_entry = n;
@@ -2892,7 +2871,7 @@ namespace Mono.CSharp {
 
                        var me = ExtensionExpression as MemberExpr;
                        if (me != null)
-                               me.ResolveInstanceExpression (ec);
+                               me.ResolveInstanceExpression (ec, null);
 
                        InstanceExpression = null;
                        return this;
@@ -2977,6 +2956,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public IList<MemberSpec> Candidates {
+                       get {
+                               return Methods;
+                       }
+               }
+
                protected override TypeSpec DeclaringType {
                        get {
                                return queried_type;
@@ -3042,7 +3027,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (best_candidate.IsConditionallyExcluded (loc))
+                       if (best_candidate.IsConditionallyExcluded (ec.Module.Compiler, loc))
                                ec.Report.Error (765, loc,
                                        "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
                        
@@ -3125,7 +3110,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;
@@ -3138,7 +3123,7 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               ResolveInstanceExpression (ec);
+                               ResolveInstanceExpression (ec, null);
                                if (InstanceExpression != null)
                                        CheckProtectedMemberAccess (ec, best_candidate);
                        }
@@ -3194,7 +3179,7 @@ namespace Mono.CSharp {
                                return null;
 
                        int arity = type_arguments == null ? 0 : type_arguments.Count;
-                       NamespaceEntry methods_scope = null;
+                       NamespaceContainer methods_scope = null;
                        var methods = rc.LookupExtensionMethod (InstanceExpression.Type, Methods[0].Name, arity, ref methods_scope);
                        if (methods == null)
                                return null;
@@ -3374,23 +3359,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.IsExpressionTreeType || q.IsExpressionTreeType) {
+                                       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.Kind == MemberKind.Void) {
+                                       return q.Kind != MemberKind.Void ? 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.Kind == MemberKind.Void) {
+                                       return p.Kind != MemberKind.Void ? 1: 0;
+                               }
                        } else {
                                if (argument_type == p)
                                        return 1;
@@ -3410,44 +3423,70 @@ namespace Mono.CSharp {
                        if (p == null || q == null)
                                throw new InternalErrorException ("BetterTypeConversion got a null conversion");
 
-                       if (p == TypeManager.int32_type) {
-                               if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+                       switch (p.BuiltinType) {
+                       case BuiltinTypeSpec.Type.Int:
+                               if (q.BuiltinType == BuiltinTypeSpec.Type.UInt || q.BuiltinType == BuiltinTypeSpec.Type.ULong)
                                        return 1;
-                       } else if (p == TypeManager.int64_type) {
-                               if (q == TypeManager.uint64_type)
+                               break;
+                       case BuiltinTypeSpec.Type.Long:
+                               if (q.BuiltinType == BuiltinTypeSpec.Type.ULong)
                                        return 1;
-                       } else if (p == TypeManager.sbyte_type) {
-                               if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
-                                       q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+                               break;
+                       case BuiltinTypeSpec.Type.SByte:
+                               switch (q.BuiltinType) {
+                               case BuiltinTypeSpec.Type.Byte:
+                               case BuiltinTypeSpec.Type.UShort:
+                               case BuiltinTypeSpec.Type.UInt:
+                               case BuiltinTypeSpec.Type.ULong:
                                        return 1;
-                       } else if (p == TypeManager.short_type) {
-                               if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
-                                       q == TypeManager.uint64_type)
+                               }
+                               break;
+                       case BuiltinTypeSpec.Type.Short:
+                               switch (q.BuiltinType) {
+                               case BuiltinTypeSpec.Type.UShort:
+                               case BuiltinTypeSpec.Type.UInt:
+                               case BuiltinTypeSpec.Type.ULong:
                                        return 1;
-                       } else if (p == InternalType.Dynamic) {
+                               }
+                               break;
+                       case BuiltinTypeSpec.Type.Dynamic:
                                // Dynamic is never better
                                return 2;
                        }
 
-                       if (q == TypeManager.int32_type) {
-                               if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+                       switch (q.BuiltinType) {
+                       case BuiltinTypeSpec.Type.Int:
+                               if (p.BuiltinType == BuiltinTypeSpec.Type.UInt || p.BuiltinType == BuiltinTypeSpec.Type.ULong)
                                        return 2;
-                       } if (q == TypeManager.int64_type) {
-                               if (p == TypeManager.uint64_type)
+                               break;
+                       case BuiltinTypeSpec.Type.Long:
+                               if (p.BuiltinType == BuiltinTypeSpec.Type.ULong)
                                        return 2;
-                       } else if (q == TypeManager.sbyte_type) {
-                               if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
-                                       p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+                               break;
+                       case BuiltinTypeSpec.Type.SByte:
+                               switch (p.BuiltinType) {
+                               case BuiltinTypeSpec.Type.Byte:
+                               case BuiltinTypeSpec.Type.UShort:
+                               case BuiltinTypeSpec.Type.UInt:
+                               case BuiltinTypeSpec.Type.ULong:
                                        return 2;
-                       } if (q == TypeManager.short_type) {
-                               if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
-                                       p == TypeManager.uint64_type)
+                               }
+                               break;
+                       case BuiltinTypeSpec.Type.Short:
+                               switch (p.BuiltinType) {
+                               case BuiltinTypeSpec.Type.UShort:
+                               case BuiltinTypeSpec.Type.UInt:
+                               case BuiltinTypeSpec.Type.ULong:
                                        return 2;
-                       } else if (q == InternalType.Dynamic) {
+                               }
+                               break;
+                       case BuiltinTypeSpec.Type.Dynamic:
                                // 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);
@@ -3483,9 +3522,10 @@ 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)
@@ -3550,7 +3590,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;
 
                        //
@@ -3611,7 +3651,7 @@ 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) {
+                       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)];
@@ -3633,9 +3673,6 @@ namespace Mono.CSharp {
                        if (specific_at_least_once)
                                return true;
 
-                       // FIXME: handle lifted operators
-                       // ...
-
                        return false;
                }
 
@@ -3657,7 +3694,12 @@ namespace Mono.CSharp {
                //
                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)
                {
+                       // 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;
@@ -3671,21 +3713,19 @@ 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;
@@ -3734,7 +3774,7 @@ namespace Mono.CSharp {
                                                        Argument temp;
                                                        if (index >= param_count) {
                                                                // When using parameters which should not be available to the user
-                                                               if ((pd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
+                                                               if ((cpd.FixedParameters[index].ModFlags & Parameter.Modifier.PARAMS) == 0)
                                                                        break;
 
                                                                arguments.Add (null);
@@ -3770,6 +3810,7 @@ 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
@@ -3780,7 +3821,7 @@ namespace Mono.CSharp {
                                        if (g_args_count != type_arguments.Count)
                                                return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count);
 
-                                       ms = ms.MakeGenericMethod (type_arguments.Arguments);
+                                       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
@@ -3797,7 +3838,7 @@ namespace Mono.CSharp {
                                                return ti.InferenceScore - 20000;
 
                                        if (i_args.Length != 0) {
-                                               ms = ms.MakeGenericMethod (i_args);
+                                               ms = ms.MakeGenericMethod (ec, i_args);
                                        }
 
                                        cc.IgnoreInferredDynamic = true;
@@ -3820,17 +3861,19 @@ namespace Mono.CSharp {
                                //
                                if (candidate != pm) {
                                        MethodSpec override_ms = (MethodSpec) pm;
-                                       var inflator = new TypeParameterInflator (ms.DeclaringType, override_ms.GenericDefinition.TypeParameters, ms.TypeArguments);
+                                       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;
                        }
 
                        //
@@ -3838,7 +3881,6 @@ namespace Mono.CSharp {
                        //
                        Parameter.Modifier p_mod = 0;
                        TypeSpec pt = null;
-                       TypeSpec[] ptypes = ((IParametersMember) candidate).Parameters.Types;
 
                        for (int i = 0; i < arg_count; i++) {
                                Argument a = arguments[i];
@@ -3857,7 +3899,7 @@ namespace Mono.CSharp {
                                                //
                                                // 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) {
+                                               if (e == EmptyExpression.MissingValue && ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Object || ptypes[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
                                                        e = new MemberAccess (new MemberAccess (new MemberAccess (
                                                                new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc);
                                                } else {
@@ -3872,7 +3914,7 @@ namespace Mono.CSharp {
                                }
 
                                if (p_mod != Parameter.Modifier.PARAMS) {
-                                       p_mod = pd.FixedParameters[i].ModFlags;
+                                       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;
@@ -3889,8 +3931,8 @@ namespace Mono.CSharp {
                                                //
                                                var at = a.Type;
                                                if (at == pt || TypeSpecComparer.IsEqual (at, pt) ||
-                                                       Convert.ImplicitReferenceConversionExists (a.Expr, pt) ||
-                                                       Convert.ImplicitBoxingConversion (EmptyExpression.Null, at, pt) != null) {
+                                                       Convert.ImplicitReferenceConversionExists (at, pt) ||
+                                                       Convert.ImplicitBoxingConversion (null, at, pt) != null) {
                                                        score = 0;
                                                        continue;
                                                }
@@ -3930,7 +3972,7 @@ namespace Mono.CSharp {
                        //
                        // When params parameter has no argument it will be provided later if the method is the best candidate
                        //
-                       if (arg_count + 1 == pd.Count && (pd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
+                       if (arg_count + 1 == pd.Count && (cpd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
                                params_expanded_form = true;
 
                        //
@@ -3965,7 +4007,7 @@ namespace Mono.CSharp {
                                                //
                                                // Using dynamic for ref/out parameter can still succeed at runtime
                                                //
-                                               if (argument.Type == InternalType.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
+                                               if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
                                                        return -1;
 
                                                return 2;
@@ -3976,20 +4018,20 @@ namespace Mono.CSharp {
                                        //
                                        // Using dynamic for ref/out parameter can still succeed at runtime
                                        //
-                                       if (argument.Type == InternalType.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
+                                       if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
                                                return -1;
 
                                        return 1;
                                }
 
                        } else {
-                               if (argument.Type == InternalType.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0)
+                               if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.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
-                               // candidate found, this set is used to report more details about what was wrong
+                               // candidate was found, this set is used to report more details about what was wrong
                                // with lambda body
                                //
                                if (argument.Expr.Type == InternalType.AnonymousMethod) {
@@ -3999,6 +4041,10 @@ namespace Mono.CSharp {
                                        }
                                }
 
+                               //
+                               // Use implicit conversion in all modes to return same candidates when the expression
+                               // is used as argument or delegate conversion
+                               //
                                if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
                                        if (lambda_conv_msgs != null) {
                                                lambda_conv_msgs.EndSession ();
@@ -4068,7 +4114,6 @@ namespace Mono.CSharp {
 
                        Arguments candidate_args = args;
                        bool error_mode = false;
-                       var current_type = rc.CurrentType;
                        MemberSpec invocable_member = null;
 
                        // Be careful, cannot return until error reporter is restored
@@ -4090,8 +4135,13 @@ namespace Mono.CSharp {
                                                        if ((member.Modifiers & Modifiers.OVERRIDE) != 0)
                                                                continue;
 
-                                                       if (!member.IsAccessible (current_type) && !error_mode)
-                                                               continue;
+                                                       if (!error_mode) {
+                                                               if (!member.IsAccessible (rc))
+                                                                       continue;
+
+                                                               if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
+                                                                       continue;
+                                                       }
 
                                                        IParametersMember pm = member as IParametersMember;
                                                        if (pm == null) {
@@ -4145,8 +4195,39 @@ namespace Mono.CSharp {
                                                                                continue;
                                                                }
 
-                                                               // Is the new candidate better
-                                                               if (BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params)) {
+                                                               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;
@@ -4222,6 +4303,13 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       //
+                       // These flags indicates we are running delegate probing conversion. No need to
+                       // do more expensive checks
+                       // 
+                       if ((restrictions & (Restrictions.ProbingOnly | Restrictions.CovariantDelegate)) == (Restrictions.CovariantDelegate | Restrictions.ProbingOnly))
+                               return (T) best_candidate;
+
                        if (ambiguous_candidates != null) {
                                //
                                // Now check that there are no ambiguities i.e the selected method
@@ -4230,7 +4318,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_parameter_member.Parameters, best_candidate_params, candidate.Member, candidate.Parameters, 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);
@@ -4270,6 +4358,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;
@@ -4316,14 +4409,13 @@ namespace Mono.CSharp {
                                else
                                        ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (mod));
-                       } else {
+                       } else if (a.Expr != ErrorExpression.Instance) {
                                string p1 = a.GetSignatureForError ();
                                string p2 = TypeManager.CSharpName (paramType);
 
                                if (p1 == p2) {
-                                       ec.Report.ExtraInformation (loc, "(equally named types possibly from different assemblies in previous ");
-                                       ec.Report.SymbolRelatedToPreviousError (a.Expr.Type);
-                                       ec.Report.SymbolRelatedToPreviousError (paramType);
+                                       p1 = a.Type.GetSignatureForErrorIncludingAssemblyName ();
+                                       p2 = paramType.GetSignatureForErrorIncludingAssemblyName ();
                                }
 
                                ec.Report.Error (1503, loc,
@@ -4341,7 +4433,7 @@ namespace Mono.CSharp {
 
                        if (ta_count != best_candidate.Arity && (ta_count > 0 || ((IParametersMember) best_candidate).Parameters.IsEmpty)) {
                                var mg = new MethodGroupExpr (new [] { best_candidate }, best_candidate.DeclaringType, loc);
-                               mg.Error_TypeArgumentsCannotBeUsed (rc.Report, loc, best_candidate, ta_count);
+                               mg.Error_TypeArgumentsCannotBeUsed (rc, best_candidate, ta_count, loc);
                                return;
                        }
 
@@ -4354,10 +4446,10 @@ namespace Mono.CSharp {
                        // For candidates which match on parameters count report more details about incorrect arguments
                        //
                        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) || !best_candidate.DeclaringType.IsAccessible (rc)) {
                                                rc.Report.SymbolRelatedToPreviousError (best_candidate);
                                                Expression.ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
                                                return;
@@ -4477,10 +4569,10 @@ namespace Mono.CSharp {
                                        }
                                }
                                
-                               if (a.Expr.Type == InternalType.Dynamic)
+                               if (a.Expr.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                                        continue;
 
-                               if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (a.Expr, pt)) {
+                               if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (ec, a.Expr.Type, pt)) {
                                        custom_errors.NoArgumentMatch (ec, member);
                                        return false;
                                }
@@ -4554,7 +4646,7 @@ namespace Mono.CSharp {
                        if (type_arguments == null && member.IsGeneric) {
                                var ms = (MethodSpec) member;
                                foreach (var ta in ms.TypeArguments) {
-                                       if (!ta.IsAccessible (ec.CurrentType)) {
+                                       if (!ta.IsAccessible (ec)) {
                                                ec.Report.SymbolRelatedToPreviousError (ta);
                                                Expression.ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
                                                break;
@@ -4568,7 +4660,7 @@ namespace Mono.CSharp {
 
        public class ConstantExpr : MemberExpr
        {
-               ConstSpec constant;
+               readonly ConstSpec constant;
 
                public ConstantExpr (ConstSpec constant, Location loc)
                {
@@ -4599,13 +4691,13 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       ResolveInstanceExpression (rc);
+                       ResolveInstanceExpression (rc, null);
                        DoBestMemberChecks (rc, constant);
 
                        var c = constant.GetConstant (rc);
 
                        // Creates reference expression to the constant value
-                       return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc);
+                       return Constant.CreateConstant (constant.MemberType, c.GetValue (), loc);
                }
 
                public override void Emit (EmitContext ec)
@@ -4620,7 +4712,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "constant", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "constant", GetSignatureForError (), loc);
                }
        }
 
@@ -4704,12 +4796,12 @@ namespace Mono.CSharp {
                        return TypeManager.GetFullNameSignature (spec);
                }
 
-               public bool IsMarshalByRefAccess ()
+               public bool IsMarshalByRefAccess (ResolveContext rc)
                {
                        // Checks possible ldflda of field access expression
-                       return !spec.IsStatic && TypeManager.IsValueType (spec.MemberType) &&
-                               TypeSpec.IsBaseClass (spec.DeclaringType, TypeManager.mbr_type, false) &&
-                               !(InstanceExpression is This);
+                       return !spec.IsStatic && TypeSpec.IsValueType (spec.MemberType) && !(InstanceExpression is This) &&
+                               rc.Module.PredefinedTypes.MarshalByRefObject.Define () &&
+                               TypeSpec.IsBaseClass (spec.DeclaringType, rc.Module.PredefinedTypes.MarshalByRefObject.TypeSpec, false);
                }
 
                public void SetHasAddressTaken ()
@@ -4742,38 +4834,40 @@ 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)) {
-                               // 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.
+                       bool lvalue_instance = rhs != null && IsInstance && spec.DeclaringType.IsStruct;
 
-                               if (lvalue_instance) {
-                                       using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                               Expression right_side =
-                                                       out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
+                       if (rhs != this) {
+                               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.
 
-                                               InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
-                                       }
-                               } else {
-                                       using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                               InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
-                                       }
-                               }
+                                       if (lvalue_instance) {
+                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                                       bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
 
-                               if (InstanceExpression == null)
-                                       return null;
+                                                       Expression right_side =
+                                                               out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
 
-                               using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
-                                       InstanceExpression.CheckMarshalByRefAccess (ec);
+                                                       InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
+                                               }
+                                       } else {
+                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
+                                                       InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
+                                               }
+                                       }
+
+                                       if (InstanceExpression == null)
+                                               return null;
                                }
-                       }
 
-                       DoBestMemberChecks (ec, spec);
+                               DoBestMemberChecks (ec, spec);
+                       }
 
                        var fb = spec as FixedFieldSpec;
                        IVariableReference var = InstanceExpression as IVariableReference;
@@ -4839,7 +4933,7 @@ namespace Mono.CSharp {
                Expression Report_AssignToReadonly (ResolveContext ec, Expression right_side)
                {
                        int i = 0;
-                       if (right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess)
+                       if (right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess)
                                i += 1;
                        if (IsStatic)
                                i += 2;
@@ -4852,17 +4946,14 @@ 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;
 
                        spec.MemberDefinition.SetIsAssigned ();
 
-                       if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) &&
+                       if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess) &&
                                        (spec.Modifiers & Modifiers.VOLATILE) != 0) {
                                ec.Report.Warning (420, 1, loc,
                                        "`{0}': A volatile field references will not be treated as volatile",
@@ -4888,8 +4979,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (right_side == EmptyExpression.OutAccess.Instance &&
-                               !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeSpec.IsBaseClass (spec.DeclaringType, TypeManager.mbr_type, false)) {
+                       if (right_side == EmptyExpression.OutAccess && IsMarshalByRefAccess (ec)) {
                                ec.Report.SymbolRelatedToPreviousError (spec.DeclaringType);
                                ec.Report.Warning (197, 1, loc,
                                                "Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class",
@@ -4953,7 +5043,7 @@ namespace Mono.CSharp {
                                        EmitInstance (ec, false);
 
                                // Optimization for build-in types
-                               if (TypeManager.IsStruct (type) && type == ec.MemberContext.CurrentType && InstanceExpression.Type == type) {
+                               if (type.IsStruct && type == ec.CurrentType && InstanceExpression.Type == type) {
                                        ec.EmitLoadFromPtr (type);
                                } else {
                                        var ff = spec as FixedFieldSpec;
@@ -5037,7 +5127,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;
@@ -5073,14 +5163,18 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
+#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)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "field", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "field", GetSignatureForError (), loc);
                }
        }
 
@@ -5165,12 +5259,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)
@@ -5182,7 +5284,7 @@ namespace Mono.CSharp {
 
                bool IsSingleDimensionalArrayLength ()
                {
-                       if (best_candidate.DeclaringType != TypeManager.array_type || !best_candidate.HasGet || Name != "Length")
+                       if (best_candidate.DeclaringType.BuiltinType != BuiltinTypeSpec.Type.Array || !best_candidate.HasGet || Name != "Length")
                                return false;
 
                        ArrayContainer ac = InstanceExpression.Type as ArrayContainer;
@@ -5254,14 +5356,11 @@ namespace Mono.CSharp {
                {
                        eclass = ExprClass.PropertyAccess;
 
-                       if (best_candidate.IsNotRealProperty) {
+                       if (best_candidate.IsNotCSharpCompatible) {
                                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);
@@ -5277,7 +5376,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "property", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "property", GetSignatureForError (), loc);
                }
        }
 
@@ -5324,9 +5423,6 @@ namespace Mono.CSharp {
                                if (expr == null)
                                        return null;
 
-                               if (InstanceExpression != null)
-                                       InstanceExpression.CheckMarshalByRefAccess (ec);
-
                                if (expr != this)
                                        return expr.Resolve (ec);
                        }
@@ -5339,7 +5435,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       if (right_side == EmptyExpression.OutAccess.Instance) {
+                       if (right_side == EmptyExpression.OutAccess) {
                                // TODO: best_candidate can be null at this point
                                INamedBlockVariable variable = null;
                                if (best_candidate != null && ec.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, ec.CurrentBlock, ref variable) && variable is Linq.RangeVariable) {
@@ -5395,7 +5491,7 @@ namespace Mono.CSharp {
                                                best_candidate.GetSignatureForError ());
                                        return false;
                                }
-                       } else if (!best_candidate.Get.IsAccessible (rc.CurrentType)) {
+                       } else if (!best_candidate.Get.IsAccessible (rc)) {
                                if (best_candidate.HasDifferentAccessibility) {
                                        rc.Report.SymbolRelatedToPreviousError (best_candidate.Get);
                                        rc.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
@@ -5422,7 +5518,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       if (!best_candidate.Set.IsAccessible (rc.CurrentType)) {
+                       if (!best_candidate.Set.IsAccessible (rc)) {
                                if (best_candidate.HasDifferentAccessibility) {
                                        rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
                                        rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
@@ -5496,7 +5592,7 @@ namespace Mono.CSharp {
                        //
                        if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
                                if (spec.BackingField != null &&
-                                       (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType))) {
+                                       (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType.MemberDefinition))) {
 
                                        spec.MemberDefinition.SetIsUsed ();
 
@@ -5515,8 +5611,6 @@ namespace Mono.CSharp {
 
                                        return ml.ResolveMemberAccess (ec, left, original);
                                }
-
-                               Error_AssignmentEventOnly (ec);
                        }
 
                        return base.ResolveMemberAccess (ec, left, original);
@@ -5549,10 +5643,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);
@@ -5586,15 +5680,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)
@@ -5610,7 +5704,7 @@ namespace Mono.CSharp {
 
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
-                       Error_TypeArgumentsCannotBeUsed (ec.Report, "event", GetSignatureForError (), loc);
+                       Error_TypeArgumentsCannotBeUsed (ec, "event", GetSignatureForError (), loc);
                }
        }
 
@@ -5754,7 +5848,7 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("An implicitly typed local variable could not be redefined");
                        
                        type = right_side.Type;
-                       if (type == InternalType.Null || type == TypeManager.void_type || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) {
+                       if (type == InternalType.NullLiteral || type.Kind == MemberKind.Void || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) {
                                ec.Report.Error (815, loc,
                                        "An implicitly typed local variable declaration cannot be initialized with `{0}'",
                                        type.GetSignatureForError ());
@@ -5767,10 +5861,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");
+                               ec.Module.Compiler.Report.Error (825, loc, "The contextual keyword `var' may only appear within a local variable declaration");
                }
        }
 }