Inflate custom site container delegates correctly.
[mono.git] / mcs / mcs / expression.cs
index 38ec8e37d2bf11dfd594da791e9e1a4ac971fc97..ccfb19e030fbbe7eff683e228474a8a2acd59ed0 100644 (file)
@@ -622,7 +622,7 @@ namespace Mono.CSharp {
                                VariableInfo vi = vr.VariableInfo;
                                if (vi != null) {
                                        if (vi.LocalInfo != null)
-                                               vi.LocalInfo.Used = true;
+                                               vi.LocalInfo.SetIsUsed ();
 
                                        //
                                        // A variable is considered definitely assigned if you take its address.
@@ -688,7 +688,7 @@ namespace Mono.CSharp {
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (expr));
 
-                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.NoBaseMembers, loc);
+                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.BaseMembersIncluded | OverloadResolver.Restrictions.NoBaseMembers, loc);
                        var oper = res.ResolveOperator (ec, ref args);
 
                        if (oper == null)
@@ -857,7 +857,7 @@ namespace Mono.CSharp {
                        }
 
                        if (expr.Type == TypeManager.void_ptr_type) {
-                               ec.Report.Error (242, loc, "The operation in question is undefined on void pointers");
+                               Error_VoidPointerOperation (ec);
                                return null;
                        }
 
@@ -974,6 +974,8 @@ namespace Mono.CSharp {
                // Holds the real operation
                Expression operation;
 
+               static TypeSpec[] predefined;
+
                public UnaryMutator (Mode m, Expression e, Location loc)
                {
                        mode = m;
@@ -986,6 +988,29 @@ namespace Mono.CSharp {
                        return new SimpleAssign (this, this).CreateExpressionTree (ec);
                }
 
+               void CreatePredefinedOperators ()
+               {
+                       //
+                       // Predefined ++ and -- operators exist for the following types: 
+                       // sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal
+                       //
+                       predefined = new TypeSpec[] {
+                               TypeManager.int32_type,
+
+                               TypeManager.sbyte_type,
+                               TypeManager.byte_type,
+                               TypeManager.short_type,
+                               TypeManager.ushort_type,
+                               TypeManager.uint32_type,
+                               TypeManager.int64_type,
+                               TypeManager.uint64_type,
+                               TypeManager.char_type,
+                               TypeManager.float_type,
+                               TypeManager.double_type,
+                               TypeManager.decimal_type
+                       };
+               }
+
                protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
@@ -1011,7 +1036,108 @@ namespace Mono.CSharp {
 
                        eclass = ExprClass.Value;
                        type = expr.Type;
-                       return ResolveOperator (ec);
+
+                       if (expr is RuntimeValueExpression) {
+                               operation = expr;
+                       } else {
+                               // Use itself at the top of the stack
+                               operation = new EmptyExpression (type);
+                       }
+
+                       //
+                       // The operand of the prefix/postfix increment decrement operators
+                       // should be an expression that is classified as a variable,
+                       // a property access or an indexer access
+                       //
+                       // TODO: Move to parser, expr is ATypeNameExpression
+                       if (expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess) {
+                               expr = expr.ResolveLValue (ec, expr);
+                       } else {
+                               ec.Report.Error (1059, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
+                       }
+
+                       //
+                       // Step 1: Try to find a user operator, it has priority over predefined ones
+                       //
+                       var user_op = IsDecrement ? Operator.OpType.Decrement : Operator.OpType.Increment;
+                       var methods = MemberCache.GetUserOperator (type, user_op, false);
+
+                       if (methods != null) {
+                               Arguments args = new Arguments (1);
+                               args.Add (new Argument (expr));
+
+                               var res = new OverloadResolver (methods, OverloadResolver.Restrictions.BaseMembersIncluded | OverloadResolver.Restrictions.NoBaseMembers, loc);
+                               var method = res.ResolveOperator (ec, ref args);
+                               if (method == null)
+                                       return null;
+
+                               args[0].Expr = operation;
+                               operation = new UserOperatorCall (method, args, null, loc);
+                               operation = Convert.ImplicitConversionRequired (ec, operation, type, loc);
+                               return this;
+                       }
+
+                       //
+                       // Step 2: Try predefined types
+                       //
+                       if (predefined == null)
+                               CreatePredefinedOperators ();
+
+                       // Predefined without user conversion first for speed-up
+                       Expression source = null;
+                       bool primitive_type = false;
+                       foreach (var t in predefined) {
+                               if (t == type) {
+                                       source = operation;
+                                       primitive_type = true;
+                                       break;
+                               }
+                       }
+
+                       // ++/-- on pointer variables of all types except void*
+                       if (source == null && type.IsPointer) {
+                               if (type == TypeManager.void_ptr_type) {
+                                       Error_VoidPointerOperation (ec);
+                                       return null;
+                               }
+
+                               source = operation;
+                       }
+
+                       if (source == null) {
+                               // LAMESPEC: It should error on ambiguous operators but that would make us incompatible
+                               foreach (var t in predefined) {
+                                       source = Convert.ImplicitUserConversion (ec, operation, t, loc);
+                                       if (source != null) {
+                                               break;
+                                       }
+                               }
+                       }
+
+                       // ++/-- on enum types
+                       if (source == null && type.IsEnum)
+                               source = operation;
+
+                       if (source == null) {
+                               Unary.Error_OperatorCannotBeApplied (ec, loc, Operator.GetName (user_op), type);
+                               return null;
+                       }
+
+                       var one = new IntConstant (1, loc);
+                       var op = IsDecrement ? Binary.Operator.Subtraction : Binary.Operator.Addition;
+                       operation = new Binary (op, source, one, loc);
+                       operation = operation.Resolve (ec);
+                       if (operation == null)
+                               throw new NotImplementedException ("should not be reached");
+
+                       if (operation.Type != type) {
+                               if (primitive_type)
+                                       operation = Convert.ExplicitNumericConversion (operation, type);
+                               else
+                                       operation = Convert.ImplicitConversionRequired (ec, operation, type, loc);
+                       }
+
+                       return this;
                }
 
                void EmitCode (EmitContext ec, bool is_expr)
@@ -1057,18 +1183,6 @@ namespace Mono.CSharp {
                        get { return (mode & Mode.IsDecrement) != 0; }
                }
 
-               //
-               //   Returns whether an object of type `t' can be incremented
-               //   or decremented with add/sub (ie, basically whether we can
-               //   use pre-post incr-decr operations on it, but it is not a
-               //   System.Decimal, which we require operator overloading to catch)
-               //
-               static bool IsPredefinedOperator (TypeSpec t)
-               {
-                       return (TypeManager.IsPrimitiveType (t) && t != TypeManager.bool_type) ||
-                               TypeManager.IsEnumType (t) ||
-                               t.IsPointer && t != TypeManager.void_ptr_type;
-               }
 
 #if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
@@ -1079,78 +1193,16 @@ namespace Mono.CSharp {
                }
 #endif
 
-               protected override void CloneTo (CloneContext clonectx, Expression t)
+               public static void Reset ()
                {
-                       UnaryMutator target = (UnaryMutator) t;
-
-                       target.expr = expr.Clone (clonectx);
+                       predefined = null;
                }
 
-               Expression ResolveOperator (ResolveContext ec)
+               protected override void CloneTo (CloneContext clonectx, Expression t)
                {
-                       if (expr is RuntimeValueExpression) {
-                               operation = expr;
-                       } else {
-                               // Use itself at the top of the stack
-                               operation = new EmptyExpression (type);
-                       }
-
-                       //
-                       // The operand of the prefix/postfix increment decrement operators
-                       // should be an expression that is classified as a variable,
-                       // a property access or an indexer access
-                       //
-                       if (expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess) {
-                               expr = expr.ResolveLValue (ec, expr);
-                       } else {
-                               ec.Report.Error (1059, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
-                       }
-
-                       //
-                       // 1. Check predefined types
-                       //
-                       if (IsPredefinedOperator (type)) {
-                               // TODO: Move to IntConstant once I get rid of int32_type
-                               var one = new IntConstant (1, loc);
-
-                               // TODO: Cache this based on type when using EmptyExpression in
-                               // context cache
-                               Binary.Operator op = IsDecrement ? Binary.Operator.Subtraction : Binary.Operator.Addition;
-                               operation = new Binary (op, operation, one, loc);
-                               operation = operation.Resolve (ec);
-                               if (operation != null && operation.Type != type)
-                                       operation = Convert.ExplicitNumericConversion (operation, type);
-
-                               return this;
-                       }
-
-                       //
-                       // Step 2: Perform Operator Overload location
-                       //
-                       var user_op = IsDecrement ? Operator.OpType.Decrement : Operator.OpType.Increment;
-                       var methods = MemberCache.GetUserOperator (type, user_op, false);
-
-                       if (methods != null) {
-                               Arguments args = new Arguments (1);
-                               args.Add (new Argument (expr));
-
-                               var res = new OverloadResolver (methods, OverloadResolver.Restrictions.NoBaseMembers, loc);
-                               var op = res.ResolveOperator (ec, ref args);
-                               if (op == null)
-                                       return null;
-
-                               args[0].Expr = operation;
-                               operation = new UserOperatorCall (op, args, null, loc);
-                               operation = Convert.ImplicitConversionRequired (ec, operation, type, loc);
-                               return this;
-                       }
-
-                       string name = IsDecrement ?
-                               Operator.GetName (Operator.OpType.Decrement) :
-                               Operator.GetName (Operator.OpType.Increment);
+                       UnaryMutator target = (UnaryMutator) t;
 
-                       Unary.Error_OperatorCannotBeApplied (ec, loc, name, type);
-                       return null;
+                       target.expr = expr.Clone (clonectx);
                }
        }
 
@@ -1342,6 +1394,12 @@ namespace Mono.CSharp {
                                if (TypeManager.IsGenericParameter (t))
                                        return ResolveGenericParameter (ec, d, (TypeParameterSpec) t);
 
+                               if (t == InternalType.Dynamic) {
+                                       ec.Report.Warning (1981, 3, loc,
+                                               "Using `{0}' to test compatibility with `{1}' is identical to testing compatibility with `object'",
+                                               OperatorName, t.GetSignatureForError ());
+                               }
+
                                if (TypeManager.IsStruct (d)) {
                                        if (Convert.ImplicitBoxingConversion (null, d, t) != null)
                                                return CreateConstantResult (ec, true);
@@ -1529,14 +1587,6 @@ namespace Mono.CSharp {
 
                        if (type.IsPointer && !ec.IsUnsafe) {
                                UnsafeError (ec, loc);
-                       } else if (expr.Type == InternalType.Dynamic) {
-                               if (type != InternalType.Dynamic) {
-                                       Arguments arg = new Arguments (1);
-                                       arg.Add (new Argument (expr));
-                                       return new DynamicConversion (type, CSharpBinderFlags.ConvertExplicit, arg, loc).Resolve (ec);
-                               }
-
-                               return expr;
                        }
 
                        var res = Convert.ExplicitConversion (ec, expr, type, loc);
@@ -1621,7 +1671,7 @@ namespace Mono.CSharp {
                        if (TypeManager.IsReferenceType (type))
                                return new NullConstant (type, loc);
 
-                       Constant c = New.Constantify (type);
+                       Constant c = New.Constantify (type, expr.Location);
                        if (c != null)
                                return c.Resolve (ec);
 
@@ -1700,7 +1750,7 @@ namespace Mono.CSharp {
 
                                var c = b.right as Constant;
                                if (c != null) {
-                                       if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.BitwiseOr || b.oper == Operator.Subtraction))
+                                       if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.Subtraction || (b.oper == Operator.BitwiseOr && !(b is Nullable.LiftedBinaryOperator))))
                                                return ReducedExpression.Create (b.left, b).Resolve (ec);
                                        if ((b.oper == Operator.Multiply || b.oper == Operator.Division) && c.IsOneInteger)
                                                return ReducedExpression.Create (b.left, b).Resolve (ec);
@@ -1709,7 +1759,7 @@ namespace Mono.CSharp {
 
                                c = b.left as Constant;
                                if (c != null) {
-                                       if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.BitwiseOr))
+                                       if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.Subtraction || (b.oper == Operator.BitwiseOr && !(b is Nullable.LiftedBinaryOperator))))
                                                return ReducedExpression.Create (b.right, b).Resolve (ec);
                                        if (b.oper == Operator.Multiply && c.IsOneInteger)
                                                return ReducedExpression.Create (b.right, b).Resolve (ec);
@@ -1979,9 +2029,17 @@ namespace Mono.CSharp {
                        RelationalMask  = 1 << 13
                }
 
+               protected enum State
+               {
+                       None = 0,
+                       Compound = 1 << 1,
+                       LeftNullLifted = 1 << 2,
+                       RightNullLifted = 1 << 3
+               }
+
                readonly Operator oper;
                protected Expression left, right;
-               readonly bool is_compound;
+               protected State state;
                Expression enum_conversion;
 
                static PredefinedOperator[] standard_operators;
@@ -1991,7 +2049,8 @@ namespace Mono.CSharp {
                public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc)
                        : this (oper, left, right, loc)
                {
-                       this.is_compound = isCompound;
+                       if (isCompound)
+                               state |= State.Compound;
                }
 
                public Binary (Operator oper, Expression left, Expression right, Location loc)
@@ -2002,12 +2061,22 @@ namespace Mono.CSharp {
                        this.loc = loc;
                }
 
+               #region Properties
+
+               public bool IsCompound {
+                       get {
+                               return (state & State.Compound) != 0;
+                       }
+               }
+
                public Operator Oper {
                        get {
                                return oper;
                        }
                }
-               
+
+               #endregion
+
                /// <summary>
                ///   Returns a stringified representation of the Operator
                /// </summary>
@@ -2074,7 +2143,7 @@ namespace Mono.CSharp {
                                break;
                        }
 
-                       if (is_compound)
+                       if (IsCompound)
                                return s + "=";
 
                        return s;
@@ -2107,15 +2176,15 @@ namespace Mono.CSharp {
                {
                        switch (oper) {
                        case Operator.Addition:
-                               return is_compound ? "AddAssign" : "Add";
+                               return IsCompound ? "AddAssign" : "Add";
                        case Operator.BitwiseAnd:
-                               return is_compound ? "AndAssign" : "And";
+                               return IsCompound ? "AndAssign" : "And";
                        case Operator.BitwiseOr:
-                               return is_compound ? "OrAssign" : "Or";
+                               return IsCompound ? "OrAssign" : "Or";
                        case Operator.Division:
-                               return is_compound ? "DivideAssign" : "Divide";
+                               return IsCompound ? "DivideAssign" : "Divide";
                        case Operator.ExclusiveOr:
-                               return is_compound ? "ExclusiveOrAssign" : "ExclusiveOr";
+                               return IsCompound ? "ExclusiveOrAssign" : "ExclusiveOr";
                        case Operator.Equality:
                                return "Equal";
                        case Operator.GreaterThan:
@@ -2125,7 +2194,7 @@ namespace Mono.CSharp {
                        case Operator.Inequality:
                                return "NotEqual";
                        case Operator.LeftShift:
-                               return is_compound ? "LeftShiftAssign" : "LeftShift";
+                               return IsCompound ? "LeftShiftAssign" : "LeftShift";
                        case Operator.LessThan:
                                return "LessThan";
                        case Operator.LessThanOrEqual:
@@ -2135,13 +2204,13 @@ namespace Mono.CSharp {
                        case Operator.LogicalOr:
                                return "Or";
                        case Operator.Modulus:
-                               return is_compound ? "ModuloAssign" : "Modulo";
+                               return IsCompound ? "ModuloAssign" : "Modulo";
                        case Operator.Multiply:
-                               return is_compound ? "MultiplyAssign" : "Multiply";
+                               return IsCompound ? "MultiplyAssign" : "Multiply";
                        case Operator.RightShift:
-                               return is_compound ? "RightShiftAssign" : "RightShift";
+                               return IsCompound ? "RightShiftAssign" : "RightShift";
                        case Operator.Subtraction:
-                               return is_compound ? "SubtractAssign" : "Subtract";
+                               return IsCompound ? "SubtractAssign" : "Subtract";
                        default:
                                throw new NotImplementedException ("Unknown expression type operator " + oper.ToString ());
                        }
@@ -2366,12 +2435,11 @@ namespace Mono.CSharp {
                                        return ResolveOperatorPointer (ec, l, r);
 
                                // Enums
-                               bool lenum = TypeManager.IsEnumType (l);
-                               bool renum = TypeManager.IsEnumType (r);
+                               bool lenum = l.IsEnum;
+                               bool renum = r.IsEnum;
                                if (lenum || renum) {
                                        expr = ResolveOperatorEnum (ec, lenum, renum, l, r);
 
-                                       // TODO: Can this be ambiguous
                                        if (expr != null)
                                                return expr;
                                }
@@ -2862,88 +2930,133 @@ namespace Mono.CSharp {
                        //
                        // U operator - (E e, E f)
                        // E operator - (E e, U x)
+                       // E operator - (U x, E e)      // LAMESPEC: Not covered by the specification
                        //
-                       // E operator + (U x, E e)
                        // E operator + (E e, U x)
+                       // E operator + (U x, E e)
                        //
-                       if (!((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0 ||
-                               (oper == Operator.Subtraction && lenum) ||
-                               (oper == Operator.Addition && (lenum != renum || type != null))))       // type != null for lifted null
-                               return null;
-
                        Expression ltemp = left;
                        Expression rtemp = right;
                        TypeSpec underlying_type;
+                       TypeSpec underlying_type_result;
+                       TypeSpec res_type;
                        Expression expr;
                        
+                       //
+                       // LAMESPEC: There is never ambiguous conversion between enum operators
+                       // the one which contains more enum parameters always wins even if there
+                       // is an implicit conversion involved
+                       //
                        if ((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0) {
                                if (renum) {
+                                       underlying_type = EnumSpec.GetUnderlyingType (rtype);
                                        expr = Convert.ImplicitConversion (ec, left, rtype, loc);
-                                       if (expr != null) {
-                                               left = expr;
-                                               ltype = expr.Type;
-                                       }
+                                       if (expr == null)
+                                               return null;
+
+                                       left = expr;
+                                       ltype = expr.Type;
                                } else if (lenum) {
+                                       underlying_type = EnumSpec.GetUnderlyingType (ltype);
                                        expr = Convert.ImplicitConversion (ec, right, ltype, loc);
-                                       if (expr != null) {
-                                               right = expr;
-                                               rtype = expr.Type;
-                                       }
+                                       if (expr == null)
+                                               return null;
+
+                                       right = expr;
+                                       rtype = expr.Type;
+                               } else {
+                                       return null;
                                }
-                       }                       
 
-                       if (ltype == rtype) {
-                               underlying_type = EnumSpec.GetUnderlyingType (ltype);
+                               if ((oper & Operator.BitwiseMask) != 0) {
+                                       res_type = ltype;
+                                       underlying_type_result = underlying_type;
+                               } else {
+                                       res_type = null;
+                                       underlying_type_result = null;
+                               }
+                       } else if (oper == Operator.Subtraction) {
+                               if (renum) {
+                                       underlying_type = EnumSpec.GetUnderlyingType (rtype);
+                                       if (ltype != rtype) {
+                                               expr = Convert.ImplicitConversion (ec, left, rtype, left.Location);
+                                               if (expr == null) {
+                                                       expr = Convert.ImplicitConversion (ec, left, underlying_type, left.Location);
+                                                       if (expr == null)
+                                                               return null;
+
+                                                       res_type = rtype;
+                                               } else {
+                                                       res_type = underlying_type;
+                                               }
 
-                               if (left is Constant)
-                                       left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
-                               else
-                                       left = EmptyCast.Create (left, underlying_type);
+                                               left = expr;
+                                       } else {
+                                               res_type = underlying_type;
+                                       }
 
-                               if (right is Constant)
-                                       right = ((Constant) right).ConvertExplicitly (false, underlying_type).Resolve (ec);
-                               else
-                                       right = EmptyCast.Create (right, underlying_type);
-                       } else if (lenum) {
-                               underlying_type = EnumSpec.GetUnderlyingType (ltype);
+                                       underlying_type_result = underlying_type;
+                               } else if (lenum) {
+                                       underlying_type = EnumSpec.GetUnderlyingType (ltype);
+                                       expr = Convert.ImplicitConversion (ec, right, ltype, right.Location);
+                                       if (expr == null) {
+                                               expr = Convert.ImplicitConversion (ec, right, underlying_type, right.Location);
+                                               if (expr == null)
+                                                       return null;
 
-                               if (oper != Operator.Subtraction && oper != Operator.Addition) {
-                                       Constant c = right as Constant;
-                                       if (c == null || !c.IsDefaultValue)
-                                               return null;
+                                               res_type = ltype;
+                                       } else {
+                                               res_type = underlying_type;
+                                       }
+
+                                       right = expr;
+                                       underlying_type_result = underlying_type;
                                } else {
-                                       if (!Convert.ImplicitStandardConversionExists (right, underlying_type))
-                                               return null;
+                                       return null;
+                               }
+                       } else if (oper == Operator.Addition) {
+                               if (lenum) {
+                                       underlying_type = EnumSpec.GetUnderlyingType (ltype);
+                                       res_type = ltype;
+
+                                       if (rtype != underlying_type && (state & (State.RightNullLifted | State.LeftNullLifted)) == 0) {
+                                               expr = Convert.ImplicitConversion (ec, right, underlying_type, right.Location);
+                                               if (expr == null)
+                                                       return null;
 
-                                       right = Convert.ImplicitConversionStandard (ec, right, underlying_type, right.Location);
+                                               right = expr;
+                                       }
+                               } else {
+                                       underlying_type = EnumSpec.GetUnderlyingType (rtype);
+                                       res_type = rtype;
+                                       if (ltype != underlying_type) {
+                                               expr = Convert.ImplicitConversion (ec, left, underlying_type, left.Location);
+                                               if (expr == null)
+                                                       return null;
+
+                                               left = expr;
+                                       }
                                }
 
+                               underlying_type_result = underlying_type;
+                       } else {
+                               return null;
+                       }
+
+                       // Unwrap the constant correctly, so DoBinaryOperatorPromotion can do the magic
+                       // with constants and expressions
+                       if (left.Type != underlying_type) {
                                if (left is Constant)
                                        left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
                                else
                                        left = EmptyCast.Create (left, underlying_type);
+                       }
 
-                       } else if (renum) {
-                               underlying_type = EnumSpec.GetUnderlyingType (rtype);
-
-                               if (oper != Operator.Addition) {
-                                       Constant c = left as Constant;
-                                       if (c == null || !c.IsDefaultValue)
-                                               return null;
-                               } else {
-                                       if (!Convert.ImplicitStandardConversionExists (left, underlying_type))
-                                               return null;
-
-                                       left = Convert.ImplicitConversionStandard (ec, left, underlying_type, left.Location);
-                               }
-
+                       if (right.Type != underlying_type) {
                                if (right is Constant)
                                        right = ((Constant) right).ConvertExplicitly (false, underlying_type).Resolve (ec);
                                else
                                        right = EmptyCast.Create (right, underlying_type);
-
-                       } else {
-                               return null;
                        }
 
                        //
@@ -2956,22 +3069,15 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       TypeSpec res_type = null;
-                       if ((oper & Operator.BitwiseMask) != 0 || oper == Operator.Subtraction || oper == Operator.Addition) {
-                               TypeSpec promoted_type = lenum ? left.Type : right.Type;
-                               enum_conversion = Convert.ExplicitNumericConversion (
-                                       new EmptyExpression (promoted_type), underlying_type);
-
-                               if (oper == Operator.Subtraction && renum && lenum)
-                                       res_type = underlying_type;
-                               else if (oper == Operator.Addition && renum)
-                                       res_type = rtype;
-                               else
-                                       res_type = ltype;
+                       if (underlying_type_result != null && left.Type != underlying_type_result) {
+                               enum_conversion = Convert.ExplicitNumericConversion (new EmptyExpression (left.Type), underlying_type_result);
                        }
-                       
+
                        expr = ResolveOperatorPredefined (ec, standard_operators, true, res_type);
-                       if (!is_compound || expr == null)
+                       if (expr == null)
+                               return null;
+
+                       if (!IsCompound)
                                return expr;
 
                        //
@@ -3220,7 +3326,7 @@ namespace Mono.CSharp {
                        if (oper == Operator.BitwiseAnd || oper == Operator.LogicalAnd) {
                                Constant rc = right as Constant;
                                Constant lc = left as Constant;
-                               if ((lc != null && lc.IsDefaultValue) || (rc != null && rc.IsDefaultValue)) {
+                               if (((lc != null && lc.IsDefaultValue) || (rc != null && rc.IsDefaultValue)) && !(this is Nullable.LiftedBinaryOperator)) {
                                        //
                                        // The result is a constant with side-effect
                                        //
@@ -3275,7 +3381,8 @@ namespace Mono.CSharp {
                                left_operators = right_operators;
                        }
 
-                       var res = new OverloadResolver (left_operators, OverloadResolver.Restrictions.ProbingOnly, loc);
+                       var res = new OverloadResolver (left_operators, OverloadResolver.Restrictions.ProbingOnly | 
+                               OverloadResolver.Restrictions.NoBaseMembers | OverloadResolver.Restrictions.BaseMembersIncluded, loc);
 
                        var oper_method = res.ResolveOperator (ec, ref args);
                        if (oper_method == null)
@@ -3987,7 +4094,7 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Variable;
                        
                        if (left.Type == TypeManager.void_ptr_type) {
-                               ec.Report.Error (242, loc, "The operation in question is undefined on void pointers");
+                               Error_VoidPointerOperation (ec);
                                return null;
                        }
                        
@@ -4442,34 +4549,19 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       ///   Local variables
-       /// </summary>
-       public class LocalVariableReference : VariableReference {
-               readonly string name;
-               public Block Block;
-               public LocalInfo local_info;
-               bool is_readonly;
+       //
+       // Resolved reference to a local variable
+       //
+       public class LocalVariableReference : VariableReference
+       {
+               public LocalVariable local_info;
 
-               public LocalVariableReference (Block block, string name, Location l)
+               public LocalVariableReference (LocalVariable li, Location l)
                {
-                       Block = block;
-                       this.name = name;
+                       this.local_info = li;
                        loc = l;
                }
 
-               //
-               // Setting `is_readonly' to false will allow you to create a writable
-               // reference to a read-only variable.  This is used by foreach and using.
-               //
-               public LocalVariableReference (Block block, string name, Location l,
-                                              LocalInfo local_info, bool is_readonly)
-                       : this (block, name, l)
-               {
-                       this.local_info = local_info;
-                       this.is_readonly = is_readonly;
-               }
-
                public override VariableInfo VariableInfo {
                        get { return local_info.VariableInfo; }
                }
@@ -4490,12 +4582,8 @@ namespace Mono.CSharp {
                        get { return false; }
                }
 
-               public bool IsReadOnly {
-                       get { return is_readonly; }
-               }
-
                public override string Name {
-                       get { return name; }
+                       get { return local_info.Name; }
                }
 
                public bool VerifyAssigned (ResolveContext ec)
@@ -4504,15 +4592,6 @@ namespace Mono.CSharp {
                        return variable_info == null || variable_info.IsAssigned (ec, loc);
                }
 
-               void ResolveLocalInfo ()
-               {
-                       if (local_info == null) {
-                               local_info = Block.GetLocalInfo (Name);
-                               type = local_info.VariableType;
-                               is_readonly = local_info.ReadOnly;
-                       }
-               }
-
                public override void SetHasAddressTaken ()
                {
                        local_info.AddressTaken = true;
@@ -4531,10 +4610,6 @@ namespace Mono.CSharp {
 
                Expression DoResolveBase (ResolveContext ec)
                {
-                       Expression e = Block.GetConstantExpression (Name);
-                       if (e != null)
-                               return e.Resolve (ec);
-
                        VerifyAssigned (ec);
 
                        //
@@ -4552,43 +4627,24 @@ namespace Mono.CSharp {
                        }
 
                        eclass = ExprClass.Variable;
-                       type = local_info.VariableType;
+                       type = local_info.Type;
                        return this;
                }
 
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       ResolveLocalInfo ();
-                       local_info.Used = true;
+                       local_info.SetIsUsed ();
 
-                       if (type == null && local_info.Type is VarExpr) {
-                           local_info.VariableType = TypeManager.object_type;
-                               Error_VariableIsUsedBeforeItIsDeclared (ec.Report, Name);
-                           return null;
-                       }
-                       
                        return DoResolveBase (ec);
                }
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       ResolveLocalInfo ();
-
                        // is out param
                        if (right_side == EmptyExpression.OutAccess.Instance)
-                               local_info.Used = true;
+                               local_info.SetIsUsed ();
 
-                       // Infer implicitly typed local variable
-                       if (type == null) {
-                               VarExpr ve = local_info.Type as VarExpr;
-                               if (ve != null) {
-                                       if (!ve.InferType (ec, right_side))
-                                               return null;
-                                       type = local_info.VariableType = ve.Type;
-                               }
-                       }
-                                               
-                       if (is_readonly) {
+                       if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) {
                                int code;
                                string msg;
                                if (right_side == EmptyExpression.OutAccess.Instance) {
@@ -4612,7 +4668,7 @@ namespace Mono.CSharp {
 
                public override int GetHashCode ()
                {
-                       return Name.GetHashCode ();
+                       return local_info.GetHashCode ();
                }
 
                public override bool Equals (object obj)
@@ -4621,7 +4677,7 @@ namespace Mono.CSharp {
                        if (lvr == null)
                                return false;
 
-                       return Name == lvr.Name && Block == lvr.Block;
+                       return local_info == lvr.local_info;
                }
 
                protected override ILocalVariable Variable {
@@ -4635,11 +4691,7 @@ namespace Mono.CSharp {
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
-                       LocalVariableReference target = (LocalVariableReference) t;
-                       
-                       target.Block = clonectx.LookupBlock (Block);
-                       if (local_info != null)
-                               target.local_info = clonectx.LookupVariable (local_info);
+                       // Nothing
                }
        }
 
@@ -4647,15 +4699,18 @@ namespace Mono.CSharp {
        ///   This represents a reference to a parameter in the intermediate
        ///   representation.
        /// </summary>
-       public class ParameterReference : VariableReference {
-               readonly ToplevelParameterInfo pi;
+       public class ParameterReference : VariableReference
+       {
+               protected ParametersBlock.ParameterInfo pi;
 
-               public ParameterReference (ToplevelParameterInfo pi, Location loc)
+               public ParameterReference (ParametersBlock.ParameterInfo pi, Location loc)
                {
                        this.pi = pi;
                        this.loc = loc;
                }
 
+               #region Properties
+
                public override bool IsRef {
                        get { return (pi.Parameter.ModFlags & Parameter.Modifier.ISBYREF) != 0; }
                }
@@ -4693,6 +4748,8 @@ namespace Mono.CSharp {
                        get { return Parameter; }
                }
 
+               #endregion
+
                public bool IsAssigned (ResolveContext ec, Location loc)
                {
                        // HACK: Variables are not captured in probing mode
@@ -4722,42 +4779,24 @@ namespace Mono.CSharp {
                        type = pi.ParameterType;
                        eclass = ExprClass.Variable;
 
-                       AnonymousExpression am = ec.CurrentAnonymousMethod;
-                       if (am == null)
-                               return true;
-
-                       Block b = ec.CurrentBlock;
-                       while (b != null) {
-                               b = b.Toplevel;
-                               IParameterData[] p = b.Toplevel.Parameters.FixedParameters;
-                               for (int i = 0; i < p.Length; ++i) {
-                                       if (p [i] != Parameter)
-                                               continue;
-
-                                       //
-                                       // Don't capture local parameters
-                                       //
-                                       if (b == ec.CurrentBlock.Toplevel && !am.IsIterator)
-                                               return true;
-
-                                       if (IsRef) {
-                                               ec.Report.Error (1628, loc,
-                                                       "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' modifier",
-                                                       Name, am.ContainerType);
-                                       }
-
-                                       if (pi.Parameter.HasAddressTaken)
-                                               AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, this, loc);
-
-                                       if (ec.IsVariableCapturingRequired && !b.Toplevel.IsExpressionTree) {
-                                               AnonymousMethodStorey storey = pi.Block.CreateAnonymousMethodStorey (ec);
-                                               storey.CaptureParameter (ec, this);
-                                       }
+                       //
+                       // If we are referencing a parameter from the external block
+                       // flag it for capturing
+                       //
+                       if (ec.MustCaptureVariable (pi)) {
+                               if (Parameter.HasAddressTaken)
+                                       AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, this, loc);
 
-                                       return true;
+                               if (IsRef) {
+                                       ec.Report.Error (1628, loc,
+                                               "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' modifier",
+                                               Name, ec.CurrentAnonymousMethod.ContainerType);
                                }
 
-                               b = b.Parent;
+                               if (ec.IsVariableCapturingRequired && !pi.Block.ParametersBlock.IsExpressionTree) {
+                                       AnonymousMethodStorey storey = pi.Block.Explicit.CreateAnonymousMethodStorey (ec);
+                                       storey.CaptureParameter (ec, this);
+                               }
                        }
 
                        return true;
@@ -4793,6 +4832,7 @@ namespace Mono.CSharp {
                protected override void CloneTo (CloneContext clonectx, Expression target)
                {
                        // Nothing to clone
+                       return;
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -4918,7 +4958,7 @@ namespace Mono.CSharp {
                        Expression member_expr;
                        var atn = expr as ATypeNameExpression;
                        if (atn != null) {
-                               member_expr = atn.LookupNameExpression (ec, true, true);
+                               member_expr = atn.LookupNameExpression (ec, MemberLookupRestrictions.InvocableOnly | MemberLookupRestrictions.ReadAccess);
                                if (member_expr != null)
                                        member_expr = member_expr.Resolve (ec);
                        } else {
@@ -5270,11 +5310,12 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       ///    Implements the new expression 
-       /// </summary>
-       public class New : ExpressionStatement, IMemoryLocation {
-               protected Arguments Arguments;
+       //
+       // Implements simple new expression 
+       //
+       public class New : ExpressionStatement, IMemoryLocation
+       {
+               protected Arguments arguments;
 
                //
                // During bootstrap, it contains the RequestedType,
@@ -5288,45 +5329,63 @@ namespace Mono.CSharp {
                public New (Expression requested_type, Arguments arguments, Location l)
                {
                        RequestedType = requested_type;
-                       Arguments = arguments;
+                       this.arguments = arguments;
                        loc = l;
                }
 
+               #region Properties
+               public Arguments Arguments {
+                       get {
+                               return arguments;
+                       }
+               }
+
+               //
+               // Returns true for resolved `new S()'
+               //
+               public bool IsDefaultStruct {
+                       get {
+                               return arguments == null && type.IsStruct && GetType () == typeof (New);
+                       }
+               }
+
+               #endregion
+
                /// <summary>
                /// Converts complex core type syntax like 'new int ()' to simple constant
                /// </summary>
-               public static Constant Constantify (TypeSpec t)
+               public static Constant Constantify (TypeSpec t, Location loc)
                {
                        if (t == TypeManager.int32_type)
-                               return new IntConstant (0, Location.Null);
+                               return new IntConstant (0, loc);
                        if (t == TypeManager.uint32_type)
-                               return new UIntConstant (0, Location.Null);
+                               return new UIntConstant (0, loc);
                        if (t == TypeManager.int64_type)
-                               return new LongConstant (0, Location.Null);
+                               return new LongConstant (0, loc);
                        if (t == TypeManager.uint64_type)
-                               return new ULongConstant (0, Location.Null);
+                               return new ULongConstant (0, loc);
                        if (t == TypeManager.float_type)
-                               return new FloatConstant (0, Location.Null);
+                               return new FloatConstant (0, loc);
                        if (t == TypeManager.double_type)
-                               return new DoubleConstant (0, Location.Null);
+                               return new DoubleConstant (0, loc);
                        if (t == TypeManager.short_type)
-                               return new ShortConstant (0, Location.Null);
+                               return new ShortConstant (0, loc);
                        if (t == TypeManager.ushort_type)
-                               return new UShortConstant (0, Location.Null);
+                               return new UShortConstant (0, loc);
                        if (t == TypeManager.sbyte_type)
-                               return new SByteConstant (0, Location.Null);
+                               return new SByteConstant (0, loc);
                        if (t == TypeManager.byte_type)
-                               return new ByteConstant (0, Location.Null);
+                               return new ByteConstant (0, loc);
                        if (t == TypeManager.char_type)
-                               return new CharConstant ('\0', Location.Null);
+                               return new CharConstant ('\0', loc);
                        if (t == TypeManager.bool_type)
-                               return new BoolConstant (false, Location.Null);
+                               return new BoolConstant (false, loc);
                        if (t == TypeManager.decimal_type)
-                               return new DecimalConstant (0, Location.Null);
+                               return new DecimalConstant (0, loc);
                        if (TypeManager.IsEnumType (t))
-                               return new EnumConstant (Constantify (EnumSpec.GetUnderlyingType (t)), t);
+                               return new EnumConstant (Constantify (EnumSpec.GetUnderlyingType (t), loc), t);
                        if (TypeManager.IsNullableType (t))
-                               return Nullable.LiftedNull.Create (t, Location.Null);
+                               return Nullable.LiftedNull.Create (t, loc);
 
                        return null;
                }
@@ -5349,7 +5408,7 @@ namespace Mono.CSharp {
                        if (real_class == null)
                                return null;
 
-                       New proxy = new New (new TypeExpression (real_class, loc), Arguments, loc);
+                       New proxy = new New (new TypeExpression (real_class, loc), arguments, loc);
                        Cast cast = new Cast (new TypeExpression (type, loc), proxy, loc);
                        return cast.Resolve (ec);
                }
@@ -5362,7 +5421,7 @@ namespace Mono.CSharp {
                                args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        } else {
                                args = Arguments.CreateForExpressionTree (ec,
-                                       Arguments, new TypeOfMethod (method, loc));
+                                       arguments, new TypeOfMethod (method, loc));
                        }
 
                        return CreateExpressionFactoryCall (ec, "New", args);
@@ -5383,14 +5442,14 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (Arguments == null) {
-                               Constant c = Constantify (type);
+                       if (arguments == null) {
+                               Constant c = Constantify (type, RequestedType.Location);
                                if (c != null)
                                        return ReducedExpression.Create (c.Resolve (ec), this);
                        }
 
                        if (TypeManager.IsDelegateType (type)) {
-                               return (new NewDelegate (type, Arguments, loc)).Resolve (ec);
+                               return (new NewDelegate (type, arguments, loc)).Resolve (ec);
                        }
 
                        var tparam = type as TypeParameterSpec;
@@ -5401,7 +5460,7 @@ namespace Mono.CSharp {
                                                TypeManager.CSharpName (type));
                                }
 
-                               if ((Arguments != null) && (Arguments.Count != 0)) {
+                               if ((arguments != null) && (arguments.Count != 0)) {
                                        ec.Report.Error (417, loc,
                                                "`{0}': cannot provide arguments when creating an instance of a variable type",
                                                TypeManager.CSharpName (type));
@@ -5439,21 +5498,21 @@ namespace Mono.CSharp {
                        //
                        // Any struct always defines parameterless constructor
                        //
-                       if (type.IsStruct && Arguments == null)
+                       if (type.IsStruct && arguments == null)
                                return this;
 
                        bool dynamic;
-                       if (Arguments != null) {
-                               Arguments.Resolve (ec, out dynamic);
+                       if (arguments != null) {
+                               arguments.Resolve (ec, out dynamic);
                        } else {
                                dynamic = false;
                        }
 
-                       method = ConstructorLookup (ec, type, ref Arguments, loc);
+                       method = ConstructorLookup (ec, type, ref arguments, loc);
 
                        if (dynamic) {
-                               Arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec), Argument.AType.DynamicTypeName));
-                               return new DynamicConstructorBinder (type, Arguments, loc).Resolve (ec);
+                               arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec), Argument.AType.DynamicTypeName));
+                               return new DynamicConstructorBinder (type, arguments, loc).Resolve (ec);
                        }
 
                        return this;
@@ -5534,8 +5593,8 @@ namespace Mono.CSharp {
                                vr.EmitLoad (ec);
                        }
                        
-                       if (Arguments != null)
-                               Arguments.Emit (ec);
+                       if (arguments != null)
+                               arguments.Emit (ec);
 
                        if (is_value_type) {
                                if (method == null) {
@@ -5580,12 +5639,6 @@ namespace Mono.CSharp {
                                ec.Emit (OpCodes.Pop);
                }
 
-               public virtual bool HasInitializer {
-                       get {
-                               return false;
-                       }
-               }
-
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        EmitAddressOf (ec, mode);
@@ -5617,8 +5670,8 @@ namespace Mono.CSharp {
                        if (method == null) {
                                ec.Emit (OpCodes.Initobj, type);
                        } else {
-                               if (Arguments != null)
-                                       Arguments.Emit (ec);
+                               if (arguments != null)
+                                       arguments.Emit (ec);
 
                                ec.Emit (OpCodes.Call, method);
                        }
@@ -5632,20 +5685,27 @@ namespace Mono.CSharp {
                        New target = (New) t;
 
                        target.RequestedType = RequestedType.Clone (clonectx);
-                       if (Arguments != null){
-                               target.Arguments = Arguments.Clone (clonectx);
+                       if (arguments != null){
+                               target.arguments = arguments.Clone (clonectx);
                        }
                }
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.New ((ConstructorInfo) method.GetMetaInfo (), Arguments.MakeExpression (Arguments, ctx));
+                       return SLE.Expression.New ((ConstructorInfo) method.GetMetaInfo (), Arguments.MakeExpression (arguments, ctx));
                }
        }
 
+       //
+       // Array initializer expression, the expression is allowed in
+       // variable or field initialization only which makes it tricky as
+       // the type has to be infered based on the context either from field
+       // type or variable type (think of multiple declarators)
+       //
        public class ArrayInitializer : Expression
        {
                List<Expression> elements;
+               BlockVariableDeclaration variable;
 
                public ArrayInitializer (List<Expression> init, Location loc)
                {
@@ -5654,9 +5714,8 @@ namespace Mono.CSharp {
                }
 
                public ArrayInitializer (int count, Location loc)
+                       : this (new List<Expression> (count), loc)
                {
-                       elements = new List<Expression> (count);
-                       this.loc = loc;
                }
 
                public ArrayInitializer (Location loc)
@@ -5664,6 +5723,29 @@ namespace Mono.CSharp {
                {
                }
 
+               #region Properties
+
+               public int Count {
+                       get { return elements.Count; }
+               }
+
+               public Expression this [int index] {
+                       get {
+                               return elements [index];
+                       }
+               }
+
+               public BlockVariableDeclaration VariableDeclaration {
+                       get {
+                               return variable;
+                       }
+                       set {
+                               variable = value;
+                       }
+               }
+
+               #endregion
+
                public void Add (Expression expr)
                {
                        elements.Add (expr);
@@ -5683,24 +5765,30 @@ namespace Mono.CSharp {
                                target.elements.Add (element.Clone (clonectx));
                }
 
-               public int Count {
-                       get { return elements.Count; }
-               }
-
                protected override Expression DoResolve (ResolveContext rc)
                {
                        var current_field = rc.CurrentMemberDefinition as FieldBase;
-                       return new ArrayCreation (new TypeExpression (current_field.MemberType, current_field.Location), this).Resolve (rc);
+                       TypeExpression type;
+                       if (current_field != null) {
+                               type = new TypeExpression (current_field.MemberType, current_field.Location);
+                       } else if (variable != null) {
+                               if (variable.TypeExpression is VarExpr) {
+                                       rc.Report.Error (820, loc, "An implicitly typed local variable declarator cannot use an array initializer");
+                                       return EmptyExpression.Null;
+                               }
+
+                               type = new TypeExpression (variable.Variable.Type, variable.Variable.Location);
+                       } else {
+                               throw new NotImplementedException ("Unexpected array initializer context");
+                       }
+
+                       return new ArrayCreation (type, this).Resolve (rc);
                }
 
                public override void Emit (EmitContext ec)
                {
                        throw new InternalErrorException ("Missing Resolve call");
                }
-
-               public Expression this [int index] {
-                       get { return elements [index]; }
-               }
        }
 
        /// <summary>
@@ -5969,11 +6057,6 @@ namespace Mono.CSharp {
                //
                bool ResolveArrayType (ResolveContext ec)
                {
-                       if (requested_base_type is VarExpr) {
-                               ec.Report.Error (820, loc, "An implicitly typed local variable declarator cannot use an array initializer");
-                               return false;
-                       }
-                       
                        //
                        // Lookup the type
                        //
@@ -6282,9 +6365,10 @@ namespace Mono.CSharp {
                                return;
 
                        // Emit static initializer for arrays which have contain more than 2 items and
-                       // the static initializer will initialize at least 25% of array values.
+                       // the static initializer will initialize at least 25% of array values or there
+                       // is more than 10 items to be initialized
                        // NOTE: const_initializers_count does not contain default constant values.
-                       if (const_initializers_count > 2 && const_initializers_count * 4 > (array_data.Count) &&
+                       if (const_initializers_count > 2 && (array_data.Count > 10 || const_initializers_count * 4 > (array_data.Count)) &&
                                (TypeManager.IsPrimitiveType (array_element_type) || TypeManager.IsEnumType (array_element_type))) {
                                EmitStaticInitializers (ec);
 
@@ -6568,8 +6652,8 @@ namespace Mono.CSharp {
 
                        var block = ec.CurrentBlock;
                        if (block != null) {
-                               if (block.Toplevel.ThisVariable != null)
-                                       variable_info = block.Toplevel.ThisVariable.VariableInfo;
+                               if (block.ParametersBlock.TopBlock.ThisVariable != null)
+                                       variable_info = block.ParametersBlock.TopBlock.ThisVariable.VariableInfo;
 
                                AnonymousExpression am = ec.CurrentAnonymousMethod;
                                if (am != null && ec.IsVariableCapturingRequired) {
@@ -6674,7 +6758,7 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Variable;
                        type = TypeManager.runtime_argument_handle_type;
 
-                       if (ec.HasSet (ResolveContext.Options.FieldInitializerScope) || !ec.CurrentBlock.Toplevel.Parameters.HasArglist) {
+                       if (ec.HasSet (ResolveContext.Options.FieldInitializerScope) || !ec.CurrentBlock.ParametersBlock.Parameters.HasArglist) {
                                ec.Report.Error (190, loc,
                                        "The __arglist construct is valid only within a variable argument method");
                        }
@@ -7175,7 +7259,7 @@ namespace Mono.CSharp {
                public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
                {
                        if (alias == GlobalAlias) {
-                               expr = GlobalRootNamespace.Instance;
+                               expr = ec.Compiler.GlobalRootNamespace;
                                return base.ResolveAsTypeStep (ec, silent);
                        }
 
@@ -7224,7 +7308,7 @@ namespace Mono.CSharp {
                        return alias + "::" + name;
                }
 
-               public override Expression LookupNameExpression (ResolveContext rc, bool readMode, bool invocableOnly)
+               public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        return DoResolve (rc);
                }
@@ -7284,19 +7368,25 @@ namespace Mono.CSharp {
 
                Expression DoResolveName (ResolveContext rc, Expression right_side)
                {
-                       Expression e = LookupNameExpression (rc, right_side == null, false);
+                       Expression e = LookupNameExpression (rc, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None);
                        if (e == null)
                                return null;
 
-                       if (right_side != null)
+                       if (right_side != null) {
+                               if (e is TypeExpr) {
+                                       e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc);
+                                       return null;
+                               }
+
                                e = e.ResolveLValue (rc, right_side);
-                       else
+                       } else {
                                e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type);
+                       }
 
                        return e;
                }
 
-               public override Expression LookupNameExpression (ResolveContext rc, bool readMode, bool invocableOnly)
+               public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
                {
                        var sn = expr as SimpleName;
                        const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type;
@@ -7309,7 +7399,7 @@ namespace Mono.CSharp {
                        //
                        using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
                                if (sn != null) {
-                                       expr = sn.LookupNameExpression (rc, true, false);
+                                       expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
 
                                        // Call resolve on expression which does have type set as we need expression type
                                        // TODO: I should probably ensure that the type is always set and leave resolve for the final
@@ -7360,7 +7450,10 @@ namespace Mono.CSharp {
                                MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
 
                        if ((expr_type.Kind & dot_kinds) == 0 || expr_type == TypeManager.void_type) {
-                               Unary.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type);
+                               if (expr_type == InternalType.Null && rc.Compiler.IsRuntimeBinder)
+                                       rc.Report.Error (Report.RuntimeErrorId, loc, "Cannot perform member binding on `null' value");
+                               else
+                                       Unary.Error_OperatorCannotBeApplied (rc, loc, ".", expr_type);
                                return null;
                        }
 
@@ -7369,7 +7462,7 @@ namespace Mono.CSharp {
                        bool errorMode = false;
                        Expression member_lookup;
                        while (true) {
-                               member_lookup = MemberLookup (errorMode ? null : rc, current_type, expr_type, Name, lookup_arity, invocableOnly, loc);
+                               member_lookup = MemberLookup (errorMode ? null : rc, current_type, expr_type, Name, lookup_arity, restrictions, loc);
                                if (member_lookup == null) {
                                        //
                                        // Try to look for extension method when member lookup failed
@@ -7416,7 +7509,7 @@ namespace Mono.CSharp {
 
                                current_type = null;
                                lookup_arity = 0;
-                               invocableOnly = false;
+                               restrictions &= ~MemberLookupRestrictions.InvocableOnly;
                                errorMode = true;
                        }
 
@@ -7542,7 +7635,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       var any_other_member = MemberLookup (null, rc.CurrentType, expr_type, Name, 0, false, loc);
+                       var any_other_member = MemberLookup (null, rc.CurrentType, expr_type, Name, 0, MemberLookupRestrictions.None, loc);
                        if (any_other_member != null) {
                                any_other_member.Error_UnexpectedKind (rc.Compiler.Report, null, "type", loc);
                                return;
@@ -8552,8 +8645,10 @@ namespace Mono.CSharp {
                                        UnsafeError (ec.Compiler.Report, loc);
                                }
 
-                               type = PointerContainer.MakeType (type);
-                               single_spec = single_spec.Next;
+                               do {
+                                       type = PointerContainer.MakeType (type);
+                                       single_spec = single_spec.Next;
+                               } while (single_spec != null && single_spec.IsPointer);
                        }
 
                        if (single_spec != null && single_spec.Dimension > 0) {
@@ -8802,9 +8897,9 @@ namespace Mono.CSharp {
                                target = new DynamicMemberBinder (Name, args, loc);
                        } else {
 
-                               var member = MemberLookup (ec, ec.CurrentType, t, Name, 0, false, loc);
+                               var member = MemberLookup (ec, ec.CurrentType, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
                                if (member == null) {
-                                       member = Expression.MemberLookup (null, ec.CurrentType, t, Name, 0, false, loc);
+                                       member = Expression.MemberLookup (null, ec.CurrentType, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
 
                                        if (member != null) {
                                                // TODO: ec.Report.SymbolRelatedToPreviousError (member);
@@ -9001,7 +9096,9 @@ namespace Mono.CSharp {
                                                initializer.Resolve (ec);
                                                throw new InternalErrorException ("This line should never be reached");
                                        } else {
-                                               if (!ec.CurrentInitializerVariable.Type.ImplementsInterface (TypeManager.ienumerable_type)) {
+                                               var t = ec.CurrentInitializerVariable.Type;
+                                               // LAMESPEC: The collection must implement IEnumerable only, no dynamic support
+                                               if (!t.ImplementsInterface (TypeManager.ienumerable_type, false) && t != InternalType.Dynamic) {
                                                        ec.Report.Error (1922, loc, "A field or property `{0}' cannot be initialized with a collection " +
                                                                "object initializer because type `{1}' does not implement `{2}' interface",
                                                                ec.CurrentInitializerVariable.GetSignatureForError (),
@@ -9202,12 +9299,6 @@ namespace Mono.CSharp {
 
                        return left_on_stack;
                }
-
-               public override bool HasInitializer {
-                       get {
-                               return !initializers.IsEmpty;
-                       }
-               }
        }
 
        public class NewAnonymousType : New
@@ -9267,8 +9358,8 @@ namespace Mono.CSharp {
                        foreach (Property p in anonymous_type.Properties)
                                init.Add (new TypeOfMethod (MemberCache.GetMember (type, p.Get.Spec), loc));
 
-                       var ctor_args = new ArrayInitializer (Arguments.Count, loc);
-                       foreach (Argument a in Arguments)
+                       var ctor_args = new ArrayInitializer (arguments.Count, loc);
+                       foreach (Argument a in arguments)
                                ctor_args.Add (a.CreateExpressionTree (ec));
 
                        Arguments args = new Arguments (3);
@@ -9293,7 +9384,7 @@ namespace Mono.CSharp {
                        }
 
                        bool error = false;
-                       Arguments = new Arguments (parameters.Count);
+                       arguments = new Arguments (parameters.Count);
                        TypeExpression [] t_args = new TypeExpression [parameters.Count];
                        for (int i = 0; i < parameters.Count; ++i) {
                                Expression e = ((AnonymousTypeParameter) parameters [i]).Resolve (ec);
@@ -9302,7 +9393,7 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               Arguments.Add (new Argument (e));
+                               arguments.Add (new Argument (e));
                                t_args [i] = new TypeExpression (e.Type, e.Location);
                        }