entry for a change in HttpResponseStream.cs
[mono.git] / mcs / mcs / expression.cs
index 81ddfd7f2c70b3a17758337ec6d74b063023beae..84980efd5f599e287b40d3b870acd2b1e9f83c56 100644 (file)
 
 namespace Mono.CSharp {
        using System;
-       using System.Collections;
+       using System.Collections.Generic;
        using System.Reflection;
        using System.Reflection.Emit;
        using System.Text;
-
-#if NET_4_0
+       using System.Linq;
        using SLE = System.Linq.Expressions;
-#endif
 
        //
        // This is an user operator expression, automatically created during
@@ -38,7 +36,7 @@ namespace Mono.CSharp {
                        this.arguments = args;
                        this.expr_tree = expr_tree;
 
-                       type = TypeManager.TypeToCoreType (((MethodInfo) mg).ReturnType);
+                       type = TypeManager.TypeToCoreType (((MethodSpec) mg).ReturnType);
                        eclass = ExprClass.Value;
                        this.loc = loc;
                }
@@ -60,7 +58,7 @@ namespace Mono.CSharp {
                        // Nothing to clone
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        //
                        // We are born fully resolved
@@ -73,12 +71,11 @@ namespace Mono.CSharp {
                        mg.EmitCall (ec, arguments);
                }
 
-#if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Call ((MethodInfo) mg, Arguments.MakeExpression (arguments, ctx));
+                       var method = ((MethodSpec) mg).MetaInfo as MethodInfo;
+                       return SLE.Expression.Call (method, Arguments.MakeExpression (arguments, ctx));
                }
-#endif
 
                public MethodGroupExpr Method {
                        get { return mg; }
@@ -99,7 +96,7 @@ namespace Mono.CSharp {
                        loc = expr.Location;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return expr.Resolve (ec);
                }
@@ -126,11 +123,11 @@ namespace Mono.CSharp {
                public Expression Expr;
                Expression enum_conversion;
 
-               public Unary (Operator op, Expression expr)
+               public Unary (Operator op, Expression expr, Location loc)
                {
                        Oper = op;
                        Expr = expr;
-                       loc = expr.Location;
+                       this.loc = loc;
                }
 
                // <summary>
@@ -213,7 +210,7 @@ namespace Mono.CSharp {
                                if (expr_type == TypeManager.uint32_type) {
                                        UIntLiteral uil = e as UIntLiteral;
                                        if (uil != null) {
-                                               if (uil.Value == 2147483648)
+                                               if (uil.Value == int.MaxValue + (uint) 1)
                                                        return new IntLiteral (int.MinValue, e.Location);
                                                return new LongLiteral (-uil.Value, e.Location);
                                        }
@@ -428,7 +425,7 @@ namespace Mono.CSharp {
                        return expr;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (Oper == Operator.AddressOf) {
                                return ResolveAddressOf (ec);
@@ -445,7 +442,7 @@ namespace Mono.CSharp {
                        }
 
                        if (TypeManager.IsNullableType (Expr.Type))
-                               return new Nullable.LiftedUnaryOperator (Oper, Expr).Resolve (ec);
+                               return new Nullable.LiftedUnaryOperator (Oper, Expr, loc).Resolve (ec);
 
                        //
                        // Attempt to use a constant folding operation.
@@ -454,7 +451,7 @@ namespace Mono.CSharp {
                        if (cexpr != null) {
                                cexpr = TryReduceConstant (ec, cexpr);
                                if (cexpr != null)
-                                       return cexpr;
+                                       return cexpr.Resolve (ec);
                        }
 
                        Expression expr = ResolveOperator (ec, Expr);
@@ -594,7 +591,6 @@ namespace Mono.CSharp {
                        throw new NotImplementedException (oper.ToString ());
                }
 
-#if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        var expr = Expr.MakeExpression (ctx);
@@ -605,13 +601,14 @@ namespace Mono.CSharp {
                                return is_checked ? SLE.Expression.NegateChecked (expr) : SLE.Expression.Negate (expr);
                        case Operator.LogicalNot:
                                return SLE.Expression.Not (expr);
+#if NET_4_0
                        case Operator.OnesComplement:
                                return SLE.Expression.OnesComplement (expr);
+#endif
                        default:
                                throw new NotImplementedException (Oper.ToString ());
                        }
                }
-#endif
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
@@ -630,7 +627,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (!TypeManager.VerifyUnManaged (Expr.Type, loc)) {
+                       if (!TypeManager.VerifyUnmanaged (ec.Compiler, Expr.Type, loc)) {
                                return null;
                        }
 
@@ -726,7 +723,7 @@ namespace Mono.CSharp {
 
                        Type[] predefined = predefined_operators [(int) Oper];
                        foreach (Type t in predefined) {
-                               Expression oper_expr = Convert.UserDefinedConversion (ec, expr, t, expr.Location, false);
+                               Expression oper_expr = Convert.UserDefinedConversion (ec, expr, t, expr.Location, false, false);
                                if (oper_expr == null)
                                        continue;
 
@@ -859,7 +856,7 @@ namespace Mono.CSharp {
                        return DoResolve (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
@@ -907,7 +904,69 @@ namespace Mono.CSharp {
        /// classes (indexers require temporary access;  overloaded require method)
        ///
        /// </remarks>
-       public class UnaryMutator : ExpressionStatement {
+       public class UnaryMutator : ExpressionStatement
+       {
+               class DynamicPostMutator : Expression, IAssignMethod
+               {
+                       LocalTemporary temp;
+                       Expression expr;
+
+                       public DynamicPostMutator (Expression expr)
+                       {
+                               this.expr = expr;
+                               this.type = expr.Type;
+                               this.loc = expr.Location;
+                       }
+
+                       public override Expression CreateExpressionTree (ResolveContext ec)
+                       {
+                               throw new NotImplementedException ("ET");
+                       }
+
+                       protected override Expression DoResolve (ResolveContext rc)
+                       {
+                               eclass = expr.eclass;
+                               return this;
+                       }
+
+                       public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+                       {
+                               expr.DoResolveLValue (ec, right_side);
+                               return DoResolve (ec);
+                       }
+
+                       public override void Emit (EmitContext ec)
+                       {
+                               temp.Emit (ec);
+                       }
+
+                       public void Emit (EmitContext ec, bool leave_copy)
+                       {
+                               throw new NotImplementedException ();
+                       }
+
+                       //
+                       // Emits target assignment using unmodified source value
+                       //
+                       public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+                       {
+                               //
+                               // Allocate temporary variable to keep original value before it's modified
+                               //
+                               temp = new LocalTemporary (type);
+                               expr.Emit (ec);
+                               temp.Store (ec);
+
+                               ((IAssignMethod) expr).EmitAssign (ec, source, false, prepare_for_load);
+
+                               if (leave_copy)
+                                       Emit (ec);
+
+                               temp.Release (ec);
+                               temp = null;
+                       }
+               }
+
                [Flags]
                public enum Mode : byte {
                        IsIncrement    = 0,
@@ -922,108 +981,26 @@ namespace Mono.CSharp {
                }
 
                Mode mode;
-               bool is_expr = false;
-               bool recurse = false;
+               bool is_expr, recurse;
 
                Expression expr;
 
-               //
-               // This is expensive for the simplest case.
-               //
-               UserOperatorCall method;
+               // Holds the real operation
+               Expression operation;
 
-               public UnaryMutator (Mode m, Expression e)
+               public UnaryMutator (Mode m, Expression e, Location loc)
                {
                        mode = m;
-                       loc = e.Location;
+                       this.loc = loc;
                        expr = e;
                }
 
-               string OperName ()
-               {
-                       return IsDecrement ?
-                               Operator.GetName (Operator.OpType.Decrement) :
-                               Operator.GetName (Operator.OpType.Increment);
-               }
-
-               /// <summary>
-               ///   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)
-               /// </summary>
-               static bool IsIncrementableNumber (Type t)
-               {
-                       return (t == TypeManager.sbyte_type) ||
-                               (t == TypeManager.byte_type) ||
-                               (t == TypeManager.short_type) ||
-                               (t == TypeManager.ushort_type) ||
-                               (t == TypeManager.int32_type) ||
-                               (t == TypeManager.uint32_type) ||
-                               (t == TypeManager.int64_type) ||
-                               (t == TypeManager.uint64_type) ||
-                               (t == TypeManager.char_type) ||
-                               (TypeManager.IsSubclassOf (t, TypeManager.enum_type)) ||
-                               (t == TypeManager.float_type) ||
-                               (t == TypeManager.double_type) ||
-                               (t.IsPointer && t != TypeManager.void_ptr_type);
-               }
-
-               Expression ResolveOperator (ResolveContext ec)
-               {
-                       type = expr.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");
-                       }
-
-                       //
-                       // Step 1: Perform Operator Overload location
-                       //
-                       MethodGroupExpr mg;
-                       string op_name;
-                       
-                       if (IsDecrement)
-                               op_name = Operator.GetMetadataName (Operator.OpType.Decrement);
-                       else
-                               op_name = Operator.GetMetadataName (Operator.OpType.Increment);
-
-                       mg = MemberLookup (ec.Compiler, ec.CurrentType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
-
-                       if (mg != null) {
-                               Arguments args = new Arguments (1);
-                               args.Add (new Argument (expr));
-                               mg = mg.OverloadResolve (ec, ref args, false, loc);
-                               if (mg == null)
-                                       return null;
-
-                               method = new UserOperatorCall (mg, args, null, loc);
-                               Convert.ImplicitConversionRequired (ec, method, type, loc);
-                               return this;
-                       }
-
-                       if (!IsIncrementableNumber (type)) {
-                               ec.Report.Error (187, loc, "No such operator '" + OperName () + "' defined for type '" +
-                                          TypeManager.CSharpName (type) + "'");
-                               return null;
-                       }
-
-                       return this;
-               }
-
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        return new SimpleAssign (this, this).CreateExpressionTree (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
                        
@@ -1031,81 +1008,26 @@ namespace Mono.CSharp {
                                return null;
 
                        if (TypeManager.IsDynamicType (expr.Type)) {
+                               //
+                               // Handle postfix unary operators using local
+                               // temporary variable
+                               //
+                               if ((mode & Mode.IsPost) != 0)
+                                       expr = new DynamicPostMutator (expr);
+
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (expr));
-                               return new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc).Resolve (ec);
+                               return new SimpleAssign (expr, new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc)).Resolve (ec);
                        }
 
-                       eclass = ExprClass.Value;
-
                        if (TypeManager.IsNullableType (expr.Type))
                                return new Nullable.LiftedUnaryMutator (mode, expr, loc).Resolve (ec);
 
+                       eclass = ExprClass.Value;
+                       type = expr.Type;
                        return ResolveOperator (ec);
                }
 
-               //
-               // Loads the proper "1" into the stack based on the type, then it emits the
-               // opcode for the operation requested
-               //
-               void LoadOneAndEmitOp (EmitContext ec, Type t)
-               {
-                       //
-                       // Measure if getting the typecode and using that is more/less efficient
-                       // that comparing types.  t.GetTypeCode() is an internal call.
-                       //
-                       ILGenerator ig = ec.ig;
-                                                    
-                       if (t == TypeManager.uint64_type || t == TypeManager.int64_type)
-                               LongConstant.EmitLong (ig, 1);
-                       else if (t == TypeManager.double_type)
-                               ig.Emit (OpCodes.Ldc_R8, 1.0);
-                       else if (t == TypeManager.float_type)
-                               ig.Emit (OpCodes.Ldc_R4, 1.0F);
-                       else if (t.IsPointer){
-                               Type et = TypeManager.GetElementType (t);
-                               int n = GetTypeSize (et);
-                               
-                               if (n == 0)
-                                       ig.Emit (OpCodes.Sizeof, et);
-                               else {
-                                       IntConstant.EmitInt (ig, n);
-                                       ig.Emit (OpCodes.Conv_I);
-                               }
-                       } else 
-                               ig.Emit (OpCodes.Ldc_I4_1);
-
-                       //
-                       // Now emit the operation
-                       //
-
-                       Binary.Operator op = (mode & Mode.IsDecrement) != 0 ? Binary.Operator.Subtraction : Binary.Operator.Addition;
-                       Binary.EmitOperatorOpcode (ec, op, t);
-
-                       if (t == TypeManager.sbyte_type){
-                               if (ec.HasSet (EmitContext.Options.CheckedScope))
-                                       ig.Emit (OpCodes.Conv_Ovf_I1);
-                               else
-                                       ig.Emit (OpCodes.Conv_I1);
-                       } else if (t == TypeManager.byte_type){
-                               if (ec.HasSet (EmitContext.Options.CheckedScope))
-                                       ig.Emit (OpCodes.Conv_Ovf_U1);
-                               else
-                                       ig.Emit (OpCodes.Conv_U1);
-                       } else if (t == TypeManager.short_type){
-                               if (ec.HasSet (EmitContext.Options.CheckedScope))
-                                       ig.Emit (OpCodes.Conv_Ovf_I2);
-                               else
-                                       ig.Emit (OpCodes.Conv_I2);
-                       } else if (t == TypeManager.ushort_type || t == TypeManager.char_type){
-                               if (ec.HasSet (EmitContext.Options.CheckedScope))
-                                       ig.Emit (OpCodes.Conv_Ovf_U2);
-                               else
-                                       ig.Emit (OpCodes.Conv_U2);
-                       }
-                       
-               }
-
                void EmitCode (EmitContext ec, bool is_expr)
                {
                        recurse = true;
@@ -1122,10 +1044,9 @@ namespace Mono.CSharp {
                        //
                        if (recurse) {
                                ((IAssignMethod) expr).Emit (ec, is_expr && (mode == Mode.PostIncrement || mode == Mode.PostDecrement));
-                               if (method == null)
-                                       LoadOneAndEmitOp (ec, expr.Type);
-                               else
-                                       ec.ig.Emit (OpCodes.Call, (MethodInfo)method.Method);
+
+                               operation.Emit (ec);
+
                                recurse = false;
                                return;
                        }
@@ -1150,27 +1071,25 @@ 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 (Type 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)
                {
-                       if (method != null)
-                               return method.MakeExpression (ctx);
-
-                       bool is_checked = ctx.HasSet (BuilderContext.Options.CheckedScope);
-                       var one = SLE.Expression.Constant (1);
-                       var left = expr.MakeExpression (ctx);
-
-                       SLE.Expression binary;
-                       if (IsDecrement) {
-                               binary = is_checked ? SLE.Expression.SubtractChecked (left, one) : SLE.Expression.Subtract (left, one);
-                       } else {
-                               binary = is_checked ? SLE.Expression.AddChecked (left, one) : SLE.Expression.Add (left, one);
-                       }
-
                        var target = ((RuntimeValueExpression) expr).MetaObject.Expression;
-                       binary = SLE.Expression.Convert (binary, target.Type);
-
-                       return SLE.Expression.Assign (target, binary);
+                       var source = SLE.Expression.Convert (operation.MakeExpression (ctx), target.Type);
+                       return SLE.Expression.Assign (target, source);
                }
 #endif
 
@@ -1180,6 +1099,78 @@ namespace Mono.CSharp {
 
                        target.expr = expr.Clone (clonectx);
                }
+
+               Expression ResolveOperator (ResolveContext 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
+                       //
+                       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
+                       //
+                       MethodGroupExpr mg;
+                       string op_name;
+
+                       if (IsDecrement)
+                               op_name = Operator.GetMetadataName (Operator.OpType.Decrement);
+                       else
+                               op_name = Operator.GetMetadataName (Operator.OpType.Increment);
+
+                       mg = MemberLookup (ec.Compiler, ec.CurrentType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+
+                       if (mg != null) {
+                               Arguments args = new Arguments (1);
+                               args.Add (new Argument (expr));
+                               mg = mg.OverloadResolve (ec, ref args, false, loc);
+                               if (mg == null)
+                                       return null;
+
+                               args[0].Expr = operation;
+                               operation = new UserOperatorCall (mg, 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);
+
+                       Unary.Error_OperatorCannotBeApplied (ec, loc, name, type);
+                       return null;
+               }
        }
 
        /// <summary>
@@ -1208,7 +1199,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        probe_type_expr = ProbeType.ResolveAsTypeTerminal (ec, false);
                        if (probe_type_expr == null)
@@ -1311,10 +1302,10 @@ namespace Mono.CSharp {
                                ec.Report.Warning (184, 1, loc, "The given expression is never of the provided (`{0}') type",
                                        TypeManager.CSharpName (probe_type_expr.Type));
 
-                       return ReducedExpression.Create (new BoolConstant (result, loc), this);
+                       return ReducedExpression.Create (new BoolConstant (result, loc).Resolve (ec), this);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (base.DoResolve (ec) == null)
                                return null;
@@ -1449,12 +1440,8 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Unbox_Any, type);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       // Because expr is modified
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-
                        if (resolved_type == null) {
                                resolved_type = base.DoResolve (ec);
 
@@ -1552,7 +1539,7 @@ namespace Mono.CSharp {
                        get { return target_type; }
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
@@ -1583,7 +1570,7 @@ namespace Mono.CSharp {
                        } else if (TypeManager.IsDynamicType (expr.Type)) {
                                Arguments arg = new Arguments (1);
                                arg.Add (new Argument (expr));
-                               return new DynamicConversion (type, true, arg, loc).Resolve (ec);
+                               return new DynamicConversion (type, CSharpBinderFlags.ConvertExplicit, arg, loc).Resolve (ec);
                        }
 
                        expr = Convert.ExplicitConversion (ec, expr, type, loc);
@@ -1601,17 +1588,25 @@ namespace Mono.CSharp {
 
        public class ImplicitCast : ShimExpression
        {
-               public ImplicitCast (Expression expr, Type target)
+               bool arrayAccess;
+
+               public ImplicitCast (Expression expr, Type target, bool arrayAccess)
                        : base (expr)
                {
                        this.loc = expr.Location;
                        this.type = target;
+                       this.arrayAccess = arrayAccess;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
-                       if (expr != null)
+                       if (expr == null)
+                               return null;
+
+                       if (arrayAccess)
+                               expr = ConvertExpressionToArrayIndex (ec, expr);
+                       else
                                expr = Convert.ImplicitConversionRequired (ec, expr, type, loc);
 
                        return expr;
@@ -1623,20 +1618,6 @@ namespace Mono.CSharp {
        //
        public class DefaultValueExpression : Expression
        {
-               sealed class DefaultValueNullLiteral : NullLiteral
-               {
-                       public DefaultValueNullLiteral (DefaultValueExpression expr)
-                               : base (expr.type, expr.loc)
-                       {
-                       }
-
-                       public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type t, bool expl)
-                       {
-                               Error_ValueCannotBeConvertedCore (ec, loc, t, expl);
-                       }
-               }
-
-
                Expression expr;
 
                public DefaultValueExpression (Expression expr, Location loc)
@@ -1653,7 +1634,7 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Constant", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
                        if (texpr == null)
@@ -1666,14 +1647,14 @@ namespace Mono.CSharp {
                        }
 
                        if (type.IsPointer)
-                               return new NullLiteral (Location).ConvertImplicitly (type);
+                               return new NullLiteral (Location).ConvertImplicitly (ec, type);
 
                        if (TypeManager.IsReferenceType (type))
-                               return new DefaultValueNullLiteral (this);
+                               return new NullConstant (type, loc);
 
                        Constant c = New.Constantify (type);
                        if (c != null)
-                               return c;
+                               return c.Resolve (ec);
 
                        eclass = ExprClass.Variable;
                        return this;
@@ -1706,7 +1687,6 @@ namespace Mono.CSharp {
        /// </summary>
        public class Binary : Expression, IDynamicBinder
        {
-
                protected class PredefinedOperator {
                        protected readonly Type left;
                        protected readonly Type right;
@@ -1754,6 +1734,24 @@ namespace Mono.CSharp {
                                if (left == TypeManager.decimal_type)
                                        return b.ResolveUserOperator (ec, b.left.Type, b.right.Type);
 
+                               var c = b.right as Constant;
+                               if (c != null) {
+                                       if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.BitwiseOr || b.oper == Operator.Subtraction))
+                                               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);
+                                       return b;
+                               }
+
+                               c = b.left as Constant;
+                               if (c != null) {
+                                       if (c.IsDefaultValue && (b.oper == Operator.Addition || b.oper == Operator.BitwiseOr))
+                                               return ReducedExpression.Create (b.right, b).Resolve (ec);
+                                       if (b.oper == Operator.Multiply && c.IsOneInteger)
+                                               return ReducedExpression.Create (b.right, b).Resolve (ec);
+                                       return b;
+                               }
+
                                return b;
                        }
 
@@ -1828,7 +1826,7 @@ namespace Mono.CSharp {
                                //
                                // Start a new concat expression using converted expression
                                //
-                               return new StringConcat (b.loc, b.left, b.right).Resolve (ec);
+                               return StringConcat.Create (ec, b.left, b.right, b.loc);
                        }
                }
 
@@ -1850,13 +1848,21 @@ namespace Mono.CSharp {
                                // b = b.left >> b.right & (0x1f|0x3f)
                                //
                                b.right = new Binary (Operator.BitwiseAnd,
-                                       b.right, new IntConstant (right_mask, b.right.Location)).Resolve (ec);
+                                       b.right, new IntConstant (right_mask, b.right.Location), b.loc).Resolve (ec);
 
                                //
                                // Expression tree representation does not use & mask
                                //
                                b.right = ReducedExpression.Create (b.right, expr_tree_expr).Resolve (ec);
                                b.type = ReturnType;
+
+                               //
+                               // Optimize shift by 0
+                               //
+                               var c = b.right as Constant;
+                               if (c != null && c.IsDefaultValue)
+                                       return ReducedExpression.Create (b.left, b).Resolve (ec);
+
                                return b;
                        }
                }
@@ -1975,18 +1981,18 @@ namespace Mono.CSharp {
                static PredefinedOperator [] standard_operators;
                static PredefinedOperator [] pointer_operators;
                
-               public Binary (Operator oper, Expression left, Expression right, bool isCompound)
-                       : this (oper, left, right)
+               public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc)
+                       : this (oper, left, right, loc)
                {
                        this.is_compound = isCompound;
                }
 
-               public Binary (Operator oper, Expression left, Expression right)
+               public Binary (Operator oper, Expression left, Expression right, Location loc)
                {
                        this.oper = oper;
                        this.left = left;
                        this.right = right;
-                       this.loc = left.Location;
+                       this.loc = loc;
                }
 
                public Operator Oper {
@@ -2069,7 +2075,7 @@ namespace Mono.CSharp {
 
                public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, Operator oper, Location loc)
                {
-                       new Binary (oper, left, right).Error_OperatorCannotBeApplied (ec, left, right);
+                       new Binary (oper, left, right, loc).Error_OperatorCannotBeApplied (ec, left, right);
                }
 
                public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, string oper, Location loc)
@@ -2455,7 +2461,7 @@ namespace Mono.CSharp {
 
                static void CreatePointerOperatorsTable ()
                {
-                       ArrayList temp = new ArrayList ();
+                       var temp = new List<PredefinedPointerOperator> ();
 
                        //
                        // Pointer arithmetic:
@@ -2486,12 +2492,12 @@ namespace Mono.CSharp {
                        //
                        temp.Add (new PredefinedPointerOperator (null, Operator.SubtractionMask, TypeManager.int64_type));
 
-                       pointer_operators = (PredefinedOperator []) temp.ToArray (typeof (PredefinedOperator));
+                       pointer_operators = temp.ToArray ();
                }
 
                static void CreateStandardOperatorsTable ()
                {
-                       ArrayList temp = new ArrayList ();
+                       var temp = new List<PredefinedOperator> ();
                        Type bool_type = TypeManager.bool_type;
 
                        temp.Add (new PredefinedOperator (TypeManager.int32_type, Operator.ArithmeticMask | Operator.BitwiseMask));
@@ -2524,20 +2530,20 @@ namespace Mono.CSharp {
                        temp.Add (new PredefinedShiftOperator (TypeManager.int64_type, Operator.ShiftMask));
                        temp.Add (new PredefinedShiftOperator (TypeManager.uint64_type, Operator.ShiftMask));
 
-                       standard_operators = (PredefinedOperator []) temp.ToArray (typeof (PredefinedOperator));
+                       standard_operators = temp.ToArray ();
                }
 
                //
                // Rules used during binary numeric promotion
                //
-               static bool DoNumericPromotion (ref Expression prim_expr, ref Expression second_expr, Type type)
+               static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, Type type)
                {
                        Expression temp;
                        Type etype;
 
                        Constant c = prim_expr as Constant;
                        if (c != null) {
-                               temp = c.ConvertImplicitly (type);
+                               temp = c.ConvertImplicitly (rc, type);
                                if (temp != null) {
                                        prim_expr = temp;
                                        return true;
@@ -2552,7 +2558,7 @@ namespace Mono.CSharp {
                                        if (type != second_expr.Type) {
                                                c = second_expr as Constant;
                                                if (c != null)
-                                                       temp = c.ConvertImplicitly (type);
+                                                       temp = c.ConvertImplicitly (rc, type);
                                                else
                                                        temp = Convert.ImplicitNumericConversion (second_expr, type);
                                                if (temp == null)
@@ -2565,7 +2571,7 @@ namespace Mono.CSharp {
                                // A compile-time error occurs if the other operand is of type sbyte, short, int, or long
                                //
                                if (type == TypeManager.int32_type || type == TypeManager.int64_type ||
-                                       type == TypeManager.sbyte_type || type == TypeManager.sbyte_type)
+                                       type == TypeManager.short_type || type == TypeManager.sbyte_type)
                                        return false;
                        }
 
@@ -2588,17 +2594,17 @@ namespace Mono.CSharp {
 
                        foreach (Type t in ConstantFold.binary_promotions) {
                                if (t == ltype)
-                                       return t == rtype || DoNumericPromotion (ref right, ref left, t);
+                                       return t == rtype || DoNumericPromotion (ec, ref right, ref left, t);
 
                                if (t == rtype)
-                                       return t == ltype || DoNumericPromotion (ref left, ref right, t);
+                                       return t == ltype || DoNumericPromotion (ec, ref left, ref right, t);
                        }
 
                        Type int32 = TypeManager.int32_type;
                        if (ltype != int32) {
                                Constant c = left as Constant;
                                if (c != null)
-                                       temp = c.ConvertImplicitly (int32);
+                                       temp = c.ConvertImplicitly (ec, int32);
                                else
                                        temp = Convert.ImplicitNumericConversion (left, int32);
 
@@ -2610,7 +2616,7 @@ namespace Mono.CSharp {
                        if (rtype != int32) {
                                Constant c = right as Constant;
                                if (c != null)
-                                       temp = c.ConvertImplicitly (int32);
+                                       temp = c.ConvertImplicitly (ec, int32);
                                else
                                        temp = Convert.ImplicitNumericConversion (right, int32);
 
@@ -2622,7 +2628,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (left == null)
                                return null;
@@ -2672,26 +2678,12 @@ namespace Mono.CSharp {
 
                        if (rc != null && lc != null) {
                                int prev_e = ec.Report.Errors;
-                               Expression e = ConstantFold.BinaryFold (
-                                       ec, oper, lc, rc, loc);
+                               Expression e = ConstantFold.BinaryFold (ec, oper, lc, rc, loc);
+                               if (e != null)
+                                       e = e.Resolve (ec);
+
                                if (e != null || ec.Report.Errors != prev_e)
                                        return e;
-                       } else if ((oper == Operator.BitwiseAnd || oper == Operator.LogicalAnd) && !TypeManager.IsDynamicType (left.Type) &&
-                                       ((lc != null && lc.IsDefaultValue && !(lc is NullLiteral)) || (rc != null && rc.IsDefaultValue && !(rc is NullLiteral)))) {
-
-                               if ((ResolveOperator (ec)) == null) {
-                                       Error_OperatorCannotBeApplied (ec, left, right);
-                                       return null;
-                               }
-
-                               //
-                               // The result is a constant with side-effect
-                               //
-                               Constant side_effect = rc == null ?
-                                       new SideEffectConstant (lc, right, loc) :
-                                       new SideEffectConstant (rc, left, loc);
-
-                               return ReducedExpression.Create (side_effect, this);
                        }
 
                        // Comparison warnings
@@ -2735,7 +2727,6 @@ namespace Mono.CSharp {
                        return expr;
                }
 
-#if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        var le = left.MakeExpression (ctx);
@@ -2783,7 +2774,6 @@ namespace Mono.CSharp {
                                throw new NotImplementedException (oper.ToString ());
                        }
                }
-#endif
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
@@ -2825,7 +2815,7 @@ namespace Mono.CSharp {
                        if (is_equality)
                                return ResolveUserOperator (ec, l, r);
 
-                       MethodInfo method;
+                       MethodSpec method;
                        Arguments args = new Arguments (2);
                        args.Add (new Argument (left));
                        args.Add (new Argument (right));
@@ -2846,7 +2836,7 @@ namespace Mono.CSharp {
                                method = TypeManager.delegate_remove_delegate_delegate;
                        }
 
-                       MethodGroupExpr mg = new MethodGroupExpr (new MemberInfo [] { method }, TypeManager.delegate_type, loc);
+                       MethodGroupExpr mg = new MethodGroupExpr (new [] { method }, TypeManager.delegate_type, loc);
                        mg = mg.OverloadResolve (ec, ref args, false, loc);
 
                        return new ClassCast (new UserOperatorCall (mg, args, CreateExpressionTree, loc), l);
@@ -2905,12 +2895,12 @@ namespace Mono.CSharp {
                                underlying_type = TypeManager.GetEnumUnderlyingType (ltype);
 
                                if (left is Constant)
-                                       left = ((Constant) left).ConvertExplicitly (false, underlying_type);
+                                       left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
                                else
                                        left = EmptyCast.Create (left, underlying_type);
 
                                if (right is Constant)
-                                       right = ((Constant) right).ConvertExplicitly (false, underlying_type);
+                                       right = ((Constant) right).ConvertExplicitly (false, underlying_type).Resolve (ec);
                                else
                                        right = EmptyCast.Create (right, underlying_type);
                        } else if (lenum) {
@@ -2928,7 +2918,7 @@ namespace Mono.CSharp {
                                }
 
                                if (left is Constant)
-                                       left = ((Constant) left).ConvertExplicitly (false, underlying_type);
+                                       left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
                                else
                                        left = EmptyCast.Create (left, underlying_type);
 
@@ -2947,7 +2937,7 @@ namespace Mono.CSharp {
                                }
 
                                if (right is Constant)
-                                       right = ((Constant) right).ConvertExplicitly (false, underlying_type);
+                                       right = ((Constant) right).ConvertExplicitly (false, underlying_type).Resolve (ec);
                                else
                                        right = EmptyCast.Create (right, underlying_type);
 
@@ -3205,7 +3195,7 @@ namespace Mono.CSharp {
 
                                if (best_operator == null) {
                                        ec.Report.Error (34, loc, "Operator `{0}' is ambiguous on operands of type `{1}' and `{2}'",
-                                               OperName (oper), left.GetSignatureForError (), right.GetSignatureForError ());
+                                               OperName (oper), TypeManager.CSharpName (l), TypeManager.CSharpName (r));
 
                                        best_operator = po;
                                        break;
@@ -3216,6 +3206,25 @@ namespace Mono.CSharp {
                                return null;
 
                        Expression expr = best_operator.ConvertResult (ec, this);
+
+                       //
+                       // Optimize &/&& constant expressions with 0 value
+                       //
+                       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)) {
+                                       //
+                                       // The result is a constant with side-effect
+                                       //
+                                       Constant side_effect = rc == null ?
+                                               new SideEffectConstant (lc, right, loc) :
+                                               new SideEffectConstant (rc, left, loc);
+
+                                       return ReducedExpression.Create (side_effect.Resolve (ec), expr);
+                               }
+                       }
+
                        if (enum_type == null)
                                return expr;
 
@@ -3304,9 +3313,9 @@ namespace Mono.CSharp {
                                                (right is NullLiteral && IsBuildInEqualityOperator (l))) {
                                                type = TypeManager.bool_type;
                                                if (left is NullLiteral || right is NullLiteral)
-                                                       oper_expr = ReducedExpression.Create (this, oper_expr).Resolve (ec);
+                                                       oper_expr = ReducedExpression.Create (this, oper_expr);
                                        } else if (l != r) {
-                                               MethodInfo mi = (MethodInfo) union;
+                                               var mi = union.BestCandidate;
                                                
                                                //
                                                // Two System.Delegate(s) are never equal
@@ -3624,20 +3633,19 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       left.Emit (ec);
-
                        //
-                       // Optimize zero-based operations
+                       // Optimize zero-based operations which cannot be optimized at expression level
                        //
-                       // TODO: Implement more optimizations, but it should probably go to PredefinedOperators
-                       //
-                       if ((oper & Operator.ShiftMask) != 0 || oper == Operator.Addition || oper == Operator.Subtraction) {
-                               Constant rc = right as Constant;
-                               if (rc != null && rc.IsDefaultValue) {
+                       if (oper == Operator.Subtraction) {
+                               var lc = left as IntegralConstant;
+                               if (lc != null && lc.IsDefaultValue) {
+                                       right.Emit (ec);
+                                       ig.Emit (OpCodes.Neg);
                                        return;
                                }
                        }
 
+                       left.Emit (ec);
                        right.Emit (ec);
                        EmitOperatorOpcode (ec, oper, l);
 
@@ -3675,16 +3683,19 @@ namespace Mono.CSharp {
                        MemberAccess sle = new MemberAccess (new MemberAccess (
                                new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc);
 
-                       MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace (loc);
+                       CSharpBinderFlags flags = 0;
+                       if (ec.HasSet (ResolveContext.Options.CheckedScope))
+                               flags = CSharpBinderFlags.CheckedContext;
 
-                       binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), GetOperatorExpressionTypeName (), loc)));
-                       binder_args.Add (new Argument (new BoolLiteral (ec.HasSet (ResolveContext.Options.CheckedScope), loc)));
+                       if ((oper & Operator.LogicalMask) != 0)
+                               flags |= CSharpBinderFlags.BinaryOperationLogical;
 
-                       bool member_access = left is DynamicMemberBinder || right is DynamicMemberBinder;
-                       binder_args.Add (new Argument (new BoolLiteral (member_access, loc)));
-                       binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (), loc)));
+                       binder_args.Add (new Argument (new EnumConstant (new IntLiteral ((int) flags, loc), TypeManager.binder_flags)));
+                       binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), GetOperatorExpressionTypeName (), loc)));
+                       binder_args.Add (new Argument (new TypeOf (new TypeExpression (ec.CurrentType, loc), loc)));                                                                    
+                       binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", args.CreateDynamicBinderArguments (ec), loc)));
 
-                       return new New (new MemberAccess (binder, "CSharpBinaryOperationBinder", loc), binder_args, loc);
+                       return new Invocation (DynamicExpressionStatement.GetBinder ("BinaryOperation", loc), binder_args);
                }
                
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -3793,15 +3804,24 @@ namespace Mono.CSharp {
        public class StringConcat : Expression {
                Arguments arguments;
                
-               public StringConcat (Location loc, Expression left, Expression right)
+               public StringConcat (Expression left, Expression right, Location loc)
                {
                        this.loc = loc;
                        type = TypeManager.string_type;
                        eclass = ExprClass.Value;
 
                        arguments = new Arguments (2);
-                       Append (left);
-                       Append (right);
+               }
+
+               public static StringConcat Create (ResolveContext rc, Expression left, Expression right, Location loc)
+               {
+                       if (left.eclass == ExprClass.Unresolved || right.eclass == ExprClass.Unresolved)
+                               throw new ArgumentException ();
+
+                       var s = new StringConcat (left, right, loc);
+                       s.Append (rc, left);
+                       s.Append (rc, right);
+                       return s;
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -3838,16 +3858,16 @@ namespace Mono.CSharp {
                        if (++pos == arguments.Count)
                                return expr;
 
-                       left = new Argument (new EmptyExpression (((MethodInfo)method).ReturnType));
+                       left = new Argument (new EmptyExpression (method.BestCandidate.ReturnType));
                        return CreateExpressionAddCall (ec, left, expr, pos);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return this;
                }
                
-               public void Append (Expression operand)
+               void Append (ResolveContext rc, Expression operand)
                {
                        //
                        // Constant folding
@@ -3859,7 +3879,7 @@ namespace Mono.CSharp {
                                        StringConstant last_expr_constant = last_argument.Expr as StringConstant;
                                        if (last_expr_constant != null) {
                                                last_argument.Expr = new StringConstant (
-                                                       last_expr_constant.Value + sc.Value, sc.Location);
+                                                       last_expr_constant.Value + sc.Value, sc.Location).Resolve (rc);
                                                return;
                                        }
                                }
@@ -3890,7 +3910,6 @@ namespace Mono.CSharp {
                                concat.Emit (ec);
                }
 
-#if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        if (arguments.Count != 2)
@@ -3899,7 +3918,6 @@ namespace Mono.CSharp {
                        var concat = TypeManager.string_type.GetMethod ("Concat", new[] { typeof (object), typeof (object) });
                        return SLE.Expression.Add (arguments[0].Expr.MakeExpression (ctx), arguments[1].Expr.MakeExpression (ctx), concat);
                }
-#endif
                
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
@@ -3919,17 +3937,18 @@ namespace Mono.CSharp {
                        : base (oper_method, arguments, expr_tree, loc)
                {
                        this.is_and = is_and;
+                       eclass = ExprClass.Unresolved;
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       MethodInfo method = (MethodInfo)mg;
+                       var method = mg.BestCandidate;
                        type = TypeManager.TypeToCoreType (method.ReturnType);
-                       AParametersCollection pd = TypeManager.GetParameterData (method);
+                       AParametersCollection pd = method.Parameters;
                        if (!TypeManager.IsEqual (type, type) || !TypeManager.IsEqual (type, pd.Types [0]) || !TypeManager.IsEqual (type, pd.Types [1])) {
                                ec.Report.Error (217, loc,
                                        "A user-defined operator `{0}' must have parameters and return values of the same type in order to be applicable as a short circuit operator",
-                                       TypeManager.CSharpSignature (method));
+                                       TypeManager.CSharpSignature (method.MetaInfo));
                                return null;
                        }
 
@@ -3939,7 +3958,7 @@ namespace Mono.CSharp {
                        if (op_true == null || op_false == null) {
                                ec.Report.Error (218, loc,
                                        "The type `{0}' must have operator `true' and operator `false' defined when `{1}' is used as a short circuit operator",
-                                       TypeManager.CSharpName (type), TypeManager.CSharpSignature (method));
+                                       TypeManager.CSharpName (type), TypeManager.CSharpSignature (method.MetaInfo));
                                return null;
                        }
 
@@ -3988,7 +4007,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        eclass = ExprClass.Variable;
                        
@@ -4012,7 +4031,7 @@ namespace Mono.CSharp {
                        } else {
                                FieldExpr fe = left as FieldExpr;
                                if (fe != null)
-                                       element = AttributeTester.GetFixedBuffer (fe.FieldInfo).ElementType;
+                                       element = ((FixedFieldSpec) (fe.Spec)).ElementType;
                                else
                                        element = op_type;
                        }
@@ -4054,7 +4073,7 @@ namespace Mono.CSharp {
 
                                left.Emit (ec);
 
-                               Constant right_const = right as Constant;
+                               var right_const = right as Constant;
                                if (right_const != null) {
                                        //
                                        // Optimize 0-based arithmetic
@@ -4062,16 +4081,16 @@ namespace Mono.CSharp {
                                        if (right_const.IsDefaultValue)
                                                return;
 
-                                       if (size != 0) {
-                                               // TODO: Should be the checks resolve context sensitive?
-                                               ResolveContext rc = new ResolveContext (ec.MemberContext);
-                                               right = ConstantFold.BinaryFold (rc, Binary.Operator.Multiply, new IntConstant (size, right.Location), right_const, loc);
-                                               if (right == null)
-                                                       return;
-                                       } else {
-                                               ig.Emit (OpCodes.Sizeof, element);
-                                               right = EmptyExpression.Null;
-                                       }
+                                       if (size != 0)
+                                               right = new IntConstant (size, right.Location);
+                                       else
+                                               right = new SizeOf (new TypeExpression (element, right.Location), right.Location);
+                                       
+                                       // TODO: Should be the checks resolve context sensitive?
+                                       ResolveContext rc = new ResolveContext (ec.MemberContext, ResolveContext.Options.UnsafeScope);
+                                       right = new Binary (Binary.Operator.Multiply, right, right_const, loc).Resolve (rc);
+                                       if (right == null)
+                                               return;
                                }
 
                                right.Emit (ec);
@@ -4109,30 +4128,22 @@ namespace Mono.CSharp {
        // A boolean-expression is an expression that yields a result
        // of type bool
        //
-       public class BooleanExpression : Expression
+       public class BooleanExpression : ShimExpression
        {
-               Expression expr;
-
                public BooleanExpression (Expression expr)
+                       : base (expr)
                {
-                       this.expr = expr;
                        this.loc = expr.Location;
                }
 
-               protected override void CloneTo (CloneContext clonectx, Expression t)
-               {
-                       BooleanExpression target = (BooleanExpression) t;
-                       target.expr = expr.Clone (clonectx);
-               }
-
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        // TODO: We should emit IsTrue (v4) instead of direct user operator
                        // call but that would break csc compatibility
-                       throw new NotSupportedException ();
+                       return base.CreateExpressionTree (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        // A boolean-expression is required to be of a type
                        // that can be implicitly converted to bool or of
@@ -4144,7 +4155,7 @@ namespace Mono.CSharp {
 
                        Assign ass = expr as Assign;
                        if (ass != null && ass.Source is Constant) {
-                               ec.Report.Warning (665, 3, expr.Location,
+                               ec.Report.Warning (665, 3, loc,
                                        "Assignment in conditional expression is always constant. Did you mean to use `==' instead ?");
                        }
 
@@ -4173,11 +4184,6 @@ namespace Mono.CSharp {
 
                        return converted;
                }
-
-               public override void Emit (EmitContext ec)
-               {
-                       throw new InternalErrorException ("Should not be reached");
-               }
        }
        
        /// <summary>
@@ -4221,7 +4227,7 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Condition", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
                        true_expr = true_expr.Resolve (ec);
@@ -4243,14 +4249,12 @@ namespace Mono.CSharp {
                                Expression conv = Convert.ImplicitConversion (ec, true_expr, false_type, loc);
                                if (conv != null) {
                                        //
-                                       // Check if both can convert implicitl to each other's type
+                                       // Check if both can convert implicitly to each other's type
                                        //
                                        if (Convert.ImplicitConversion (ec, false_expr, true_type, loc) != null) {
-                                               ec.Report.Error (172, loc,
-                                                          "Can not compute type of conditional expression " +
-                                                          "as `" + TypeManager.CSharpName (true_expr.Type) +
-                                                          "' and `" + TypeManager.CSharpName (false_expr.Type) +
-                                                          "' convert implicitly to each other");
+                                               ec.Report.Error (172, true_expr.Location,
+                                                       "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other",
+                                                       TypeManager.CSharpName (true_type), TypeManager.CSharpName (false_type));
                                                return null;
                                        }
                                        type = false_type;
@@ -4258,9 +4262,9 @@ namespace Mono.CSharp {
                                } else if ((conv = Convert.ImplicitConversion (ec, false_expr, true_type, loc)) != null) {
                                        false_expr = conv;
                                } else {
-                                       ec.Report.Error (173, loc,
+                                       ec.Report.Error (173, true_expr.Location,
                                                "Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'",
-                                               true_expr.GetSignatureForError (), false_expr.GetSignatureForError ());
+                                               TypeManager.CSharpName (true_type), TypeManager.CSharpName (false_type));
                                        return null;
                                }
                        }                       
@@ -4342,7 +4346,7 @@ namespace Mono.CSharp {
                public abstract VariableInfo VariableInfo { get; }
                #endregion
 
-               public void AddressOf (EmitContext ec, AddressOp mode)
+               public virtual void AddressOf (EmitContext ec, AddressOp mode)
                {
                        HoistedVariable hv = GetHoistedVariable (ec);
                        if (hv != null) {
@@ -4363,6 +4367,11 @@ namespace Mono.CSharp {
                        return GetHoistedVariable (ec.CurrentAnonymousMethod);
                }
 
+               public override string GetSignatureForError ()
+               {
+                       return Name;
+               }
+
                public override void Emit (EmitContext ec)
                {
                        Emit (ec, false);
@@ -4474,7 +4483,6 @@ namespace Mono.CSharp {
                public Block Block;
                public LocalInfo local_info;
                bool is_readonly;
-               bool resolved;  // TODO: merge with eclass
 
                public LocalVariableReference (Block block, string name, Location l)
                {
@@ -4501,7 +4509,7 @@ namespace Mono.CSharp {
 
                public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
                {
-                       return local_info.HoistedVariableReference;
+                       return local_info.HoistedVariant;
                }
 
                //              
@@ -4547,7 +4555,7 @@ namespace Mono.CSharp {
                {
                        HoistedVariable hv = GetHoistedVariable (ec);
                        if (hv != null)
-                               return hv.CreateExpressionTree (ec);
+                               return hv.CreateExpressionTree ();
 
                        Arguments arg = new Arguments (1);
                        arg.Add (new Argument (this));
@@ -4556,8 +4564,6 @@ namespace Mono.CSharp {
 
                Expression DoResolveBase (ResolveContext ec)
                {
-                       type = local_info.VariableType;
-
                        Expression e = Block.GetConstantExpression (Name);
                        if (e != null)
                                return e.Resolve (ec);
@@ -4578,16 +4584,13 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       resolved |= ec.DoFlowAnalysis;
                        eclass = ExprClass.Variable;
+                       type = local_info.VariableType;
                        return this;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (resolved)
-                               return this;
-
                        ResolveLocalInfo ();
                        local_info.Used = true;
 
@@ -4605,7 +4608,7 @@ namespace Mono.CSharp {
                        ResolveLocalInfo ();
 
                        // is out param
-                       if (right_side == EmptyExpression.OutAccess)
+                       if (right_side == EmptyExpression.OutAccess.Instance)
                                local_info.Used = true;
 
                        // Infer implicitly typed local variable
@@ -4621,7 +4624,7 @@ namespace Mono.CSharp {
                        if (is_readonly) {
                                int code;
                                string msg;
-                               if (right_side == EmptyExpression.OutAccess) {
+                               if (right_side == EmptyExpression.OutAccess.Instance) {
                                        code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
                                } else if (right_side == EmptyExpression.LValueMemberAccess) {
                                        code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'";
@@ -4696,7 +4699,7 @@ namespace Mono.CSharp {
 
                public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
                {
-                       return pi.Parameter.HoistedVariableReference;
+                       return pi.Parameter.HoistedVariant;
                }
 
                //
@@ -4758,15 +4761,16 @@ namespace Mono.CSharp {
 
                        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;
 
                                        //
-                                       // Skip closest anonymous method parameters
+                                       // Don't capture local parameters
                                        //
-                                       if (b == ec.CurrentBlock && !am.IsIterator)
+                                       if (b == ec.CurrentBlock.Toplevel && !am.IsIterator)
                                                return true;
 
                                        if (IsRef) {
@@ -4775,20 +4779,18 @@ namespace Mono.CSharp {
                                                        Name, am.ContainerType);
                                        }
 
-                                       b = null;
-                                       break;
-                               }
+                                       if (pi.Parameter.HasAddressTaken)
+                                               AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, this, loc);
 
-                               if (b != null)
-                                       b = b.Toplevel.Parent;
-                       }
+                                       if (ec.IsVariableCapturingRequired && !b.Toplevel.IsExpressionTree) {
+                                               AnonymousMethodStorey storey = pi.Block.CreateAnonymousMethodStorey (ec);
+                                               storey.CaptureParameter (ec, this);
+                                       }
 
-                       if (pi.Parameter.HasAddressTaken)
-                               AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, this, loc);
+                                       return true;
+                               }
 
-                       if (ec.IsVariableCapturingRequired) {
-                               AnonymousMethodStorey storey = pi.Block.CreateAnonymousMethodStorey (ec);
-                               storey.CaptureParameter (ec, this);
+                               b = b.Parent;
                        }
 
                        return true;
@@ -4807,6 +4809,19 @@ namespace Mono.CSharp {
 
                        return Name == pr.Name;
                }
+
+               public override void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       //
+                       // ParameterReferences might already be a reference
+                       //
+                       if (IsRef) {
+                               EmitLoad (ec);
+                               return;
+                       }
+
+                       base.AddressOf (ec, mode);
+               }
                
                protected override void CloneTo (CloneContext clonectx, Expression target)
                {
@@ -4817,7 +4832,7 @@ namespace Mono.CSharp {
                {
                        HoistedVariable hv = GetHoistedVariable (ec);
                        if (hv != null)
-                               return hv.CreateExpressionTree (ec);
+                               return hv.CreateExpressionTree ();
 
                        return Parameter.ExpressionTreeVariableReference ();
                }
@@ -4834,7 +4849,7 @@ namespace Mono.CSharp {
                // the type as it is expected, but when we generate the code, we generate
                // the alternate kind of code.
                //
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (!DoResolveBase (ec))
                                return null;
@@ -4914,22 +4929,11 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
-                       Arguments args;
-
-                       //
-                       // Special conversion for nested expression trees
-                       //
-                       if (TypeManager.DropGenericTypeArguments (type) == TypeManager.expression_type) {
-                               args = new Arguments (1);
-                               args.Add (new Argument (this));
-                               return CreateExpressionFactoryCall (ec, "Quote", args);
-                       }
-
                        Expression instance = mg.IsInstance ?
                                mg.InstanceExpression.CreateExpressionTree (ec) :
                                new NullLiteral (loc);
 
-                       args = Arguments.CreateForExpressionTree (ec, arguments,
+                       var args = Arguments.CreateForExpressionTree (ec, arguments,
                                instance,
                                mg.CreateExpressionTree (ec));
 
@@ -4939,14 +4943,10 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Call", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       // Don't resolve already resolved expression
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-                       
-                       Expression expr_resolved = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-                       if (expr_resolved == null)
+                       Expression member_expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       if (member_expr == null)
                                return null;
 
                        //
@@ -4956,80 +4956,49 @@ namespace Mono.CSharp {
                        if (arguments != null && !arguments_resolved)
                                arguments.Resolve (ec, out dynamic_arg);
 
-                       Type expr_type = expr_resolved.Type;
-                       mg = expr_resolved as MethodGroupExpr;
-
-                       if (dynamic_arg || TypeManager.IsDynamicType (expr_type)) {
-                               Arguments args;
-                               DynamicMemberBinder dmb = expr_resolved as DynamicMemberBinder;
-                               if (dmb != null) {
-                                       args = dmb.Arguments;
-                                       if (arguments != null)
-                                               args.AddRange (arguments);
-                               } else if (mg == null) {
-                                       if (arguments == null)
-                                               args = new Arguments (1);
-                                       else
-                                               args = arguments;
+                       Type expr_type = member_expr.Type;
+                       mg = member_expr as MethodGroupExpr;
 
-                                       args.Insert (0, new Argument (expr_resolved));
-                                       expr = null;
-                               } else {
-                                       if (mg.IsBase) {
-                                               ec.Report.Error (1971, loc,
-                                                       "The base call to method `{0}' cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access",
-                                                       mg.Name);
-                                               return null;
-                                       }
-
-                                       args = arguments;
+                       bool dynamic_member = TypeManager.IsDynamicType (expr_type);
 
-                                       if (mg.IsStatic != mg.IsInstance) {
-                                               if (args == null)
-                                                       args = new Arguments (1);
+                       if (!dynamic_member) {
+                               Expression invoke = null;
 
-                                               if (mg.IsStatic) {
-                                                       args.Insert (0, new Argument (new TypeOf (new TypeExpression (mg.DeclaringType, loc), loc).Resolve (ec), Argument.AType.DynamicStatic));
-                                               } else {
-                                                       MemberAccess ma = expr as MemberAccess;
-                                                       if (ma != null)
-                                                               args.Insert (0, new Argument (ma.Left.Resolve (ec)));
-                                                       else
-                                                               args.Insert (0, new Argument (new This (loc).Resolve (ec)));
+                               if (mg == null) {
+                                       if (expr_type != null && TypeManager.IsDelegateType (expr_type)) {
+                                               invoke = new DelegateInvocation (member_expr, arguments, loc);
+                                               invoke = invoke.Resolve (ec);
+                                               if (invoke == null || !dynamic_arg)
+                                                       return invoke;
+                                       } else {
+                                               MemberExpr me = member_expr as MemberExpr;
+                                               if (me == null) {
+                                                       member_expr.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup, loc);
+                                                       return null;
                                                }
-                                       }
-                               }
 
-                               return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec);
-                       }
+                                               mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
+                                               if (mg == null) {
+                                                       ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
+                                                               member_expr.GetSignatureForError ());
+                                                       return null;
+                                               }
 
-                       if (mg == null) {
-                               if (expr_type != null && TypeManager.IsDelegateType (expr_type)){
-                                       return (new DelegateInvocation (
-                                               expr_resolved, arguments, loc)).Resolve (ec);
+                                               ((ExtensionMethodGroupExpr) mg).ExtensionExpression = me.InstanceExpression;
+                                       }
                                }
 
-                               MemberExpr me = expr_resolved as MemberExpr;
-                               if (me == null) {
-                                       expr_resolved.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup, loc);
-                                       return null;
-                               }
-                               
-                               mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
-                               if (mg == null) {
-                                       ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
-                                               expr_resolved.GetSignatureForError ());
-                                       return null;
+                               if (invoke == null) {
+                                       mg = DoResolveOverload (ec);
+                                       if (mg == null)
+                                               return null;
                                }
-
-                               ((ExtensionMethodGroupExpr)mg).ExtensionExpression = me.InstanceExpression;
                        }
 
-                       mg = DoResolveOverload (ec);
-                       if (mg == null)
-                               return null;
+                       if (dynamic_arg || dynamic_member)
+                               return DoResolveDynamic (ec, member_expr);
 
-                       MethodInfo method = (MethodInfo)mg;
+                       var method = mg.BestCandidate;
                        if (method != null) {
                                type = TypeManager.TypeToCoreType (method.ReturnType);
 
@@ -5050,14 +5019,7 @@ namespace Mono.CSharp {
                                        }
                                }
                        }
-
-                       if (type.IsPointer){
-                               if (!ec.IsUnsafe){
-                                       UnsafeError (ec, loc);
-                                       return null;
-                               }
-                       }
-                       
+               
                        //
                        // Only base will allow this invocation to happen.
                        //
@@ -5083,26 +5045,74 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               Expression DoResolveDynamic (ResolveContext ec, Expression memberExpr)
+               {
+                       Arguments args;
+                       DynamicMemberBinder dmb = memberExpr as DynamicMemberBinder;
+                       if (dmb != null) {
+                               args = dmb.Arguments;
+                               if (arguments != null)
+                                       args.AddRange (arguments);
+                       } else if (mg == null) {
+                               if (arguments == null)
+                                       args = new Arguments (1);
+                               else
+                                       args = arguments;
+
+                               args.Insert (0, new Argument (memberExpr));
+                               this.expr = null;
+                       } else {
+                               if (mg.IsBase) {
+                                       ec.Report.Error (1971, loc,
+                                               "The base call to method `{0}' cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access",
+                                               mg.Name);
+                                       return null;
+                               }
+
+                               args = arguments;
+
+                               if (mg.IsStatic != mg.IsInstance) {
+                                       if (args == null)
+                                               args = new Arguments (1);
+
+                                       if (mg.IsStatic) {
+                                               args.Insert (0, new Argument (new TypeOf (new TypeExpression (mg.DeclaringType, loc), loc).Resolve (ec), Argument.AType.DynamicTypeName));
+                                       } else {
+                                               MemberAccess ma = expr as MemberAccess;
+                                               if (ma != null)
+                                                       args.Insert (0, new Argument (ma.Left.Resolve (ec)));
+                                               else
+                                                       args.Insert (0, new Argument (new This (loc).Resolve (ec)));
+                                       }
+                               }
+                       }
+
+                       return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec);
+               }
+
                protected virtual MethodGroupExpr DoResolveOverload (ResolveContext ec)
                {
                        return mg.OverloadResolve (ec, ref arguments, false, loc);
                }
 
-               public static bool IsSpecialMethodInvocation (ResolveContext ec, MethodBase method, Location loc)
+               public static bool IsSpecialMethodInvocation (ResolveContext ec, MethodSpec method, Location loc)
                {
-                       if (!TypeManager.IsSpecialMethod (method))
+                       if (!TypeManager.IsSpecialMethod (method.MetaInfo))
                                return false;
 
-                       ec.Report.SymbolRelatedToPreviousError (method);
+                       if (ec.HasSet (ResolveContext.Options.InvokeSpecialName))
+                               return false;
+
+                       ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
                        ec.Report.Error (571, loc, "`{0}': cannot explicitly call operator or accessor",
-                               TypeManager.CSharpSignature (method, true));
+                               TypeManager.CSharpSignature (method.MetaInfo, true));
        
                        return true;
                }
 
-               static Type[] GetVarargsTypes (MethodBase mb, Arguments arguments)
+               static Type[] GetVarargsTypes (MethodSpec mb, Arguments arguments)
                {
-                       AParametersCollection pd = TypeManager.GetParameterData (mb);
+                       AParametersCollection pd = mb.Parameters;
                        
                        Argument a = arguments [pd.Count - 1];
                        Arglist list = (Arglist) a.Expr;
@@ -5113,14 +5123,14 @@ namespace Mono.CSharp {
                /// <summary>
                /// This checks the ConditionalAttribute on the method 
                /// </summary>
-               public static bool IsMethodExcluded (MethodBase method, Location loc)
+               public static bool IsMethodExcluded (MethodSpec method, Location loc)
                {
                        if (method.IsConstructor)
                                return false;
 
-                       method = TypeManager.DropGenericMethodArguments (method);
-                       if (method.DeclaringType.Module == RootContext.ToplevelTypes.Builder) {
-                               IMethodData md = TypeManager.GetMethod (method);
+                       var mb = TypeManager.DropGenericMethodArguments (method.MetaInfo);
+                       if (TypeManager.IsBeingCompiled (mb)) {
+                               IMethodData md = TypeManager.GetMethod (mb);
                                if (md != null)
                                        return md.IsExcluded ();
 
@@ -5129,7 +5139,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       return AttributeTester.IsConditionalMethodExcluded (method, loc);
+                       return AttributeTester.IsConditionalMethodExcluded (mb, loc);
                }
 
                /// <remarks>
@@ -5149,7 +5159,7 @@ namespace Mono.CSharp {
                /// </remarks>
                public static void EmitCall (EmitContext ec, bool is_base,
                                             Expression instance_expr,
-                                            MethodBase method, Arguments Arguments, Location loc)
+                                            MethodSpec method, Arguments Arguments, Location loc)
                {
                        EmitCall (ec, is_base, instance_expr, method, Arguments, loc, false, false);
                }
@@ -5162,7 +5172,7 @@ namespace Mono.CSharp {
                // only have been evaluated once.
                public static void EmitCall (EmitContext ec, bool is_base,
                                             Expression instance_expr,
-                                            MethodBase method, Arguments Arguments, Location loc,
+                                            MethodSpec method, Arguments Arguments, Location loc,
                                             bool dup_args, bool omit_args)
                {
                        ILGenerator ig = ec.ig;
@@ -5237,198 +5247,102 @@ namespace Mono.CSharp {
                                                        this_arg = new LocalTemporary (t);
                                                        this_arg.Store (ec);
                                                }
-                                       }
-                               }
-                       }
-
-                       if (!omit_args && Arguments != null)
-                               Arguments.Emit (ec, dup_args, this_arg);
-
-                       OpCode call_op;
-                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual)) {
-                               call_op = OpCodes.Call;
-                       } else {
-                               call_op = OpCodes.Callvirt;
-                               
-                               if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
-                                       ig.Emit (OpCodes.Constrained, instance_expr.Type);
-                       }
-
-                       if ((method.CallingConvention & CallingConventions.VarArgs) != 0) {
-                               Type[] varargs_types = GetVarargsTypes (method, Arguments);
-                               ig.EmitCall (call_op, (MethodInfo) method, varargs_types);
-                               return;
-                       }
-
-                       //
-                       // If you have:
-                       // this.DoFoo ();
-                       // and DoFoo is not virtual, you can omit the callvirt,
-                       // because you don't need the null checking behavior.
-                       //
-                       if (method is MethodInfo)
-                               ig.Emit (call_op, (MethodInfo) method);
-                       else
-                               ig.Emit (call_op, (ConstructorInfo) method);
-               }
-
-               public override void Emit (EmitContext ec)
-               {
-                       mg.EmitCall (ec, arguments);
-               }
-               
-               public override void EmitStatement (EmitContext ec)
-               {
-                       Emit (ec);
-
-                       // 
-                       // Pop the return value if there is one
-                       //
-                       if (TypeManager.TypeToCoreType (type) != TypeManager.void_type)
-                               ec.ig.Emit (OpCodes.Pop);
-               }
-
-               protected override void CloneTo (CloneContext clonectx, Expression t)
-               {
-                       Invocation target = (Invocation) t;
-
-                       if (arguments != null)
-                               target.arguments = arguments.Clone (clonectx);
-
-                       target.expr = expr.Clone (clonectx);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       mg.MutateHoistedGenericType (storey);
-                       type = storey.MutateType (type);
-                       if (arguments != null) {
-                               arguments.MutateHoistedGenericType (storey);
-                       }
-               }
-       }
-/*
-       //
-       // It's either a cast or delegate invocation
-       //
-       public class InvocationOrCast : ExpressionStatement
-       {
-               Expression expr;
-               Expression argument;
-
-               public InvocationOrCast (Expression expr, Expression argument)
-               {
-                       this.expr = expr;
-                       this.argument = argument;
-                       this.loc = expr.Location;
-               }
-
-               public override Expression CreateExpressionTree (ResolveContext ec)
-               {
-                       throw new NotSupportedException ("ET");
-               }
-
-               public override Expression DoResolve (ResolveContext ec)
-               {
-                       Expression e = ResolveCore (ec);
-                       if (e == null)
-                               return null;
-
-                       return e.Resolve (ec);
-               }
-
-               Expression ResolveCore (EmitContext ec)
-               {
-                       //
-                       // First try to resolve it as a cast.
-                       //
-                       TypeExpr te = expr.ResolveAsBaseTerminal (ec, true);
-                       if (te != null) {
-                               return new Cast (te, argument, loc);
+                                       }
+                               }
                        }
 
-                       //
-                       // This can either be a type or a delegate invocation.
-                       // Let's just resolve it and see what we'll get.
-                       //
-                       expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue);
-                       if (expr == null)
-                               return null;
+                       if (!omit_args && Arguments != null)
+                               Arguments.Emit (ec, dup_args, this_arg);
 
-                       //
-                       // Ok, so it's a Cast.
-                       //
-                       if (expr.eclass == ExprClass.Type || expr.eclass == ExprClass.TypeParameter) {
-                               return new Cast (expr, argument, loc);
+                       OpCode call_op;
+                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual)) {
+                               call_op = OpCodes.Call;
+                       } else {
+                               call_op = OpCodes.Callvirt;
+                               
+                               if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
+                                       ig.Emit (OpCodes.Constrained, instance_expr.Type);
                        }
 
-                       if (expr.eclass == ExprClass.Namespace) {
-                               expr.Error_UnexpectedKind (null, "type", loc);
-                               return null;
-                       }                       
+                       if ((method.MetaInfo.CallingConvention & CallingConventions.VarArgs) != 0) {
+                               Type[] varargs_types = GetVarargsTypes (method, Arguments);
+                               ig.EmitCall (call_op, (MethodInfo) method.MetaInfo, varargs_types);
+                               return;
+                       }
 
                        //
-                       // It's a delegate invocation.
+                       // If you have:
+                       // this.DoFoo ();
+                       // and DoFoo is not virtual, you can omit the callvirt,
+                       // because you don't need the null checking behavior.
                        //
-                       if (!TypeManager.IsDelegateType (expr.Type)) {
-                               Error (149, "Method name expected");
-                               return null;
-                       }
+                       if (method.IsConstructor)
+                               ig.Emit (call_op, (ConstructorInfo) method.MetaInfo);
+                       else
+                               ig.Emit (call_op, (MethodInfo) method.MetaInfo);
+               }
 
-                       ArrayList args = new ArrayList (1);
-                       args.Add (new Argument (argument, Argument.AType.Expression));
-                       return new DelegateInvocation (expr, args, loc);
+               public override void Emit (EmitContext ec)
+               {
+                       mg.EmitCall (ec, arguments);
+               }
+               
+               public override void EmitStatement (EmitContext ec)
+               {
+                       Emit (ec);
+
+                       // 
+                       // Pop the return value if there is one
+                       //
+                       if (TypeManager.TypeToCoreType (type) != TypeManager.void_type)
+                               ec.ig.Emit (OpCodes.Pop);
                }
 
-               public override ExpressionStatement ResolveStatement (EmitContext ec)
+               protected override void CloneTo (CloneContext clonectx, Expression t)
                {
-                       Expression e = ResolveCore (ec);
-                       if (e == null)
-                               return null;
+                       Invocation target = (Invocation) t;
 
-                       ExpressionStatement s = e as ExpressionStatement;
-                       if (s == null) {
-                               Error_InvalidExpressionStatement ();
-                               return null;
-                       }
+                       if (arguments != null)
+                               target.arguments = arguments.Clone (clonectx);
 
-                       return s.ResolveStatement (ec);
+                       target.expr = expr.Clone (clonectx);
                }
 
-               public override void Emit (EmitContext ec)
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       throw new Exception ("Cannot happen");
+                       return MakeExpression (ctx, mg.InstanceExpression, (MethodSpec) mg, arguments);
                }
 
-               public override void EmitStatement (EmitContext ec)
+               public static SLE.Expression MakeExpression (BuilderContext ctx, Expression instance, MethodSpec mi, Arguments args)
                {
-                       throw new Exception ("Cannot happen");
+                       var instance_expr = instance == null ? null : instance.MakeExpression (ctx);
+                       return SLE.Expression.Call (instance_expr, (MethodInfo) mi.MetaInfo, Arguments.MakeExpression (args, ctx));
                }
 
-               protected override void CloneTo (CloneContext clonectx, Expression t)
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       InvocationOrCast target = (InvocationOrCast) t;
-
-                       target.expr = expr.Clone (clonectx);
-                       target.argument = argument.Clone (clonectx);
+                       mg.MutateHoistedGenericType (storey);
+                       type = storey.MutateType (type);
+                       if (arguments != null) {
+                               arguments.MutateHoistedGenericType (storey);
+                       }
                }
        }
-*/
 
        /// <summary>
        ///    Implements the new expression 
        /// </summary>
        public class New : ExpressionStatement, IMemoryLocation {
-               Arguments Arguments;
+               protected Arguments Arguments;
 
                //
                // During bootstrap, it contains the RequestedType,
                // but if `type' is not null, it *might* contain a NewDelegate
                // (because of field multi-initialization)
                //
-               Expression RequestedType;
+               protected Expression RequestedType;
 
-               MethodGroupExpr method;
+               protected MethodGroupExpr method;
 
                bool is_type_parameter;
 
@@ -5508,14 +5422,15 @@ namespace Mono.CSharp {
                                args = new Arguments (1);
                                args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        } else {
-                               args = Arguments.CreateForExpressionTree (ec, Arguments,
+                               args = Arguments.CreateForExpressionTree (ec,
+                                       Arguments,
                                        method.CreateExpressionTree (ec));
                        }
 
                        return CreateExpressionFactoryCall (ec, "New", args);
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        //
                        // The New DoResolve might be called twice when initializing field
@@ -5546,7 +5461,7 @@ namespace Mono.CSharp {
                        if (Arguments == null) {
                                Constant c = Constantify (type);
                                if (c != null)
-                                       return ReducedExpression.Create (c, this);
+                                       return ReducedExpression.Create (c.Resolve (ec), this);
                        }
 
                        if (TypeManager.IsDelegateType (type)) {
@@ -5571,7 +5486,7 @@ namespace Mono.CSharp {
                                }
 
                                if (TypeManager.activator_create_instance == null) {
-                                       Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", Kind.Class, true);
+                                       Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", MemberKind.Class, true);
                                        if (activator_type != null) {
                                                TypeManager.activator_create_instance = TypeManager.GetPredefinedMethod (
                                                        activator_type, "CreateInstance", loc, Type.EmptyTypes);
@@ -5615,14 +5530,11 @@ namespace Mono.CSharp {
                        Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName,
                                MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
 
+                       bool dynamic;
                        if (Arguments != null) {
-                               bool dynamic;
                                Arguments.Resolve (ec, out dynamic);
-
-                               if (dynamic) {
-                                       Arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec)));
-                                       return new DynamicInvocation (new SimpleName (ConstructorInfo.ConstructorName, loc), Arguments, type, loc).Resolve (ec);
-                               }
+                       } else {
+                               dynamic = false;
                        }
 
                        if (ml == null)
@@ -5638,6 +5550,11 @@ namespace Mono.CSharp {
                        if (method == null)
                                return null;
 
+                       if (dynamic) {
+                               Arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec), Argument.AType.DynamicTypeName));
+                               return new DynamicConstructorBinder (type, Arguments, loc).Resolve (ec);
+                       }
+
                        return this;
                }
 
@@ -5645,8 +5562,8 @@ namespace Mono.CSharp {
                {
                        ILGenerator ig = ec.ig;
 
-                       MethodInfo ci = TypeManager.activator_create_instance.MakeGenericMethod (
-                               new Type [] { type });
+                       MethodInfo ci = (MethodInfo) TypeManager.activator_create_instance.MetaInfo;
+                       ci = ci.MakeGenericMethod (new Type [] { type });
 
                        GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
                        if (gc.HasReferenceTypeConstraint || gc.HasClassConstraint) {
@@ -5730,7 +5647,7 @@ namespace Mono.CSharp {
                                }
 
                                if (vr != null) {
-                                       ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+                                       ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
                                        return false;
                                }
                        }
@@ -5738,7 +5655,7 @@ namespace Mono.CSharp {
                        if (is_type_parameter)
                                return DoEmitTypeParameter (ec);                        
 
-                       ConstructorInfo ci = (ConstructorInfo) method;
+                       ConstructorInfo ci = (ConstructorInfo) method.BestCandidate.MetaInfo;
 #if MS_COMPATIBLE
                        if (TypeManager.IsGenericType (type) && type.IsGenericTypeDefinition)
                                ci = TypeBuilder.GetConstructor (type, ci);
@@ -5772,12 +5689,6 @@ namespace Mono.CSharp {
                                ec.ig.Emit (OpCodes.Pop);
                }
 
-               public bool IsDefaultValueType {
-                       get {
-                               return TypeManager.IsValueType (type) && !HasInitializer && Arguments == null;
-                       }
-               }
-
                public virtual bool HasInitializer {
                        get {
                                return false;
@@ -5818,7 +5729,7 @@ namespace Mono.CSharp {
                                if (Arguments != null)
                                        Arguments.Emit (ec);
 
-                               ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+                               ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
                        }
                        
                        value_target.AddressOf (ec, mode);
@@ -5835,6 +5746,11 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       return SLE.Expression.New ((ConstructorInfo) method.BestCandidate.MetaInfo, Arguments.MakeExpression (Arguments, ctx));
+               }
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        if (method != null) {
@@ -5848,6 +5764,57 @@ namespace Mono.CSharp {
                }
        }
 
+       public class ArrayInitializer : ShimExpression
+       {
+               List<Expression> elements;
+
+               public ArrayInitializer (List<Expression> init, Location loc)
+                       : base (null)
+               {
+                       elements = init;
+               }
+
+               public ArrayInitializer (int count, Location loc)
+                       : base (null)
+               {
+                       elements = new List<Expression> (count);
+               }
+
+               public ArrayInitializer (Location loc)
+                       : this (4, loc)
+               {
+               }
+
+               public void Add (Expression expr)
+               {
+                       elements.Add (expr);
+               }
+
+               protected override void CloneTo (CloneContext clonectx, Expression t)
+               {
+                       var target = (ArrayInitializer) t;
+
+                       target.elements = new List<Expression> (elements.Count);
+                       foreach (var element in elements)
+                               target.elements.Add (element.Clone (clonectx));
+
+                       base.CloneTo (clonectx, t);
+               }
+
+               public int Count {
+                       get { return elements.Count; }
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public Expression this [int index] {
+                       get { return elements [index]; }
+               }
+       }
+
        /// <summary>
        ///   14.5.10.2: Represents an array creation expression.
        /// </summary>
@@ -5858,46 +5825,45 @@ namespace Mono.CSharp {
        ///   initialization data and the other which does not need dimensions
        ///   specified but where initialization data is mandatory.
        /// </remarks>
-       public class ArrayCreation : Expression {
+       class ArrayCreation : Expression
+       {
                FullNamedExpression requested_base_type;
-               ArrayList initializers;
+               ArrayInitializer initializers;
 
                //
                // The list of Argument types.
                // This is used to construct the `newarray' or constructor signature
                //
-               protected ArrayList arguments;
+               protected List<Expression> arguments;
                
                protected Type array_element_type;
                bool expect_initializers = false;
                int num_arguments = 0;
                protected int dimensions;
                protected readonly string rank;
+               Expression first_emit;
+               LocalTemporary first_emit_temp;
 
-               protected ArrayList array_data;
+               protected List<Expression> array_data;
 
-               IDictionary bounds;
+               Dictionary<int, int> bounds;
 
                // The number of constants in array initializers
                int const_initializers_count;
                bool only_constant_initializers;
-               
-               public ArrayCreation (FullNamedExpression requested_base_type, ArrayList exprs, string rank, ArrayList initializers, Location l)
+
+               public ArrayCreation (FullNamedExpression requested_base_type, List<Expression> exprs, string rank, ArrayInitializer initializers, Location l)
                {
                        this.requested_base_type = requested_base_type;
                        this.initializers = initializers;
                        this.rank = rank;
                        loc = l;
 
-                       arguments = new ArrayList (exprs.Count);
-
-                       foreach (Expression e in exprs) {
-                               arguments.Add (e);
-                               num_arguments++;
-                       }
+                       arguments = new List<Expression> (exprs);
+                       num_arguments = arguments.Count;
                }
 
-               public ArrayCreation (FullNamedExpression requested_base_type, string rank, ArrayList initializers, Location l)
+               public ArrayCreation (FullNamedExpression requested_base_type, string rank, ArrayInitializer initializers, Location l)
                {
                        this.requested_base_type = requested_base_type;
                        this.initializers = initializers;
@@ -5917,10 +5883,10 @@ namespace Mono.CSharp {
                        ec.Report.Error (248, loc, "Cannot create an array with a negative size");
                }
 
-               bool CheckIndices (ResolveContext ec, ArrayList probe, int idx, bool specified_dims, int child_bounds)
+               bool CheckIndices (ResolveContext ec, ArrayInitializer probe, int idx, bool specified_dims, int child_bounds)
                {
                        if (specified_dims) { 
-                               Expression a = (Expression) arguments [idx];
+                               Expression a = arguments [idx];
                                a = a.Resolve (ec);
                                if (a == null)
                                        return false;
@@ -5947,9 +5913,9 @@ namespace Mono.CSharp {
 
                        only_constant_initializers = true;
                        for (int i = 0; i < probe.Count; ++i) {
-                               object o = probe [i];
-                               if (o is ArrayList) {
-                                       ArrayList sub_probe = o as ArrayList;
+                               var o = probe [i];
+                               if (o is ArrayInitializer) {
+                                       var sub_probe = o as ArrayInitializer;
                                        if (idx + 1 >= dimensions){
                                                ec.Report.Error (623, loc, "Array initializers can only be used in a variable or field initializer. Try using a new expression instead");
                                                return false;
@@ -5959,9 +5925,9 @@ namespace Mono.CSharp {
                                        if (!ret)
                                                return false;
                                } else if (child_bounds > 1) {
-                                       ec.Report.Error (846, ((Expression) o).Location, "A nested array initializer was expected");
+                                       ec.Report.Error (846, o.Location, "A nested array initializer was expected");
                                } else {
-                                       Expression element = ResolveArrayElement (ec, (Expression) o);
+                                       Expression element = ResolveArrayElement (ec, o);
                                        if (element == null)
                                                continue;
 
@@ -6007,9 +5973,9 @@ namespace Mono.CSharp {
                        args.Add (new Argument (new TypeOf (new TypeExpression (array_element_type, loc), loc)));
                        if (array_data != null) {
                                for (int i = 0; i < array_data.Count; ++i) {
-                                       Expression e = (Expression) array_data [i];
+                                       Expression e = array_data [i];
                                        if (e == null)
-                                               e = Convert.ImplicitConversion (ec, (Expression) initializers [i], array_element_type, loc);
+                                               e = Convert.ImplicitConversion (ec, initializers [i], array_element_type, loc);
 
                                        args.Add (new Argument (e.CreateExpressionTree (ec)));
                                }
@@ -6021,14 +5987,14 @@ namespace Mono.CSharp {
                public void UpdateIndices ()
                {
                        int i = 0;
-                       for (ArrayList probe = initializers; probe != null;) {
-                               if (probe.Count > 0 && probe [0] is ArrayList) {
+                       for (var probe = initializers; probe != null;) {
+                               if (probe.Count > 0 && probe [0] is ArrayInitializer) {
                                        Expression e = new IntConstant (probe.Count, Location.Null);
                                        arguments.Add (e);
 
-                                       bounds [i++] =  probe.Count;
-                                       
-                                       probe = (ArrayList) probe [0];
+                                       bounds [i++] = probe.Count;
+
+                                       probe = (ArrayInitializer) probe[0];
                                        
                                } else {
                                        Expression e = new IntConstant (probe.Count, Location.Null);
@@ -6038,12 +6004,8 @@ namespace Mono.CSharp {
                                        return;
                                }
                        }
-
                }
 
-               Expression first_emit;
-               LocalTemporary first_emit_temp;
-
                protected virtual Expression ResolveArrayElement (ResolveContext ec, Expression element)
                {
                        element = element.Resolve (ec);
@@ -6071,13 +6033,13 @@ namespace Mono.CSharp {
                        // We use this to store all the date values in the order in which we
                        // will need to store them in the byte blob later
                        //
-                       array_data = new ArrayList ();
-                       bounds = new System.Collections.Specialized.HybridDictionary ();
+                       array_data = new List<Expression> ();
+                       bounds = new Dictionary<int, int> ();
                        
                        if (arguments != null)
                                return CheckIndices (ec, initializers, 0, true, dimensions);
 
-                       arguments = new ArrayList ();
+                       arguments = new List<Expression> ();
 
                        if (!CheckIndices (ec, initializers, 0, false, dimensions))
                                return false;
@@ -6092,11 +6054,6 @@ namespace Mono.CSharp {
                //
                bool ResolveArrayType (ResolveContext ec)
                {
-                       if (requested_base_type == null) {
-                               ec.Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
-                               return false;
-                       }
-
                        if (requested_base_type is VarExpr) {
                                ec.Report.Error (820, loc, "An implicitly typed local variable declarator cannot use an array initializer");
                                return false;
@@ -6125,13 +6082,18 @@ namespace Mono.CSharp {
                                return false;
 
                        type = array_type_expr.Type;
+                       if (!type.IsArray) {
+                               ec.Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
+                               return false;
+                       }
+
                        array_element_type = TypeManager.GetElementType (type);
                        dimensions = type.GetArrayRank ();
 
                        return true;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (type != null)
                                return this;
@@ -6147,7 +6109,7 @@ namespace Mono.CSharp {
                                return null;
 
                        for (int i = 0; i < arguments.Count; ++i) {
-                               Expression e = ((Expression) arguments[i]).Resolve (ec);
+                               Expression e = arguments[i].Resolve (ec);
                                if (e == null)
                                        continue;
 
@@ -6158,7 +6120,7 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               MethodInfo GetArrayMethod (int arguments)
+               MethodInfo GetArrayMethod (EmitContext ec, int arguments)
                {
                        ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
 
@@ -6170,7 +6132,7 @@ namespace Mono.CSharp {
                                                        arg_types);
 
                        if (mi == null) {
-                               RootContext.ToplevelTypes.Compiler.Report.Error (-6, "New invocation: Can not find a constructor for " +
+                               ec.Report.Error (-6, "New invocation: Can not find a constructor for " +
                                                  "this argument list");
                                return null;
                        }
@@ -6330,6 +6292,21 @@ namespace Mono.CSharp {
                        return data;
                }
 
+#if NET_4_0
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       var initializers = new SLE.Expression [array_data.Count];
+                       for (var i = 0; i < initializers.Length; i++) {
+                               if (array_data [i] == null)
+                                       initializers [i] = SLE.Expression.Default (array_element_type);
+                               else
+                                       initializers [i] = array_data [i].MakeExpression (ctx);
+                       }
+
+                       return SLE.Expression.NewArrayInit (array_element_type, initializers);
+               }
+#endif
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        array_element_type = storey.MutateType (array_element_type);
@@ -6376,8 +6353,7 @@ namespace Mono.CSharp {
 
                        ig.Emit (OpCodes.Dup);
                        ig.Emit (OpCodes.Ldtoken, fb);
-                       ig.Emit (OpCodes.Call,
-                                TypeManager.void_initializearray_array_fieldhandle);
+                       ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_initializearray_array_fieldhandle.MetaInfo);
                }
 
                //
@@ -6409,7 +6385,7 @@ namespace Mono.CSharp {
 
                        for (int i = 0; i < array_data.Count; i++){
 
-                               Expression e = (Expression)array_data [i];
+                               Expression e = array_data [i];
 
                                // Constant can be initialized via StaticInitializer
                                if (e != null && !(!emitConstants && e is Constant)) {
@@ -6452,7 +6428,7 @@ namespace Mono.CSharp {
                                //
                                for (int j = dims - 1; j >= 0; j--){
                                        current_pos [j]++;
-                                       if (current_pos [j] < (int) bounds [j])
+                                       if (current_pos [j] < bounds [j])
                                                break;
                                        current_pos [j] = 0;
                                }
@@ -6474,16 +6450,16 @@ namespace Mono.CSharp {
                        if (arguments.Count == 1)
                                ig.Emit (OpCodes.Newarr, TypeManager.TypeToReflectionType (array_element_type));
                        else {
-                               ig.Emit (OpCodes.Newobj, GetArrayMethod (arguments.Count));
+                               ig.Emit (OpCodes.Newobj, GetArrayMethod (ec, arguments.Count));
                        }
                        
                        if (initializers == null)
                                return;
 
-                       // Emit static initializer for arrays which have contain more than 4 items and
+                       // Emit static initializer for arrays which have contain more than 2 items and
                        // the static initializer will initialize at least 25% of array values.
                        // NOTE: const_initializers_count does not contain default constant values.
-                       if (const_initializers_count >= 4 && const_initializers_count * 4 > (array_data.Count) &&
+                       if (const_initializers_count > 2 && const_initializers_count * 4 > (array_data.Count) &&
                                (TypeManager.IsPrimitiveType (array_element_type) || TypeManager.IsEnumType (array_element_type))) {
                                EmitStaticInitializers (ec);
 
@@ -6505,7 +6481,7 @@ namespace Mono.CSharp {
                        }
 
                        if (array_data == null) {
-                               Expression arg = (Expression) arguments[0];
+                               Expression arg = arguments [0];
                                object arg_value;
                                if (arg.GetAttributableValue (ec, arg.Type, out arg_value) && arg_value is int && (int)arg_value == 0) {
                                        value = Array.CreateInstance (array_element_type, 0);
@@ -6520,7 +6496,7 @@ namespace Mono.CSharp {
                        object element_value;
                        for (int i = 0; i < ret.Length; ++i)
                        {
-                               Expression e = (Expression)array_data [i];
+                               Expression e = array_data [i];
 
                                // Is null when an initializer is optimized (value == predefined value)
                                if (e == null) 
@@ -6544,33 +6520,22 @@ namespace Mono.CSharp {
                                target.requested_base_type = (FullNamedExpression)requested_base_type.Clone (clonectx);
 
                        if (arguments != null){
-                               target.arguments = new ArrayList (arguments.Count);
+                               target.arguments = new List<Expression> (arguments.Count);
                                foreach (Expression e in arguments)
                                        target.arguments.Add (e.Clone (clonectx));
                        }
 
-                       if (initializers != null){
-                               target.initializers = new ArrayList (initializers.Count);
-                               foreach (object initializer in initializers)
-                                       if (initializer is ArrayList) {
-                                               ArrayList this_al = (ArrayList)initializer;
-                                               ArrayList al = new ArrayList (this_al.Count);
-                                               target.initializers.Add (al);
-                                               foreach (Expression e in this_al)
-                                                       al.Add (e.Clone (clonectx));
-                                       } else {
-                                               target.initializers.Add (((Expression)initializer).Clone (clonectx));
-                                       }
-                       }
+                       if (initializers != null)
+                               target.initializers = (ArrayInitializer) initializers.Clone (clonectx);
                }
        }
        
        //
        // Represents an implicitly typed array epxression
        //
-       public class ImplicitlyTypedArrayCreation : ArrayCreation
+       class ImplicitlyTypedArrayCreation : ArrayCreation
        {
-               public ImplicitlyTypedArrayCreation (string rank, ArrayList initializers, Location loc)
+               public ImplicitlyTypedArrayCreation (string rank, ArrayInitializer initializers, Location loc)
                        : base (null, rank, initializers, loc)
                {                       
                        if (rank.Length > 2) {
@@ -6580,7 +6545,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (type != null)
                                return this;
@@ -6668,7 +6633,7 @@ namespace Mono.CSharp {
                        this.type = type;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        eclass = ExprClass.Variable;
                        if (type == null)
@@ -6774,9 +6739,6 @@ namespace Mono.CSharp {
 
                public bool ResolveBase (ResolveContext ec)
                {
-                       if (eclass != ExprClass.Invalid)
-                               return true;
-
                        eclass = ExprClass.Variable;
                        type = ec.CurrentType;
 
@@ -6830,7 +6792,7 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Constant", args);
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        ResolveBase (ec);
                        return this;
@@ -6847,7 +6809,7 @@ namespace Mono.CSharp {
                        if (ec.CurrentType.IsClass){
                                if (right_side == EmptyExpression.UnaryAddress)
                                        ec.Report.Error (459, loc, "Cannot take the address of `this' because it is read-only");
-                               else if (right_side == EmptyExpression.OutAccess)
+                               else if (right_side == EmptyExpression.OutAccess.Instance)
                                        ec.Report.Error (1605, loc, "Cannot pass `this' as a ref or out argument because it is read-only");
                                else
                                        ec.Report.Error (1604, loc, "Cannot assign to `this' because it is read-only");
@@ -6902,7 +6864,7 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        eclass = ExprClass.Variable;
                        type = TypeManager.runtime_argument_handle_type;
@@ -6963,7 +6925,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        eclass = ExprClass.Variable;
                        type = InternalType.Arglist;
@@ -7017,11 +6979,8 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Constant", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-
                        TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
                        if (texpr == null)
                                return null;
@@ -7058,7 +7017,7 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        ec.ig.Emit (OpCodes.Ldtoken, TypeManager.TypeToReflectionType (typearg));
-                       ec.ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
+                       ec.ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.system_type_get_type_from_handle.MetaInfo);
                }
 
                public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value)
@@ -7082,7 +7041,8 @@ namespace Mono.CSharp {
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       typearg = storey.MutateType (typearg);
+                       if (!TypeManager.IsGenericTypeDefinition (typearg))
+                               typearg = storey.MutateType (typearg);
                }
 
                public Type TypeArgument {
@@ -7108,7 +7068,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        type = TypeManager.type_type;
                        typearg = TypeManager.void_type;
@@ -7117,23 +7077,23 @@ namespace Mono.CSharp {
                }
        }
 
-       class TypeOfMethod : TypeOfMember
+       class TypeOfMethod : TypeOfMember<MethodSpec>
        {
-               public TypeOfMethod (MethodBase method, Location loc)
+               public TypeOfMethod (MethodSpec method, Location loc)
                        : base (method, loc)
                {
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (member is MethodInfo) {
-                               type = TypeManager.methodinfo_type;
+                       if (member.IsConstructor) {
+                               type = TypeManager.ctorinfo_type;
                                if (type == null)
-                                       type = TypeManager.methodinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "MethodInfo", Kind.Class, true);
+                                       type = TypeManager.ctorinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "ConstructorInfo", MemberKind.Class, true);
                        } else {
-                               type = TypeManager.ctorinfo_type;
+                               type = TypeManager.methodinfo_type;
                                if (type == null)
-                                       type = TypeManager.ctorinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "ConstructorInfo", Kind.Class, true);
+                                       type = TypeManager.methodinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", "MethodInfo", MemberKind.Class, true);
                        }
 
                        return base.DoResolve (ec);
@@ -7141,10 +7101,10 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       if (member is ConstructorInfo)
-                               ec.ig.Emit (OpCodes.Ldtoken, (ConstructorInfo) member);
+                       if (member.IsConstructor)
+                               ec.ig.Emit (OpCodes.Ldtoken, (ConstructorInfo) member.MetaInfo);
                        else
-                               ec.ig.Emit (OpCodes.Ldtoken, (MethodInfo) member);
+                               ec.ig.Emit (OpCodes.Ldtoken, (MethodInfo) member.MetaInfo);
 
                        base.Emit (ec);
                        ec.ig.Emit (OpCodes.Castclass, type);
@@ -7158,7 +7118,7 @@ namespace Mono.CSharp {
                        get { return "RuntimeMethodHandle"; }
                }
 
-               protected override MethodInfo TypeFromHandle {
+               protected override MethodSpec TypeFromHandle {
                        get {
                                return TypeManager.methodbase_get_type_from_handle;
                        }
@@ -7167,7 +7127,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override MethodInfo TypeFromHandleGeneric {
+               protected override MethodSpec TypeFromHandleGeneric {
                        get {
                                return TypeManager.methodbase_get_type_from_handle_generic;
                        }
@@ -7181,11 +7141,11 @@ namespace Mono.CSharp {
                }
        }
 
-       abstract class TypeOfMember : Expression
+       abstract class TypeOfMember<T> : Expression where T : MemberSpec
        {
-               protected readonly MemberInfo member;
+               protected readonly T member;
 
-               protected TypeOfMember (MemberInfo member, Location loc)
+               protected TypeOfMember (T member, Location loc)
                {
                        this.member = member;
                        this.loc = loc;
@@ -7199,14 +7159,14 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Constant", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
-                       MethodInfo mi = is_generic ? TypeFromHandleGeneric : TypeFromHandle;
+                       var mi = is_generic ? TypeFromHandleGeneric : TypeFromHandle;
 
                        if (mi == null) {
-                               Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, Kind.Class, true);
-                               Type handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, Kind.Class, true);
+                               Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
+                               Type handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, MemberKind.Class, true);
 
                                if (t == null || handle_type == null)
                                        return null;
@@ -7229,7 +7189,7 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
-                       MethodInfo mi;
+                       MethodSpec mi;
                        if (is_generic) {
                                mi = TypeFromHandleGeneric;
                                ec.ig.Emit (OpCodes.Ldtoken, member.DeclaringType);
@@ -7237,27 +7197,27 @@ namespace Mono.CSharp {
                                mi = TypeFromHandle;
                        }
 
-                       ec.ig.Emit (OpCodes.Call, mi);
+                       ec.ig.Emit (OpCodes.Call, (MethodInfo) mi.MetaInfo);
                }
 
                protected abstract string GetMethodName { get; }
                protected abstract string RuntimeHandleName { get; }
-               protected abstract MethodInfo TypeFromHandle { get; set; }
-               protected abstract MethodInfo TypeFromHandleGeneric { get; set; }
+               protected abstract MethodSpec TypeFromHandle { get; set; }
+               protected abstract MethodSpec TypeFromHandleGeneric { get; set; }
                protected abstract string TypeName { get; }
        }
 
-       class TypeOfField : TypeOfMember
+       class TypeOfField : TypeOfMember<FieldSpec>
        {
-               public TypeOfField (FieldInfo field, Location loc)
+               public TypeOfField (FieldSpec field, Location loc)
                        : base (field, loc)
                {
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (TypeManager.fieldinfo_type == null)
-                               TypeManager.fieldinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, Kind.Class, true);
+                               TypeManager.fieldinfo_type = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
 
                        type = TypeManager.fieldinfo_type;
                        return base.DoResolve (ec);
@@ -7265,7 +7225,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldtoken, (FieldInfo) member);
+                       ec.ig.Emit (OpCodes.Ldtoken, member.MetaInfo);
                        base.Emit (ec);
                }
 
@@ -7277,7 +7237,7 @@ namespace Mono.CSharp {
                        get { return "RuntimeFieldHandle"; }
                }
 
-               protected override MethodInfo TypeFromHandle {
+               protected override MethodSpec TypeFromHandle {
                        get {
                                return TypeManager.fieldinfo_get_field_from_handle;
                        }
@@ -7286,7 +7246,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override MethodInfo TypeFromHandleGeneric {
+               protected override MethodSpec TypeFromHandleGeneric {
                        get {
                                return TypeManager.fieldinfo_get_field_from_handle_generic;
                        }
@@ -7319,7 +7279,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
                        if (texpr == null)
@@ -7331,10 +7291,10 @@ namespace Mono.CSharp {
 
                        int size_of = GetTypeSize (type_queried);
                        if (size_of > 0) {
-                               return new IntConstant (size_of, loc);
+                               return new IntConstant (size_of, loc).Resolve (ec);
                        }
 
-                       if (!TypeManager.VerifyUnManaged (type_queried, loc)){
+                       if (!TypeManager.VerifyUnmanaged (ec.Compiler, type_queried, loc)){
                                return null;
                        }
 
@@ -7409,7 +7369,7 @@ namespace Mono.CSharp {
                        return fne;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return ResolveAsTypeStep (ec, false);
                }
@@ -7475,9 +7435,10 @@ namespace Mono.CSharp {
                        //
 
                        SimpleName original = expr as SimpleName;
-                       Expression expr_resolved = expr.Resolve (ec,
-                               ResolveFlags.VariableOrValue | ResolveFlags.Type |
-                               ResolveFlags.Intermediate | ResolveFlags.DisableStructFlowAnalysis);
+                       Expression expr_resolved;
+                       using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
+                               expr_resolved = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.Intermediate);
+                       }
 
                        if (expr_resolved == null)
                                return null;
@@ -7489,7 +7450,7 @@ namespace Mono.CSharp {
                                FullNamedExpression retval = ns.Lookup (ec.Compiler, LookupIdentifier, loc);
 
                                if (retval == null)
-                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec.Report);
+                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec);
                                else if (targs != null)
                                        retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
 
@@ -7498,12 +7459,13 @@ namespace Mono.CSharp {
 
                        Type expr_type = expr_resolved.Type;
                        if (TypeManager.IsDynamicType (expr_type)) {
-                               Arguments args = new Arguments (2);
+                               Arguments args = new Arguments (1);
                                args.Add (new Argument (expr_resolved.Resolve (ec)));
+                               expr = new DynamicMemberBinder (Name, args, loc);
                                if (right_side != null)
-                                       args.Add (new Argument (right_side));
+                                       return expr.DoResolveLValue (ec, right_side);
 
-                               return new DynamicMemberBinder (right_side != null, Name, args, loc).Resolve (ec);
+                               return expr.Resolve (ec);
                        }
 
                        if (expr_type.IsPointer || expr_type == TypeManager.void_type ||
@@ -7549,7 +7511,7 @@ namespace Mono.CSharp {
                                                        ex_method_lookup.SetTypeArguments (ec, targs);
                                                }
 
-                                               return ex_method_lookup.DoResolve (ec);
+                                               return ex_method_lookup.Resolve (ec);
                                        }
                                }
 
@@ -7611,7 +7573,7 @@ namespace Mono.CSharp {
                                me.SetTypeArguments (ec, targs);
                        }
 
-                       if (original != null && !TypeManager.IsValueType (expr_type)) {
+                       if (original != null && (!TypeManager.IsValueType (expr_type) || me is PropertyExpr)) {
                                if (me.IsInstance) {
                                        LocalVariableReference var = expr_resolved as LocalVariableReference;
                                        if (var != null && !var.VerifyAssigned (ec))
@@ -7625,10 +7587,10 @@ namespace Mono.CSharp {
                        if (right_side != null)
                                return me.DoResolveLValue (ec, right_side);
                        else
-                               return me.DoResolve (ec);
+                               return me.Resolve (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return DoResolve (ec, null);
                }
@@ -7657,7 +7619,7 @@ namespace Mono.CSharp {
                                FullNamedExpression retval = ns.Lookup (rc.Compiler, LookupIdentifier, loc);
 
                                if (retval == null && !silent)
-                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc.Compiler.Report);
+                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc);
                                else if (targs != null)
                                        retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
 
@@ -7726,7 +7688,7 @@ namespace Mono.CSharp {
                                if (expr_type == null)
                                        return;
 
-                               Namespace.Error_TypeArgumentsCannotBeUsed (expr_type, loc);
+                               expr_type.Error_TypeArgumentsCannotBeUsed (rc.Compiler.Report, loc);
                                return;
                        }
 
@@ -7745,7 +7707,7 @@ namespace Mono.CSharp {
 
                protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
                {
-                       if (RootContext.Version > LanguageVersion.ISO_2 &&
+                       if (RootContext.Version > LanguageVersion.ISO_2 && !ec.Compiler.IsRuntimeBinder &&
                                ((expr.eclass & (ExprClass.Value | ExprClass.Variable)) != 0)) {
                                ec.Report.Error (1061, loc, "Type `{0}' does not contain a definition for `{1}' and no " +
                                        "extension method `{1}' of type `{0}' could be found " +
@@ -7795,7 +7757,7 @@ namespace Mono.CSharp {
                                return Expr.CreateExpressionTree (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        using (ec.With (ResolveContext.Options.AllCheckStateFlags, true))
                                Expr = Expr.Resolve (ec);
@@ -7823,14 +7785,12 @@ namespace Mono.CSharp {
                                Expr.EmitBranchable (ec, target, on_true);
                }
 
-#if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        using (ctx.With (BuilderContext.Options.AllCheckStateFlags, true)) {
                                return Expr.MakeExpression (ctx);
                        }
                }
-#endif
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
@@ -7864,7 +7824,7 @@ namespace Mono.CSharp {
                                return Expr.CreateExpressionTree (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        using (ec.With (ResolveContext.Options.AllCheckStateFlags, false))
                                Expr = Expr.Resolve (ec);
@@ -7944,7 +7904,7 @@ namespace Mono.CSharp {
                        return new Indirection (p, loc).Resolve (ec);
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        Expr = Expr.Resolve (ec);
                        if (Expr == null)
@@ -7970,7 +7930,7 @@ namespace Mono.CSharp {
 
                        FieldExpr fe = Expr as FieldExpr;
                        if (fe != null) {
-                               IFixedBuffer ff = AttributeTester.GetFixedBuffer (fe.FieldInfo);
+                               var ff = fe.Spec as FixedFieldSpec;
                                if (ff != null) {
                                        return MakePointerAccess (ec, ff.ElementType);
                                }
@@ -8004,7 +7964,7 @@ namespace Mono.CSharp {
 
                public static void Error_NamedArgument (NamedArgument na, Report Report)
                {
-                       Report.Error (1742, na.Name.Location, "An element access expression cannot use named argument");
+                       Report.Error (1742, na.Location, "An element access expression cannot use named argument");
                }
 
                public override string GetSignatureForError ()
@@ -8025,7 +7985,7 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Implements array access 
        /// </summary>
-       public class ArrayAccess : Expression, IAssignMethod, IMemoryLocation {
+       public class ArrayAccess : Expression, IDynamicAssign, IMemoryLocation {
                //
                // Points to our "data" repository
                //
@@ -8051,22 +8011,8 @@ namespace Mono.CSharp {
                        return DoResolve (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-#if false
-                       ExprClass eclass = ea.Expr.eclass;
-
-                       // As long as the type is valid
-                       if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
-                             eclass == ExprClass.Value)) {
-                               ea.Expr.Error_UnexpectedKind ("variable or value");
-                               return null;
-                       }
-#endif
-
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-
                        // dynamic is used per argument in ConvertExpressionToArrayIndex case
                        bool dynamic;
                        ea.Arguments.Resolve (ec, out dynamic);
@@ -8375,6 +8321,22 @@ namespace Mono.CSharp {
                        }
                }
 
+#if NET_4_0
+               public SLE.Expression MakeAssignExpression (BuilderContext ctx)
+               {
+                       return SLE.Expression.ArrayAccess (
+                               ea.Expr.MakeExpression (ctx),
+                               Arguments.MakeExpression (ea.Arguments, ctx));
+               }
+#endif
+
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
+               {
+                       return SLE.Expression.ArrayIndex (
+                               ea.Expr.MakeExpression (ctx),
+                               Arguments.MakeExpression (ea.Arguments, ctx));
+               }
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        type = storey.MutateType (type);
@@ -8385,14 +8347,14 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Expressions that represent an indexer call.
        /// </summary>
-       public class IndexerAccess : Expression, IAssignMethod
+       public class IndexerAccess : Expression, IDynamicAssign
        {
                class IndexerMethodGroupExpr : MethodGroupExpr
                {
                        public IndexerMethodGroupExpr (Indexers indexers, Location loc)
                                : base (null, loc)
                        {
-                               Methods = (MethodBase []) indexers.Methods.ToArray (typeof (MethodBase));
+                               Methods = indexers.Methods.ToArray ();
                        }
 
                        public override string Name {
@@ -8401,7 +8363,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       protected override int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
+                       protected override int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
                        {
                                //
                                // Here is the trick, decrease number of arguments by 1 when only
@@ -8419,8 +8381,8 @@ namespace Mono.CSharp {
                class Indexers
                {
                        // Contains either property getter or setter
-                       public ArrayList Methods;
-                       public ArrayList Properties;
+                       public List<MethodSpec> Methods;
+                       public List<PropertyInfo> Properties;
 
                        Indexers ()
                        {
@@ -8437,11 +8399,11 @@ namespace Mono.CSharp {
                                                accessor = property.GetSetMethod (true);
 
                                        if (Methods == null) {
-                                               Methods = new ArrayList ();
-                                               Properties = new ArrayList ();
+                                               Methods = new List<MethodSpec> ();
+                                               Properties = new List<PropertyInfo> ();
                                        }
 
-                                       Methods.Add (accessor);
+                                       Methods.Add (Import.CreateMethod (accessor));
                                        Properties.Add (property);
                                }
                        }
@@ -8501,7 +8463,7 @@ namespace Mono.CSharp {
                //
                // Points to our "data" repository
                //
-               MethodInfo get, set;
+               MethodSpec get, set;
                bool is_base_indexer;
                bool prepared;
                LocalTemporary temp;
@@ -8524,7 +8486,6 @@ namespace Mono.CSharp {
                {
                        this.instance_expr = instance_expr;
                        this.is_base_indexer = is_base_indexer;
-                       this.eclass = ExprClass.Value;
                        this.loc = loc;
                }
 
@@ -8548,16 +8509,15 @@ namespace Mono.CSharp {
                        current_type = ec.CurrentType;
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return ResolveAccessor (ec, null);
                }
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
                {
-                       if (right_side == EmptyExpression.OutAccess) {
-                               ec.Report.Error (206, loc,
-                                       "A property or indexer may not be passed as an out or ref parameter");
+                       if (right_side == EmptyExpression.OutAccess.Instance) {
+                               right_side.DoResolveLValue (ec, this);
                                return null;
                        }
 
@@ -8573,39 +8533,50 @@ namespace Mono.CSharp {
                {
                        CommonResolve (ec);
 
+                       MethodGroupExpr mg;
+                       Indexers ilist;
                        bool dynamic;
+
                        arguments.Resolve (ec, out dynamic);
-                       if (dynamic || TypeManager.IsDynamicType (indexer_type)) {
-                               int additional = right_side == null ? 1 : 2;
-                               Arguments args = new Arguments (arguments.Count + additional);
+
+                       if (TypeManager.IsDynamicType (indexer_type)) {
+                               dynamic = true;
+                               mg = null;
+                               ilist = null;
+                       } else {
+                               ilist = Indexers.GetIndexersForType (current_type, indexer_type);
+                               if (ilist.Methods == null) {
+                                       ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
+                                                         TypeManager.CSharpName (indexer_type));
+                                       return null;
+                               }
+
+                               mg = new IndexerMethodGroupExpr (ilist, loc);
+                               mg = mg.OverloadResolve (ec, ref arguments, false, loc);
+                               if (mg == null)
+                                       return null;
+                       }
+
+                       if (dynamic) {
+                               Arguments args = new Arguments (arguments.Count + 1);
                                if (is_base_indexer) {
                                        ec.Report.Error (1972, loc, "The indexer base access cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access");
                                } else {
                                        args.Add (new Argument (instance_expr));
                                }
                                args.AddRange (arguments);
-                               if (right_side != null)
-                                       args.Add (new Argument (right_side));
 
-                               return new DynamicIndexBinder (right_side != null, args, loc).Resolve (ec);
-                       }
+                               var expr = new DynamicIndexBinder (args, loc);
+                               if (right_side != null)
+                                       return expr.ResolveLValue (ec, right_side);
 
-                       Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type);
-                       if (ilist.Methods == null) {
-                               ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
-                                                 TypeManager.CSharpName (indexer_type));
-                               return null;
+                               return expr.Resolve (ec);
                        }
 
-                       MethodGroupExpr mg = new IndexerMethodGroupExpr (ilist, loc);
-                       mg = mg.OverloadResolve (ec, ref arguments, false, loc);
-                       if (mg == null)
-                               return null;
-
-                       MethodInfo mi = (MethodInfo) mg;
+                       var mi = (MethodSpec) mg;
                        PropertyInfo pi = null;
                        for (int i = 0; i < ilist.Methods.Count; ++i) {
-                               if (ilist.Methods [i] == mi) {
+                               if (ilist.Methods [i].MetaInfo == mi.MetaInfo) {
                                        pi = (PropertyInfo) ilist.Properties [i];
                                        break;
                                }
@@ -8615,11 +8586,15 @@ namespace Mono.CSharp {
                        if (type.IsPointer && !ec.IsUnsafe)
                                UnsafeError (ec, loc);
 
-                       MethodInfo accessor;
+                       MethodSpec accessor = null;
                        if (right_side == null) {
-                               accessor = get = pi.GetGetMethod (true);
+                               var m = pi.GetGetMethod (true);
+                               if (m != null)
+                                       accessor = get = Import.CreateMethod (m);
                        } else {
-                               accessor = set = pi.GetSetMethod (true);
+                               var m = pi.GetSetMethod (true);
+                               if (m != null)
+                                       accessor = set = Import.CreateMethod (m);
                                if (accessor == null && pi.GetGetMethod (true) != null) {
                                        ec.Report.SymbolRelatedToPreviousError (pi);
                                        ec.Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to",
@@ -8646,14 +8621,19 @@ namespace Mono.CSharp {
 
                        bool must_do_cs1540_check;
                        if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
-                               if (set == null)
-                                       set = pi.GetSetMethod (true);
-                               else
-                                       get = pi.GetGetMethod (true);
+                               if (set == null) {
+                                       var m = pi.GetSetMethod (true);
+                                       if (m != null)
+                                               set = Import.CreateMethod (m);
+                               } else {
+                                       var m = pi.GetGetMethod (true);
+                                       if (m != null)
+                                               get = Import.CreateMethod (m);
+                               }
 
                                if (set != null && get != null &&
-                                       (set.Attributes & MethodAttributes.MemberAccessMask) != (get.Attributes & MethodAttributes.MemberAccessMask)) {
-                                       ec.Report.SymbolRelatedToPreviousError (accessor);
+                                       (set.MetaInfo.Attributes & MethodAttributes.MemberAccessMask) != (get.MetaInfo.Attributes & MethodAttributes.MemberAccessMask)) {
+                                       ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
                                        ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible",
                                                TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
                                } else {
@@ -8663,9 +8643,24 @@ namespace Mono.CSharp {
                        }
 
                        instance_expr.CheckMarshalByRefAccess (ec);
+
+                       if (must_do_cs1540_check && (instance_expr != EmptyExpression.Null) &&
+                           !TypeManager.IsInstantiationOfSameGenericType (instance_expr.Type, ec.CurrentType) &&
+                           !TypeManager.IsNestedChildOf (ec.CurrentType, instance_expr.Type) &&
+                           !TypeManager.IsSubclassOf (instance_expr.Type, ec.CurrentType)) {
+                               ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
+                               Error_CannotAccessProtected (ec, loc, accessor.MetaInfo, instance_expr.Type, ec.CurrentType);
+                               return null;
+                       }
+
                        eclass = ExprClass.IndexerAccess;
                        return this;
                }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
                
                public void Emit (EmitContext ec, bool leave_copy)
                {
@@ -8725,22 +8720,35 @@ namespace Mono.CSharp {
                        }
                }
                
-               public override void Emit (EmitContext ec)
+               public override string GetSignatureForError ()
                {
-                       Emit (ec, false);
+                       return TypeManager.CSharpSignature (get != null ? get.MetaInfo : set.MetaInfo, false);
                }
 
-               public override string GetSignatureForError ()
+#if NET_4_0
+               public SLE.Expression MakeAssignExpression (BuilderContext ctx)
+               {
+                       var value = new[] { set_expr.MakeExpression (ctx) };
+                       var args = Arguments.MakeExpression (arguments, ctx).Concat (value);
+
+                       return SLE.Expression.Block (
+                                       SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) set.MetaInfo, args),
+                                       value [0]);
+               }
+#endif
+
+               public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return TypeManager.CSharpSignature (get != null ? get : set, false);
+                       var args = Arguments.MakeExpression (arguments, ctx);
+                       return SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) get.MetaInfo, args);
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        if (get != null)
-                               get = storey.MutateGenericMethod (get);
+                               storey.MutateGenericMethod (get);
                        if (set != null)
-                               set = storey.MutateGenericMethod (set);
+                               storey.MutateGenericMethod (set);
 
                        instance_expr.MutateHoistedGenericType (storey);
                        if (arguments != null)
@@ -8785,7 +8793,7 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        Expression c = CommonResolve (ec);
 
@@ -8924,7 +8932,19 @@ namespace Mono.CSharp {
        public class EmptyExpression : Expression {
                public static readonly Expression Null = new EmptyExpression ();
 
-               public static readonly EmptyExpression OutAccess = new EmptyExpression ();
+               public class OutAccess : EmptyExpression
+               {
+                       public static readonly OutAccess Instance = new OutAccess ();
+
+                       public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
+                       {
+                               rc.Report.Error (206, right_side.Location,
+                                       "A property, indexer or dynamic member access may not be passed as `ref' or `out' parameter");
+
+                               return null;
+                       }
+               }
+
                public static readonly EmptyExpression LValueMemberAccess = new EmptyExpression ();
                public static readonly EmptyExpression LValueMemberOutAccess = new EmptyExpression ();
                public static readonly EmptyExpression UnaryAddress = new EmptyExpression ();
@@ -8962,7 +8982,7 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        return this;
                }
@@ -8996,7 +9016,6 @@ namespace Mono.CSharp {
 
                private EmptyExpressionStatement ()
                {
-                       eclass = ExprClass.Value;
                        loc = Location.Null;
                }
 
@@ -9010,8 +9029,9 @@ namespace Mono.CSharp {
                        // Do nothing
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
+                       eclass = ExprClass.Value;
                        type = TypeManager.object_type;
                        return this;
                }
@@ -9023,10 +9043,10 @@ namespace Mono.CSharp {
        }       
 
        public class UserCast : Expression {
-               MethodInfo method;
+               MethodSpec method;
                Expression source;
                
-               public UserCast (MethodInfo method, Expression source, Location l)
+               public UserCast (MethodSpec method, Expression source, Location l)
                {
                        this.method = method;
                        this.source = source;
@@ -9049,9 +9069,9 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Convert", args);
                }
                        
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method);
+                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method.MetaInfo);
                        if (oa != null)
                                AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
 
@@ -9062,25 +9082,23 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        source.Emit (ec);
-                       ec.ig.Emit (OpCodes.Call, method);
+                       ec.ig.Emit (OpCodes.Call, (MethodInfo) method.MetaInfo);
                }
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpSignature (method);
+                       return TypeManager.CSharpSignature (method.MetaInfo);
                }
 
-#if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Convert (source.MakeExpression (ctx), type, method);
+                       return SLE.Expression.Convert (source.MakeExpression (ctx), type, (MethodInfo) method.MetaInfo);
                }
-#endif
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        source.MutateHoistedGenericType (storey);
-                       method = storey.MutateGenericMethod (method);
+                       storey.MutateGenericMethod (method);
                }
        }
 
@@ -9120,7 +9138,7 @@ namespace Mono.CSharp {
                                return nullable.ResolveAsTypeTerminal (ec, false);
                        }
 
-                       if (dim == "*" && !TypeManager.VerifyUnManaged (ltype, loc))
+                       if (dim == "*" && !TypeManager.VerifyUnmanaged (ec.Compiler, ltype, loc))
                                return null;
 
                        if (dim.Length != 0 && dim [0] == '[') {
@@ -9186,7 +9204,7 @@ namespace Mono.CSharp {
                        array.Emit (ec);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        //
                        // We are born fully resolved
@@ -9226,29 +9244,30 @@ namespace Mono.CSharp {
        public class ArrayIndexCast : TypeCast
        {
                public ArrayIndexCast (Expression expr)
-                       : base (expr, expr.Type)
+                       : base (expr, TypeManager.int32_type)
                {
-                       if (type == TypeManager.int32_type)
-                               throw new ArgumentException ("unnecessary conversion");
+                       if (expr.Type == TypeManager.int32_type)
+                               throw new ArgumentException ("unnecessary array index conversion");
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
-                       Arguments args = new Arguments (2);
-                       args.Add (new Argument (child.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOf (new TypeExpression (TypeManager.int32_type, loc), loc)));
-                       return CreateExpressionFactoryCall (ec, "ConvertChecked", args);
+                       using (ec.Set (ResolveContext.Options.CheckedScope)) {
+                               return base.CreateExpressionTree (ec);
+                       }
                }
 
                public override void Emit (EmitContext ec)
                {
                        child.Emit (ec);
 
-                       if (type == TypeManager.uint32_type)
+                       var expr_type = child.Type;
+
+                       if (expr_type == TypeManager.uint32_type)
                                ec.ig.Emit (OpCodes.Conv_U);
-                       else if (type == TypeManager.int64_type)
+                       else if (expr_type == TypeManager.int64_type)
                                ec.ig.Emit (OpCodes.Conv_Ovf_I);
-                       else if (type == TypeManager.uint64_type)
+                       else if (expr_type == TypeManager.uint64_type)
                                ec.ig.Emit (OpCodes.Conv_Ovf_I_Un);
                        else
                                throw new InternalErrorException ("Cannot emit cast to unknown array element type", type);
@@ -9280,7 +9299,7 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        count = count.Resolve (ec);
                        if (count == null)
@@ -9307,7 +9326,7 @@ namespace Mono.CSharp {
 
                        otype = texpr.Type;
 
-                       if (!TypeManager.VerifyUnManaged (otype, loc))
+                       if (!TypeManager.VerifyUnmanaged (ec.Compiler, otype, loc))
                                return null;
 
                        type = TypeManager.GetPointerType (otype);
@@ -9374,7 +9393,7 @@ namespace Mono.CSharp {
                                args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        if (source == null)
                                return EmptyExpressionStatement.Instance;
@@ -9410,7 +9429,7 @@ namespace Mono.CSharp {
                        //
                        Constant c = source as Constant;
                        if (c != null && c.IsDefaultInitializer (type) && target.eclass == ExprClass.Variable)
-                               return EmptyExpressionStatement.Instance.DoResolve (ec);
+                               return EmptyExpressionStatement.Instance.Resolve (ec);
 
                        return expr;
                }
@@ -9473,7 +9492,7 @@ namespace Mono.CSharp {
                        this.loc = argument.Location;
                }
 
-               public CollectionElementInitializer (ArrayList arguments, Location loc)
+               public CollectionElementInitializer (List<Expression> arguments, Location loc)
                        : base (null, new Arguments (arguments.Count))
                {
                        foreach (Expression e in arguments)
@@ -9487,7 +9506,7 @@ namespace Mono.CSharp {
                        Arguments args = new Arguments (2);
                        args.Add (new Argument (mg.CreateExpressionTree (ec)));
 
-                       ArrayList expr_initializers = new ArrayList (arguments.Count);
+                       var expr_initializers = new ArrayInitializer (arguments.Count, loc);
                        foreach (Argument a in arguments)
                                expr_initializers.Add (a.CreateExpressionTree (ec));
 
@@ -9503,11 +9522,8 @@ namespace Mono.CSharp {
                                target.arguments = arguments.Clone (clonectx);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-
                        base.expr = new AddMemberAccess (ec.CurrentInitializerVariable, loc);
 
                        return base.DoResolve (ec);
@@ -9519,13 +9535,13 @@ namespace Mono.CSharp {
        //
        public class CollectionOrObjectInitializers : ExpressionStatement
        {
-               ArrayList initializers;
+               IList<Expression> initializers;
                bool is_collection_initialization;
                
                public static readonly CollectionOrObjectInitializers Empty = 
-                       new CollectionOrObjectInitializers (new ArrayList (0), Location.Null);
+                       new CollectionOrObjectInitializers (Array.AsReadOnly (new Expression [0]), Location.Null);
 
-               public CollectionOrObjectInitializers (ArrayList initializers, Location loc)
+               public CollectionOrObjectInitializers (IList<Expression> initializers, Location loc)
                {
                        this.initializers = initializers;
                        this.loc = loc;
@@ -9547,14 +9563,14 @@ namespace Mono.CSharp {
                {
                        CollectionOrObjectInitializers t = (CollectionOrObjectInitializers) target;
 
-                       t.initializers = new ArrayList (initializers.Count);
-                       foreach (Expression e in initializers)
+                       t.initializers = new List<Expression> (initializers.Count);
+                       foreach (var e in initializers)
                                t.initializers.Add (e.Clone (clonectx));
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
-                       ArrayList expr_initializers = new ArrayList (initializers.Count);
+                       var expr_initializers = new ArrayInitializer (initializers.Count, loc);
                        foreach (Expression e in initializers) {
                                Expression expr = e.CreateExpressionTree (ec);
                                if (expr != null)
@@ -9564,19 +9580,16 @@ namespace Mono.CSharp {
                        return new ImplicitlyTypedArrayCreation ("[]", expr_initializers, loc);
                }
                
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-
-                       ArrayList element_names = null;
+                       List<string> element_names = null;
                        for (int i = 0; i < initializers.Count; ++i) {
                                Expression initializer = (Expression) initializers [i];
                                ElementInitializer element_initializer = initializer as ElementInitializer;
 
                                if (i == 0) {
                                        if (element_initializer != null) {
-                                               element_names = new ArrayList (initializers.Count);
+                                               element_names = new List<string> (initializers.Count);
                                                element_names.Add (element_initializer.Name);
                                        } else if (initializer is CompletingExpression){
                                                initializer.Resolve (ec);
@@ -9675,7 +9688,7 @@ namespace Mono.CSharp {
                                throw new NotSupportedException ("ET");
                        }
 
-                       public override Expression DoResolve (ResolveContext ec)
+                       protected override Expression DoResolve (ResolveContext ec)
                        {
                                return this;
                        }
@@ -9740,11 +9753,8 @@ namespace Mono.CSharp {
                                args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       if (eclass != ExprClass.Invalid)
-                               return this;
-                       
                        Expression e = base.DoResolve (ec);
                        if (type == null)
                                return null;
@@ -9806,17 +9816,19 @@ namespace Mono.CSharp {
                }
        }
 
-       public class AnonymousTypeDeclaration : Expression
+       public class NewAnonymousType : New
        {
-               ArrayList parameters;
+               static readonly IList<AnonymousTypeParameter> EmptyParameters = Array.AsReadOnly (new AnonymousTypeParameter[0]);
+
+               List<AnonymousTypeParameter> parameters;
                readonly TypeContainer parent;
-               static readonly ArrayList EmptyParameters = new ArrayList (0);
+               AnonymousTypeClass anonymous_type;
 
-               public AnonymousTypeDeclaration (ArrayList parameters, TypeContainer parent, Location loc)
+               public NewAnonymousType (List<AnonymousTypeParameter> parameters, TypeContainer parent, Location loc)
+                        : base (null, null, loc)
                {
                        this.parameters = parameters;
                        this.parent = parent;
-                       this.loc = loc;
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression target)
@@ -9824,15 +9836,15 @@ namespace Mono.CSharp {
                        if (parameters == null)
                                return;
 
-                       AnonymousTypeDeclaration t = (AnonymousTypeDeclaration) target;
-                       t.parameters = new ArrayList (parameters.Count);
+                       NewAnonymousType t = (NewAnonymousType) target;
+                       t.parameters = new List<AnonymousTypeParameter> (parameters.Count);
                        foreach (AnonymousTypeParameter atp in parameters)
-                               t.parameters.Add (atp.Clone (clonectx));
+                               t.parameters.Add ((AnonymousTypeParameter) atp.Clone (clonectx));
                }
 
-               AnonymousTypeClass CreateAnonymousType (ResolveContext ec, ArrayList parameters)
+               AnonymousTypeClass CreateAnonymousType (ResolveContext ec, IList<AnonymousTypeParameter> parameters)
                {
-                       AnonymousTypeClass type = parent.Module.GetAnonymousType (parameters);
+                       AnonymousTypeClass type = parent.Module.Compiled.GetAnonymousType (parameters);
                        if (type != null)
                                return type;
 
@@ -9846,19 +9858,33 @@ namespace Mono.CSharp {
                        if (ec.Report.Errors == 0)
                                type.CloseType ();
 
-                       parent.Module.AddAnonymousType (type);
+                       parent.Module.Compiled.AddAnonymousType (type);
                        return type;
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
-                       throw new NotSupportedException ("ET");
+                       if (parameters == null)
+                               return base.CreateExpressionTree (ec);
+
+                       var init = new ArrayInitializer (parameters.Count, loc);
+                       foreach (Property p in anonymous_type.Properties)
+                               init.Add (new TypeOfMethod (Import.CreateMethod (TypeBuilder.GetMethod (type, p.GetBuilder)), loc));
+
+                       var ctor_args = new ArrayInitializer (Arguments.Count, loc);
+                       foreach (Argument a in Arguments)
+                               ctor_args.Add (a.CreateExpressionTree (ec));
+
+                       Arguments args = new Arguments (3);
+                       args.Add (new Argument (method.CreateExpressionTree (ec)));
+                       args.Add (new Argument (new ArrayCreation (TypeManager.expression_type_expr, "[]", ctor_args, loc)));
+                       args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", init, loc)));
+
+                       return CreateExpressionFactoryCall (ec, "New", args);
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
-                       AnonymousTypeClass anonymous_type;
-
                        if (ec.HasSet (ResolveContext.Options.ConstantScope)) {
                                ec.Report.Error (836, loc, "Anonymous types cannot be used in this expression");
                                return null;
@@ -9866,12 +9892,12 @@ namespace Mono.CSharp {
 
                        if (parameters == null) {
                                anonymous_type = CreateAnonymousType (ec, EmptyParameters);
-                               return new New (new TypeExpression (anonymous_type.TypeBuilder, loc),
-                                       null, loc).Resolve (ec);
+                               RequestedType = new TypeExpression (anonymous_type.TypeBuilder, loc);
+                               return base.DoResolve (ec);
                        }
 
                        bool error = false;
-                       Arguments 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);
@@ -9880,7 +9906,7 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               arguments.Add (new Argument (e));
+                               Arguments.Add (new Argument (e));
                                t_args [i] = new TypeExpression (e.Type, e.Location);
                        }
 
@@ -9891,15 +9917,8 @@ namespace Mono.CSharp {
                        if (anonymous_type == null)
                                return null;
 
-                       GenericTypeExpr te = new GenericTypeExpr (anonymous_type.TypeBuilder,
-                               new TypeArguments (t_args), loc);
-
-                       return new New (te, arguments, loc).Resolve (ec);
-               }
-
-               public override void Emit (EmitContext ec)
-               {
-                       throw new InternalErrorException ("Should not be reached");
+                       RequestedType = new GenericTypeExpr (anonymous_type.TypeBuilder, new TypeArguments (t_args), loc);
+                       return base.DoResolve (ec);
                }
        }
 
@@ -9932,7 +9951,7 @@ namespace Mono.CSharp {
                        return Name.GetHashCode ();
                }
 
-               public override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        Expression e = expr.Resolve (ec);
                        if (e == null)