2009-07-22 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / expression.cs
index b48fd1358c860f5b031fae69e740aacbed6b3e12..c9a7ab18eb6db7423553acbd0d87adef93c3291c 100644 (file)
@@ -24,11 +24,11 @@ namespace Mono.CSharp {
        public class UserOperatorCall : Expression {
                public delegate Expression ExpressionTreeExpression (EmitContext ec, MethodGroupExpr mg);
 
-               protected readonly ArrayList arguments;
+               protected readonly Arguments arguments;
                protected readonly MethodGroupExpr mg;
                readonly ExpressionTreeExpression expr_tree;
 
-               public UserOperatorCall (MethodGroupExpr mg, ArrayList args, ExpressionTreeExpression expr_tree, Location loc)
+               public UserOperatorCall (MethodGroupExpr mg, Arguments args, ExpressionTreeExpression expr_tree, Location loc)
                {
                        this.mg = mg;
                        this.arguments = args;
@@ -44,12 +44,9 @@ namespace Mono.CSharp {
                        if (expr_tree != null)
                                return expr_tree (ec, mg);
 
-                       ArrayList args = new ArrayList (arguments.Count + 1);
-                       args.Add (new Argument (new NullLiteral (loc)));
-                       args.Add (new Argument (mg.CreateExpressionTree (ec)));
-                       foreach (Argument a in arguments) {
-                               args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
-                       }
+                       Arguments args = Arguments.CreateForExpressionTree (ec, arguments,
+                               new NullLiteral (loc),
+                               mg.CreateExpressionTree (ec));
 
                        return CreateExpressionFactoryCall ("Call", args);
                }
@@ -78,9 +75,7 @@ namespace Mono.CSharp {
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       foreach (Argument a in arguments)
-                               a.Expr.MutateHoistedGenericType (storey);
-
+                       arguments.MutateHoistedGenericType (storey);
                        mg.MutateHoistedGenericType (storey);
                }
        }
@@ -106,6 +101,11 @@ namespace Mono.CSharp {
                        return Expr;
                }
 
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return Expr.DoResolveLValue (ec, right_side);
+               }
+
                public override void Emit (EmitContext ec)
                {
                        throw new Exception ("Should not happen");
@@ -122,7 +122,8 @@ namespace Mono.CSharp {
        //
        //   Unary implements unary expressions.
        //
-       public class Unary : Expression {
+       public class Unary : Expression
+       {
                public enum Operator : byte {
                        UnaryPlus, UnaryNegation, LogicalNot, OnesComplement,
                        AddressOf,  TOP
@@ -134,11 +135,11 @@ namespace Mono.CSharp {
                public Expression Expr;
                Expression enum_conversion;
 
-               public Unary (Operator op, Expression expr, Location loc)
+               public Unary (Operator op, Expression expr)
                {
                        Oper = op;
                        Expr = expr;
-                       this.loc = loc;
+                       loc = expr.Location;
                }
 
                // <summary>
@@ -238,20 +239,17 @@ namespace Mono.CSharp {
                                if (expr_type == TypeManager.float_type) {
                                        FloatLiteral fl = e as FloatLiteral;
                                        // For better error reporting
-                                       if (fl != null) {
-                                               fl.Value = -fl.Value;
-                                               return fl;
-                                       }
+                                       if (fl != null)
+                                               return new FloatLiteral (-fl.Value, e.Location);
+
                                        return new FloatConstant (-((FloatConstant)e).Value, e.Location);
                                }
                                if (expr_type == TypeManager.double_type) {
                                        DoubleLiteral dl = e as DoubleLiteral;
                                        // For better error reporting
-                                       if (dl != null) {
-                                               dl.Value = -dl.Value;
-                                               return dl;
-                                       }
-                                       
+                                       if (dl != null)
+                                               return new DoubleLiteral (-dl.Value, e.Location);
+
                                        return new DoubleConstant (-((DoubleConstant)e).Value, e.Location);
                                }
                                if (expr_type == TypeManager.decimal_type)
@@ -374,7 +372,7 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("Unknown unary operator " + Oper.ToString ());
                        }
 
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (Expr.CreateExpressionTree (ec)));
                        if (user_op != null)
                                args.Add (new Argument (user_op.CreateExpressionTree (ec)));
@@ -449,8 +447,14 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return null;
 
-                       if (TypeManager.IsNullableValueType (Expr.Type))
-                               return new Nullable.LiftedUnaryOperator (Oper, Expr, loc).Resolve (ec);
+                       if (Expr.Type == InternalType.Dynamic) {
+                               Arguments args = new Arguments (1);
+                               args.Add (new Argument (Expr));
+                               return new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc).DoResolve (ec);
+                       }
+
+                       if (TypeManager.IsNullableType (Expr.Type))
+                               return new Nullable.LiftedUnaryOperator (Oper, Expr).Resolve (ec);
 
                        //
                        // Attempt to use a constant folding operation.
@@ -554,6 +558,19 @@ namespace Mono.CSharp {
                                oper, TypeManager.CSharpName (t));
                }
 
+               //
+               // Converts operator to System.Linq.Expressions.ExpressionType enum name
+               //
+               string GetOperatorExpressionTypeName ()
+               {
+                       switch (Oper) {
+                       case Operator.UnaryPlus:
+                               return "UnaryPlus";
+                       default:
+                               throw new NotImplementedException ("Unknown express type operator " + Oper.ToString ());
+                       }
+               }
+
                static bool IsFloat (Type t)
                {
                        return t == TypeManager.float_type || t == TypeManager.double_type;
@@ -671,14 +688,14 @@ namespace Mono.CSharp {
                        if (user_op == null)
                                return null;
 
-                       ArrayList args = new ArrayList (1);
+                       Arguments args = new Arguments (1);
                        args.Add (new Argument (expr));
                        user_op = user_op.OverloadResolve (ec, ref args, false, expr.Location);
 
                        if (user_op == null)
                                return null;
 
-                       Expr = ((Argument) args [0]).Expr;
+                       Expr = args [0].Expr;
                        return new UserOperatorCall (user_op, args, CreateExpressionTree, expr.Location);
                }
 
@@ -899,10 +916,10 @@ namespace Mono.CSharp {
                //
                UserOperatorCall method;
 
-               public UnaryMutator (Mode m, Expression e, Location l)
+               public UnaryMutator (Mode m, Expression e)
                {
                        mode = m;
-                       loc = l;
+                       loc = e.Location;
                        expr = e;
                }
 
@@ -938,6 +955,17 @@ namespace Mono.CSharp {
                Expression ResolveOperator (EmitContext 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 {
+                               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
@@ -953,8 +981,8 @@ namespace Mono.CSharp {
                        mg = MemberLookup (ec.ContainerType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
 
                        if (mg != null) {
-                               ArrayList args = new ArrayList (1);
-                               args.Add (new Argument (expr, Argument.AType.Expression));
+                               Arguments args = new Arguments (1);
+                               args.Add (new Argument (expr));
                                mg = mg.OverloadResolve (ec, ref args, false, loc);
                                if (mg == null)
                                        return null;
@@ -970,17 +998,6 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       //
-                       // 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, Location);
-                       } else {
-                               Report.Error (1059, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
-                       }
-
                        return this;
                }
 
@@ -998,10 +1015,8 @@ namespace Mono.CSharp {
 
                        eclass = ExprClass.Value;
 
-#if GMCS_SOURCE
-                       if (TypeManager.IsNullableValueType (expr.Type))
+                       if (TypeManager.IsNullableType (expr.Type))
                                return new Nullable.LiftedUnaryMutator (mode, expr, loc).Resolve (ec);
-#endif
 
                        return ResolveOperator (ec);
                }
@@ -1155,7 +1170,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (expr.Type == TypeManager.anonymous_method_type) {
+                       if (expr.Type == InternalType.AnonymousMethod) {
                                Report.Error (837, loc, "The `{0}' operator cannot be applied to a lambda expression or anonymous method",
                                        OperatorName);
                                return null;
@@ -1195,9 +1210,10 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
-                       args.Add (new Argument (expr.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOf (probe_type_expr, loc)));
+                       Arguments args = Arguments.CreateForExpressionTree (ec, null,
+                               expr.CreateExpressionTree (ec),
+                               new TypeOf (probe_type_expr, loc));
+
                        return CreateExpressionFactoryCall ("TypeIs", args);
                }
                
@@ -1268,13 +1284,13 @@ namespace Mono.CSharp {
                                t_is_nullable = true;
                        }
 
-                       if (t.IsValueType) {
+                       if (TypeManager.IsStruct (t)) {
                                if (d == t) {
                                        //
                                        // D and T are the same value types but D can be null
                                        //
                                        if (d_is_nullable && !t_is_nullable) {
-                                               expr_unwrap = Nullable.Unwrap.Create (expr, ec);
+                                               expr_unwrap = Nullable.Unwrap.Create (expr, false);
                                                return this;
                                        }
                                        
@@ -1296,7 +1312,7 @@ namespace Mono.CSharp {
                                if (TypeManager.IsGenericParameter (t))
                                        return ResolveGenericParameter (d, t);
 
-                               if (d.IsValueType) {
+                               if (TypeManager.IsStruct (d)) {
                                        bool temp;
                                        if (Convert.ImplicitBoxingConversionExists (expr, t, out temp))
                                                return CreateConstantResult (true);
@@ -1319,23 +1335,19 @@ namespace Mono.CSharp {
 
                Expression ResolveGenericParameter (Type d, Type t)
                {
-#if GMCS_SOURCE
                        GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
                        if (constraints != null) {
-                               if (constraints.IsReferenceType && d.IsValueType)
+                               if (constraints.IsReferenceType && TypeManager.IsStruct (d))
                                        return CreateConstantResult (false);
 
-                               if (constraints.IsValueType && !d.IsValueType)
+                               if (constraints.IsValueType && !TypeManager.IsStruct (d))
                                        return CreateConstantResult (TypeManager.IsEqual (d, t));
                        }
 
-                       if (!TypeManager.IsReferenceType (expr.Type))
+                       if (TypeManager.IsGenericParameter (expr.Type))
                                expr = new BoxedCast (expr, d);
 
                        return this;
-#else
-                       return null;
-#endif
                }
                
                protected override string OperatorName {
@@ -1357,9 +1369,10 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
-                       args.Add (new Argument (expr.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOf (probe_type_expr, loc)));
+                       Arguments args = Arguments.CreateForExpressionTree (ec, null,
+                               expr.CreateExpressionTree (ec),
+                               new TypeOf (probe_type_expr, loc));
+
                        return CreateExpressionFactoryCall ("TypeAs", args);
                }
 
@@ -1370,16 +1383,20 @@ namespace Mono.CSharp {
                        expr.Emit (ec);
 
                        if (do_isinst)
-                               ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
+                               ig.Emit (OpCodes.Isinst, type);
 
 #if GMCS_SOURCE
-                       if (TypeManager.IsNullableType (type))
+                       if (TypeManager.IsGenericParameter (type) || TypeManager.IsNullableType (type))
                                ig.Emit (OpCodes.Unbox_Any, type);
 #endif
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       // Because expr is modified
+                       if (eclass != ExprClass.Invalid)
+                               return this;
+
                        if (resolved_type == null) {
                                resolved_type = base.DoResolve (ec);
 
@@ -1394,7 +1411,7 @@ namespace Mono.CSharp {
                        if (!TypeManager.IsReferenceType (type) && !TypeManager.IsNullableType (type)) {
                                if (probe_type_expr is TypeParameterExpr) {
                                        Report.Error (413, loc,
-                                               "The `as' operator cannot be used with a non-reference type parameter `{0}'",
+                                               "The `as' operator cannot be used with a non-reference type parameter `{0}'. Consider adding `class' or a reference type constraint",
                                                probe_type_expr.GetSignatureForError ());
                                } else {
                                        Report.Error (77, loc,
@@ -1439,6 +1456,12 @@ namespace Mono.CSharp {
                protected override string OperatorName {
                        get { return "as"; }
                }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       type = storey.MutateType (type);
+                       base.MutateHoistedGenericType (storey);
+               }
        
                public override bool GetAttributableValue (EmitContext ec, Type value_type, out object value)
                {
@@ -1534,6 +1557,20 @@ 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 (EmitContext ec, Location loc, Type t, bool expl)
+                       {
+                               Error_ValueCannotBeConvertedCore (ec, loc, t, expl);
+                       }
+               }
+
+
                Expression expr;
 
                public DefaultValueExpression (Expression expr, Location loc)
@@ -1544,7 +1581,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (this));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        return CreateExpressionFactoryCall ("Constant", args);
@@ -1565,12 +1602,8 @@ namespace Mono.CSharp {
                        if (type.IsPointer)
                                return new NullLiteral (Location).ConvertImplicitly (type);
 
-                       if (TypeManager.IsReferenceType (type)) {
-                               return new EmptyConstantCast (new NullLiteral (Location), type);
-
-                               // TODO: ET needs
-                               // return ReducedExpression.Create (new NullLiteral (Location), this);
-                       }
+                       if (TypeManager.IsReferenceType (type))
+                               return new DefaultValueNullLiteral (this);
 
                        Constant c = New.Constantify (type);
                        if (c != null)
@@ -1605,7 +1638,8 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Binary operators
        /// </summary>
-       public class Binary : Expression {
+       public class Binary : Expression, IDynamicBinder
+       {
 
                protected class PredefinedOperator {
                        protected readonly Type left;
@@ -1975,16 +2009,8 @@ namespace Mono.CSharp {
                public static void Error_OperatorCannotBeApplied (Expression left, Expression right, string oper, Location loc)
                {
                        string l, r;
-                       // TODO: This should be handled as Type of method group in CSharpName
-                       if (left.eclass == ExprClass.MethodGroup)
-                               l = left.ExprClassName;
-                       else
-                               l = TypeManager.CSharpName (left.Type);
-
-                       if (right.eclass == ExprClass.MethodGroup)
-                               r = right.ExprClassName;
-                       else
-                               r = TypeManager.CSharpName (right.Type);
+                       l = TypeManager.CSharpName (left.Type);
+                       r = TypeManager.CSharpName (right.Type);
 
                        Report.Error (19, loc, "Operator `{0}' cannot be applied to operands of type `{1}' and `{2}'",
                                oper, l, r);
@@ -1995,6 +2021,23 @@ namespace Mono.CSharp {
                        Error_OperatorCannotBeApplied (left, right, OperName (oper), loc);
                }
 
+               //
+               // Converts operator to System.Linq.Expressions.ExpressionType enum name
+               //
+               string GetOperatorExpressionTypeName ()
+               {
+                       switch (oper) {
+                       case Operator.Addition:
+                               return is_compound ? "AddAssign" : "Add";
+                       case Operator.Equality:
+                               return "Equal";
+                       case Operator.Multiply:
+                               return is_compound ? "MultiplyAssign" : "Multiply";
+                       default:
+                               throw new NotImplementedException ("Unknown expression type operator " + oper.ToString ());
+                       }
+               }
+
                static string GetOperatorMetadataName (Operator op)
                {
                        CSharp.Operator.OpType op_type;
@@ -2526,13 +2569,9 @@ namespace Mono.CSharp {
 
                        // The conversion rules are ignored in enum context but why
                        if (!ec.InEnumContext && lc != null && rc != null && (TypeManager.IsEnumType (left.Type) || TypeManager.IsEnumType (right.Type))) {
-                               left = lc = EnumLiftUp (ec, lc, rc, loc);
-                               if (lc == null)
-                                       return null;
-
-                               right = rc = EnumLiftUp (ec, rc, lc, loc);
-                               if (rc == null)
-                                       return null;
+                               lc = EnumLiftUp (ec, lc, rc, loc);
+                               if (lc != null)
+                                       rc = EnumLiftUp (ec, rc, lc, loc);
                        }
 
                        if (rc != null && lc != null) {
@@ -2570,9 +2609,18 @@ namespace Mono.CSharp {
                                CheckUselessComparison (rc, left.Type);
                        }
 
+                       if (left.Type == InternalType.Dynamic || right.Type == InternalType.Dynamic) {
+                               Arguments args = new Arguments (2);
+                               args.Add (new Argument (left));
+                               args.Add (new Argument (right));
+                               return new DynamicExpressionStatement (this, args, loc).Resolve (ec);
+                       }
+
                        if (RootContext.Version >= LanguageVersion.ISO_2 &&
-                               (TypeManager.IsNullableType (left.Type) || TypeManager.IsNullableType (right.Type) ||
-                               (left is NullLiteral && right.Type.IsValueType) || (right is NullLiteral && left.Type.IsValueType)))
+                               ((TypeManager.IsNullableType (left.Type) && (right is NullLiteral || TypeManager.IsNullableType (right.Type) || TypeManager.IsValueType (right.Type))) ||
+                               (TypeManager.IsValueType (left.Type) && right is NullLiteral) ||
+                               (TypeManager.IsNullableType (right.Type) && (left is NullLiteral || TypeManager.IsNullableType (left.Type) || TypeManager.IsValueType (left.Type))) ||
+                               (TypeManager.IsValueType (right.Type) && left is NullLiteral)))
                                return new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
 
                        return DoResolveCore (ec, left, right);
@@ -2608,15 +2656,15 @@ namespace Mono.CSharp {
                Expression ResolveOperatorDelegate (EmitContext ec, Type l, Type r)
                {
                        bool is_equality = (oper & Operator.EqualityMask) != 0;
-                       if (!TypeManager.IsEqual (l, r)) {
+                       if (!TypeManager.IsEqual (l, r) && !TypeManager.IsVariantOf (r, l)) {
                                Expression tmp;
-                               if (right.eclass == ExprClass.MethodGroup || (r == TypeManager.anonymous_method_type && !is_equality)) {
+                               if (right.eclass == ExprClass.MethodGroup || (r == InternalType.AnonymousMethod && !is_equality)) {
                                        tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
                                        if (tmp == null)
                                                return null;
                                        right = tmp;
                                        r = right.Type;
-                               } else if (left.eclass == ExprClass.MethodGroup || (l == TypeManager.anonymous_method_type && !is_equality)) {
+                               } else if (left.eclass == ExprClass.MethodGroup || (l == InternalType.AnonymousMethod && !is_equality)) {
                                        tmp = Convert.ImplicitConversionRequired (ec, left, r, loc);
                                        if (tmp == null)
                                                return null;
@@ -2634,9 +2682,9 @@ namespace Mono.CSharp {
                                return ResolveUserOperator (ec, l, r);
 
                        MethodInfo method;
-                       ArrayList args = new ArrayList (2);
-                       args.Add (new Argument (left, Argument.AType.Expression));
-                       args.Add (new Argument (right, Argument.AType.Expression));
+                       Arguments args = new Arguments (2);
+                       args.Add (new Argument (left));
+                       args.Add (new Argument (right));
 
                        if (oper == Operator.Addition) {
                                if (TypeManager.delegate_combine_delegate_delegate == null) {
@@ -2836,7 +2884,7 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               if (l == TypeManager.anonymous_method_type)
+                               if (l == InternalType.AnonymousMethod)
                                        return null;
 
                                if (TypeManager.IsValueType (l))
@@ -2884,7 +2932,7 @@ namespace Mono.CSharp {
                                        return null;
                        } else if (l.IsInterface) {
                                l = TypeManager.object_type;
-                       } else if (l.IsValueType) {
+                       } else if (TypeManager.IsStruct (l)) {
                                return null;
                        }
 
@@ -2894,7 +2942,7 @@ namespace Mono.CSharp {
                                        return null;
                        } else if (r.IsInterface) {
                                r = TypeManager.object_type;
-                       } else if (r.IsValueType) {
+                       } else if (TypeManager.IsStruct (r)) {
                                return null;
                        }
 
@@ -3041,7 +3089,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        Argument larg = new Argument (left);
                        args.Add (larg);
                        Argument rarg = new Argument (right);
@@ -3094,11 +3142,14 @@ namespace Mono.CSharp {
                                                type = TypeManager.bool_type;
                                                if (left is NullLiteral || right is NullLiteral)
                                                        oper_expr = ReducedExpression.Create (this, oper_expr).Resolve (ec);
-                                       } else if (union.DeclaringType == TypeManager.delegate_type && l != r) {
+                                       } else if (l != r) {
+                                               MethodInfo mi = (MethodInfo) union;
+                                               
                                                //
                                                // Two System.Delegate(s) are never equal
                                                //
-                                               return null;
+                                               if (mi.DeclaringType == TypeManager.multicast_delegate_type)
+                                                       return null;
                                        }
                                }
                        }
@@ -3453,6 +3504,25 @@ namespace Mono.CSharp {
                        target.left = left.Clone (clonectx);
                        target.right = right.Clone (clonectx);
                }
+
+               public Expression CreateCallSiteBinder (EmitContext ec, Arguments args)
+               {
+                       Arguments binder_args = new Arguments (4);
+
+                       MemberAccess sle = new MemberAccess (new MemberAccess (
+                               new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Linq", loc), "Expressions", loc);
+
+                       MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace (loc);
+
+                       binder_args.Add (new Argument (new MemberAccess (new MemberAccess (sle, "ExpressionType", loc), GetOperatorExpressionTypeName (), loc)));
+                       binder_args.Add (new Argument (new BoolLiteral (ec.CheckState, loc)));
+
+                       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)));
+
+                       return new New (new MemberAccess (binder, "CSharpBinaryOperationBinder", loc), binder_args, loc);
+               }
                
                public override Expression CreateExpressionTree (EmitContext ec)
                {
@@ -3539,7 +3609,7 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("Unknown expression tree binary operator " + oper);
                        }
 
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (left.CreateExpressionTree (ec)));
                        args.Add (new Argument (right.CreateExpressionTree (ec)));
                        if (method != null) {
@@ -3558,7 +3628,7 @@ namespace Mono.CSharp {
        // b, c, d... may be strings or objects.
        //
        public class StringConcat : Expression {
-               ArrayList arguments;
+               Arguments arguments;
                
                public StringConcat (EmitContext ec, Location loc, Expression left, Expression right)
                {
@@ -3566,15 +3636,15 @@ namespace Mono.CSharp {
                        type = TypeManager.string_type;
                        eclass = ExprClass.Value;
 
-                       arguments = new ArrayList (2);
+                       arguments = new Arguments (2);
                        Append (ec, left);
                        Append (ec, right);
                }
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       Argument arg = (Argument) arguments [0];
-                       return CreateExpressionAddCall (ec, arg, arg.Expr.CreateExpressionTree (ec), 1);
+                       Argument arg = arguments [0];
+                       return CreateExpressionAddCall (ec, arg, arg.CreateExpressionTree (ec), 1);
                }
 
                //
@@ -3582,14 +3652,14 @@ namespace Mono.CSharp {
                //
                Expression CreateExpressionAddCall (EmitContext ec, Argument left, Expression left_etree, int pos)
                {
-                       ArrayList concat_args = new ArrayList (2);
-                       ArrayList add_args = new ArrayList (3);
+                       Arguments concat_args = new Arguments (2);
+                       Arguments add_args = new Arguments (3);
 
                        concat_args.Add (left);
                        add_args.Add (new Argument (left_etree));
 
                        concat_args.Add (arguments [pos]);
-                       add_args.Add (new Argument (((Argument) arguments [pos]).Expr.CreateExpressionTree (ec)));
+                       add_args.Add (new Argument (arguments [pos].CreateExpressionTree (ec)));
 
                        MethodGroupExpr method = CreateConcatMemberExpression ().Resolve (ec) as MethodGroupExpr;
                        if (method == null)
@@ -3605,7 +3675,7 @@ namespace Mono.CSharp {
                        if (++pos == arguments.Count)
                                return expr;
 
-                       left = new Argument (new EmptyExpression (method.Type));
+                       left = new Argument (new EmptyExpression (((MethodInfo)method).ReturnType));
                        return CreateExpressionAddCall (ec, left, expr, pos);
                }
 
@@ -3622,7 +3692,7 @@ namespace Mono.CSharp {
                        StringConstant sc = operand as StringConstant;
                        if (sc != null) {
                                if (arguments.Count != 0) {
-                                       Argument last_argument = (Argument) arguments [arguments.Count - 1];
+                                       Argument last_argument = arguments [arguments.Count - 1];
                                        StringConstant last_expr_constant = last_argument.Expr as StringConstant;
                                        if (last_expr_constant != null) {
                                                last_argument.Expr = new StringConstant (
@@ -3659,8 +3729,7 @@ namespace Mono.CSharp {
                
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       foreach (Argument a in arguments)
-                               a.Expr.MutateHoistedGenericType (storey);
+                       arguments.MutateHoistedGenericType (storey);
                }               
        }
 
@@ -3671,7 +3740,7 @@ namespace Mono.CSharp {
                readonly bool is_and;
                Expression oper;
 
-               public ConditionalLogicalOperator (MethodGroupExpr oper_method, ArrayList arguments,
+               public ConditionalLogicalOperator (MethodGroupExpr oper_method, Arguments arguments,
                        ExpressionTreeExpression expr_tree, bool is_and, Location loc)
                        : base (oper_method, arguments, expr_tree, loc)
                {
@@ -3713,7 +3782,7 @@ namespace Mono.CSharp {
                        //
                        // Emit and duplicate left argument
                        //
-                       ((Argument)arguments [0]).Expr.Emit (ec);
+                       arguments [0].Expr.Emit (ec);
                        ig.Emit (OpCodes.Dup);
                        arguments.RemoveAt (0);
 
@@ -3894,7 +3963,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (3);
+                       Arguments args = new Arguments (3);
                        args.Add (new Argument (expr.CreateExpressionTree (ec)));
                        args.Add (new Argument (true_expr.CreateExpressionTree (ec)));
                        args.Add (new Argument (false_expr.CreateExpressionTree (ec)));
@@ -3903,18 +3972,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       expr = expr.Resolve (ec);
-
-                       if (expr == null)
-                               return null;
-
-                       if (expr.Type != TypeManager.bool_type){
-                               expr = Expression.ResolveBoolean (
-                                       ec, expr, loc);
-                               
-                               if (expr == null)
-                                       return null;
-                       }
+                       expr = Expression.ResolveBoolean (ec, expr, loc);
                        
                        Assign ass = expr as Assign;
                        if (ass != null && ass.Source is Constant) {
@@ -3924,7 +3982,7 @@ namespace Mono.CSharp {
                        true_expr = true_expr.Resolve (ec);
                        false_expr = false_expr.Resolve (ec);
 
-                       if (true_expr == null || false_expr == null)
+                       if (true_expr == null || false_expr == null || expr == null)
                                return null;
 
                        eclass = ExprClass.Value;
@@ -4022,7 +4080,7 @@ namespace Mono.CSharp {
                LocalTemporary temp;
 
                #region Abstract
-               public abstract HoistedVariable HoistedVariable { get; }
+               public abstract HoistedVariable GetHoistedVariable (EmitContext ec);
                public abstract bool IsFixed { get; }
                public abstract bool IsRef { get; }
                public abstract string Name { get; }
@@ -4041,8 +4099,9 @@ namespace Mono.CSharp {
 
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
-                       if (IsHoistedEmitRequired (ec)) {
-                               HoistedVariable.AddressOf (ec, mode);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null) {
+                               hv.AddressOf (ec, mode);
                                return;
                        }
 
@@ -4074,8 +4133,9 @@ namespace Mono.CSharp {
                {
                        Report.Debug (64, "VARIABLE EMIT", this, Variable, type, IsRef, loc);
 
-                       if (IsHoistedEmitRequired (ec)) {
-                               HoistedVariable.Emit (ec, leave_copy);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null) {
+                               hv.Emit (ec, leave_copy);
                                return;
                        }
 
@@ -4102,25 +4162,24 @@ namespace Mono.CSharp {
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy,
                                        bool prepare_for_load)
                {
-                       Report.Debug (64, "VARIABLE EMIT ASSIGN", this, Variable, type, IsRef,
-                                     source, loc);
-
-                       if (IsHoistedEmitRequired (ec)) {
-                               HoistedVariable.EmitAssign (ec, source, leave_copy, prepare_for_load);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null) {
+                               hv.EmitAssign (ec, source, leave_copy, prepare_for_load);
                                return;
                        }
 
-                       if (IsRef)
-                               Variable.Emit (ec);
-
-                       source.Emit (ec);
-
-                       // HACK: variable is already emitted when source is an initializer 
-                       if (source is NewInitialize) {
-                               if (leave_copy) {
-                                       Variable.Emit (ec);
+                       New n_source = source as New;
+                       if (n_source != null) {
+                               if (!n_source.Emit (ec, this)) {
+                                       if (leave_copy)
+                                               EmitLoad (ec);
+                                       return;
                                }
-                               return;
+                       } else {
+                               if (IsRef)
+                                       EmitLoad (ec);
+
+                               source.Emit (ec);
                        }
 
                        if (leave_copy) {
@@ -4143,15 +4202,7 @@ namespace Mono.CSharp {
                }
 
                public bool IsHoisted {
-                       get { return HoistedVariable != null; }
-               }
-
-               protected virtual bool IsHoistedEmitRequired (EmitContext ec)
-               {
-                       //
-                       // Default implementation return true when there is a hosted variable
-                       //
-                       return HoistedVariable != null;
+                       get { return GetHoistedVariable (null) != null; }
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -4168,13 +4219,13 @@ 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)
                {
                        Block = block;
                        this.name = name;
                        loc = l;
-                       eclass = ExprClass.Variable;
                }
 
                //
@@ -4193,8 +4244,9 @@ namespace Mono.CSharp {
                        get { return local_info.VariableInfo; }
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return local_info.HoistedVariableReference; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return local_info.HoistedVariableReference;
                }
 
                //              
@@ -4238,7 +4290,11 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList arg = new ArrayList (1);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null)
+                               return hv.CreateExpressionTree (ec);
+
+                       Arguments arg = new Arguments (1);
                        arg.Add (new Argument (this));
                        return CreateExpressionFactoryCall ("Constant", arg);
                }
@@ -4267,11 +4323,16 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       resolved |= ec.DoFlowAnalysis;
+                       eclass = ExprClass.Variable;
                        return this;
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       if (resolved)
+                               return this;
+
                        ResolveLocalInfo ();
                        local_info.Used = true;
 
@@ -4284,7 +4345,7 @@ namespace Mono.CSharp {
                        return DoResolveBase (ec);
                }
 
-               override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        ResolveLocalInfo ();
 
@@ -4363,12 +4424,10 @@ namespace Mono.CSharp {
        /// </summary>
        public class ParameterReference : VariableReference {
                readonly ToplevelParameterInfo pi;
-               readonly ToplevelBlock referenced;
 
-               public ParameterReference (ToplevelBlock referenced, ToplevelParameterInfo pi, Location loc)
+               public ParameterReference (ToplevelParameterInfo pi, Location loc)
                {
                        this.pi = pi;
-                       this.referenced = referenced;
                        this.loc = loc;
                }
 
@@ -4380,8 +4439,9 @@ namespace Mono.CSharp {
                        get { return pi.Parameter.ModFlags == Parameter.Modifier.OUT; }
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return pi.Parameter.HoistedVariableReference; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return pi.Parameter.HoistedVariableReference;
                }
 
                //
@@ -4441,24 +4501,38 @@ namespace Mono.CSharp {
                        if (am == null)
                                return true;
 
-                       ToplevelBlock declared = pi.Block;
-                       if (declared != referenced) {
-                               if (IsRef) {
-                                       Report.Error (1628, loc,
-                                               "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' modifier",
-                                               Name, am.ContainerType);
-                                       return false;
+                       Block b = ec.CurrentBlock;
+                       while (b != null) {
+                               IParameterData[] p = b.Toplevel.Parameters.FixedParameters;
+                               for (int i = 0; i < p.Length; ++i) {
+                                       if (p [i] != Parameter)
+                                               continue;
+
+                                       //
+                                       // Skip closest anonymous method parameters
+                                       //
+                                       if (b == ec.CurrentBlock && !am.IsIterator)
+                                               return true;
+
+                                       if (IsRef) {
+                                               Report.Error (1628, loc,
+                                                       "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' modifier",
+                                                       Name, am.ContainerType);
+                                       }
+
+                                       b = null;
+                                       break;
                                }
-                       } else {
-                               if (!am.IsIterator)
-                                       return true;
+
+                               if (b != null)
+                                       b = b.Toplevel.Parent;
                        }
 
-                       if (ec.IsVariableCapturingRequired) {
-                               if (pi.Parameter.HasAddressTaken)
-                                       AnonymousMethodExpression.Error_AddressOfCapturedVar (this, loc);
+                       if (pi.Parameter.HasAddressTaken)
+                               AnonymousMethodExpression.Error_AddressOfCapturedVar (this, loc);
 
-                               AnonymousMethodStorey storey = declared.CreateAnonymousMethodStorey (ec);
+                       if (ec.IsVariableCapturingRequired) {
+                               AnonymousMethodStorey storey = pi.Block.CreateAnonymousMethodStorey (ec);
                                storey.CaptureParameter (ec, this);
                        }
 
@@ -4476,7 +4550,7 @@ namespace Mono.CSharp {
                        if (pr == null)
                                return false;
 
-                       return Name == pr.Name && referenced == pr.referenced;
+                       return Name == pr.Name;
                }
                
                protected override void CloneTo (CloneContext clonectx, Expression target)
@@ -4486,8 +4560,9 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       if (IsHoistedEmitRequired (ec))
-                               return HoistedVariable.CreateExpressionTree (ec);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null)
+                               return hv.CreateExpressionTree (ec);
 
                        return Parameter.ExpressionTreeVariableReference ();
                }
@@ -4509,6 +4584,10 @@ namespace Mono.CSharp {
                        if (!DoResolveBase (ec))
                                return null;
 
+                       // HACK: Variables are not captured in probing mode
+                       if (ec.IsInProbingMode)
+                               return this;
+
                        if (HasOutModifier && ec.DoFlowAnalysis &&
                            (!ec.OmitStructFlowAnalysis || !VariableInfo.TypeInfo.IsStruct) && !IsAssigned (ec, loc))
                                return null;
@@ -4530,143 +4609,27 @@ namespace Mono.CSharp {
 
                static public void EmitLdArg (ILGenerator ig, int x)
                {
-                       if (x <= 255){
-                               switch (x){
-                               case 0: ig.Emit (OpCodes.Ldarg_0); break;
-                               case 1: ig.Emit (OpCodes.Ldarg_1); break;
-                               case 2: ig.Emit (OpCodes.Ldarg_2); break;
-                               case 3: ig.Emit (OpCodes.Ldarg_3); break;
-                               default: ig.Emit (OpCodes.Ldarg_S, (byte) x); break;
-                               }
-                       } else
-                               ig.Emit (OpCodes.Ldarg, x);
-               }
-       }
-       
-       /// <summary>
-       ///   Used for arguments to New(), Invocation()
-       /// </summary>
-       public class Argument {
-               public enum AType : byte {
-                       Expression,
-                       Ref,
-                       Out,
-                       ArgList
-               };
-
-               public static readonly Argument[] Empty = new Argument [0];
-
-               public readonly AType ArgType;
-               public Expression Expr;
-               
-               public Argument (Expression expr, AType type)
-               {
-                       this.Expr = expr;
-                       this.ArgType = type;
-               }
-
-               public Argument (Expression expr)
-               {
-                       this.Expr = expr;
-                       this.ArgType = AType.Expression;
-               }
-
-               public Type Type {
-                       get { return Expr.Type; }
-               }
-
-               public Parameter.Modifier Modifier
-               {
-                       get {
-                               switch (ArgType) {
-                               case AType.Out:
-                                       return Parameter.Modifier.OUT;
-                                       
-                               case AType.Ref:
-                                       return Parameter.Modifier.REF;
-                                       
-                               default:
-                                       return Parameter.Modifier.NONE;
-                               }
-                       }
-               }
-
-               public string GetSignatureForError ()
-               {
-                       if (Expr.eclass == ExprClass.MethodGroup)
-                               return Expr.ExprClassName;
-
-                       return TypeManager.CSharpName (Expr.Type);
-               }               
-
-               public bool ResolveMethodGroup (EmitContext ec)
-               {
-                       SimpleName sn = Expr as SimpleName;
-                       if (sn != null)
-                               Expr = sn.GetMethodGroup ();
-
-                       // FIXME: csc doesn't report any error if you try to use `ref' or
-                       //        `out' in a delegate creation expression.
-                       Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-                       if (Expr == null)
-                               return false;
-
-                       return true;
-               }
-
-               public bool Resolve (EmitContext ec, Location loc)
-               {
-                       if (Expr == null)
-                               return false;
-
-                       using (ec.With (EmitContext.Flags.DoFlowAnalysis, true)) {
-                               // Verify that the argument is readable
-                               if (ArgType != AType.Out)
-                                       Expr = Expr.Resolve (ec);
-
-                               // Verify that the argument is writeable
-                               if (Expr != null && (ArgType == AType.Out || ArgType == AType.Ref))
-                                       Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess, loc);
-
-                               return Expr != null;
-                       }
-               }
-
-               public void Emit (EmitContext ec)
-               {
-                       if (ArgType != AType.Ref && ArgType != AType.Out) {
-                               Expr.Emit (ec);
-                               return;
+                       switch (x) {
+                       case 0: ig.Emit (OpCodes.Ldarg_0); break;
+                       case 1: ig.Emit (OpCodes.Ldarg_1); break;
+                       case 2: ig.Emit (OpCodes.Ldarg_2); break;
+                       case 3: ig.Emit (OpCodes.Ldarg_3); break;
+                       default:
+                               if (x > byte.MaxValue)
+                                       ig.Emit (OpCodes.Ldarg, x);
+                               else
+                                       ig.Emit (OpCodes.Ldarg_S, (byte) x);
+                               break;
                        }
-
-                       AddressOp mode = AddressOp.Store;
-                       if (ArgType == AType.Ref)
-                               mode |= AddressOp.Load;
-                               
-                       IMemoryLocation ml = (IMemoryLocation) Expr;
-                       ParameterReference pr = ml as ParameterReference;
-
-                       //
-                       // ParameterReferences might already be references, so we want
-                       // to pass just the value
-                       //
-                       if (pr != null && pr.IsRef)
-                               pr.EmitLoad (ec);
-                       else
-                               ml.AddressOf (ec, mode);
-               }
-
-               public Argument Clone (CloneContext clonectx)
-               {
-                       return new Argument (Expr.Clone (clonectx), ArgType);
                }
        }
-
+       
        /// <summary>
        ///   Invocation of methods or delegates.
        /// </summary>
-       public class Invocation : ExpressionStatement {
-               protected ArrayList Arguments;
+       public class Invocation : ExpressionStatement
+       {
+               protected Arguments arguments;
                protected Expression expr;
                protected MethodGroupExpr mg;
                bool arguments_resolved;
@@ -4675,7 +4638,7 @@ namespace Mono.CSharp {
                // arguments is an ArrayList, but we do not want to typecast,
                // as it might be null.
                //
-               public Invocation (Expression expr, ArrayList arguments)
+               public Invocation (Expression expr, Arguments arguments)
                {
                        SimpleName sn = expr as SimpleName;
                        if (sn != null)
@@ -4683,12 +4646,12 @@ namespace Mono.CSharp {
                        else
                                this.expr = expr;
                        
-                       Arguments = arguments;
+                       this.arguments = arguments;
                        if (expr != null)
                                loc = expr.Location;
                }
 
-               public Invocation (Expression expr, ArrayList arguments, bool arguments_resolved)
+               public Invocation (Expression expr, Arguments arguments, bool arguments_resolved)
                        : this (expr, arguments)
                {
                        this.arguments_resolved = arguments_resolved;
@@ -4696,47 +4659,24 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args;
+                       Arguments args;
 
                        //
                        // Special conversion for nested expression trees
                        //
                        if (TypeManager.DropGenericTypeArguments (type) == TypeManager.expression_type) {
-                               args = new ArrayList (1);
+                               args = new Arguments (1);
                                args.Add (new Argument (this));
                                return CreateExpressionFactoryCall ("Quote", args);
                        }
 
-                       ExtensionMethodGroupExpr emg = mg as ExtensionMethodGroupExpr;
-
-                       int arg_count = Arguments == null ? 2 : Arguments.Count + 2;
-                       if (emg != null)
-                               ++arg_count;
-                       args = new ArrayList (arg_count);
-
-                       if (mg.IsInstance)
-                               args.Add (new Argument (mg.InstanceExpression.CreateExpressionTree (ec)));
-                       else
-                               args.Add (new Argument (new NullLiteral (loc)));
-
-                       args.Add (new Argument (mg.CreateExpressionTree (ec)));
-
-                       //
-                       // Use extension argument when exists
-                       //
-                       if (emg != null) {
-                               Expression e = emg.ExtensionExpression.CreateExpressionTree (ec);
-                               if (e != null)
-                                       args.Add (new Argument (e));
-                       }
+                       Expression instance = mg.IsInstance ?
+                               mg.InstanceExpression.CreateExpressionTree (ec) :
+                               new NullLiteral (loc);
 
-                       if (Arguments != null) {
-                               foreach (Argument a in Arguments) {
-                                       Expression e = a.Expr.CreateExpressionTree (ec);
-                                       if (e != null)
-                                               args.Add (new Argument (e));
-                               }
-                       }
+                       args = Arguments.CreateForExpressionTree (ec, arguments,
+                               instance,
+                               mg.CreateExpressionTree (ec));
 
                        if (mg.IsBase)
                                MemberExpr.Error_BaseAccessInExpressionTree (loc);
@@ -4758,9 +4698,14 @@ namespace Mono.CSharp {
                        if (mg == null) {
                                Type expr_type = expr_resolved.Type;
 
+                               if (expr_type == InternalType.Dynamic) {
+                                       Arguments args = ((DynamicMemberBinder) expr_resolved).Arguments;
+                                       return new DynamicInvocation (expr as MemberAccess, args, loc).Resolve (ec);
+                               }
+
                                if (expr_type != null && TypeManager.IsDelegateType (expr_type)){
                                        return (new DelegateInvocation (
-                                               expr_resolved, Arguments, loc)).Resolve (ec);
+                                               expr_resolved, arguments, loc)).Resolve (ec);
                                }
 
                                MemberExpr me = expr_resolved as MemberExpr;
@@ -4782,12 +4727,8 @@ namespace Mono.CSharp {
                        //
                        // Next, evaluate all the expressions in the argument list
                        //
-                       if (Arguments != null && !arguments_resolved) {
-                               for (int i = 0; i < Arguments.Count; ++i)
-                               {
-                                       if (!((Argument)Arguments[i]).Resolve(ec, loc))
-                                               return null;
-                               }
+                       if (arguments != null && !arguments_resolved) {
+                               arguments.Resolve (ec);
                        }
 
                        mg = DoResolveOverload (ec);
@@ -4810,7 +4751,7 @@ namespace Mono.CSharp {
                                                return null;
                                        }
                                } else {
-                                       if (iexpr == null) {
+                                       if (iexpr == null || iexpr == EmptyExpression.Null) {
                                                SimpleName.Error_ObjectRefRequired (ec, loc, mg.GetSignatureForError ());
                                        }
                                }
@@ -4831,7 +4772,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (Arguments == null && method.DeclaringType == TypeManager.object_type && method.Name == "Finalize") {
+                       if (arguments == null && method.DeclaringType == TypeManager.object_type && method.Name == Destructor.MetadataName) {
                                if (mg.IsBase)
                                        Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor");
                                else
@@ -4850,7 +4791,7 @@ namespace Mono.CSharp {
 
                protected virtual MethodGroupExpr DoResolveOverload (EmitContext ec)
                {
-                       return mg.OverloadResolve (ec, ref Arguments, false, loc);
+                       return mg.OverloadResolve (ec, ref arguments, false, loc);
                }
 
                public static bool IsSpecialMethodInvocation (MethodBase method, Location loc)
@@ -4865,58 +4806,11 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               /// <summary>
-               ///   Emits a list of resolved Arguments that are in the arguments
-               ///   ArrayList.
-               /// 
-               ///   The MethodBase argument might be null if the
-               ///   emission of the arguments is known not to contain
-               ///   a `params' field (for example in constructors or other routines
-               ///   that keep their arguments in this structure)
-               ///   
-               ///   if `dup_args' is true, a copy of the arguments will be left
-               ///   on the stack. If `dup_args' is true, you can specify `this_arg'
-               ///   which will be duplicated before any other args. Only EmitCall
-               ///   should be using this interface.
-               /// </summary>
-               public static void EmitArguments (EmitContext ec, ArrayList arguments, bool dup_args, LocalTemporary this_arg)
+               static Type[] GetVarargsTypes (MethodBase mb, Arguments arguments)
                {
-                       if (arguments == null)
-                               return;
-
-                       int top = arguments.Count;
-                       LocalTemporary [] temps = null;
+                       AParametersCollection pd = TypeManager.GetParameterData (mb);
                        
-                       if (dup_args && top != 0)
-                               temps = new LocalTemporary [top];
-
-                       int argument_index = 0;
-                       Argument a;
-                       for (int i = 0; i < top; i++) {
-                               a = (Argument) arguments [argument_index++];
-                               a.Emit (ec);
-                               if (dup_args) {
-                                       ec.ig.Emit (OpCodes.Dup);
-                                       (temps [i] = new LocalTemporary (a.Type)).Store (ec);
-                               }
-                       }
-                       
-                       if (dup_args) {
-                               if (this_arg != null)
-                                       this_arg.Emit (ec);
-                               
-                               for (int i = 0; i < top; i ++) {
-                                       temps [i].Emit (ec);
-                                       temps [i].Release (ec);
-                               }
-                       }
-               }
-
-               static Type[] GetVarargsTypes (MethodBase mb, ArrayList arguments)
-               {
-                       AParametersCollection pd = TypeManager.GetParameterData (mb);
-                       
-                       Argument a = (Argument) arguments [pd.Count - 1];
+                       Argument a = arguments [pd.Count - 1];
                        Arglist list = (Arglist) a.Expr;
 
                        return list.ArgumentTypes;
@@ -4931,7 +4825,7 @@ namespace Mono.CSharp {
                                return false;
 
                        method = TypeManager.DropGenericMethodArguments (method);
-                       if (method.DeclaringType.Module == CodeGen.Module.Builder) {
+                       if (method.DeclaringType.Module == RootContext.ToplevelTypes.Builder) {
                                IMethodData md = TypeManager.GetMethod (method);
                                if (md != null)
                                        return md.IsExcluded ();
@@ -4961,7 +4855,7 @@ namespace Mono.CSharp {
                /// </remarks>
                public static void EmitCall (EmitContext ec, bool is_base,
                                             Expression instance_expr,
-                                            MethodBase method, ArrayList Arguments, Location loc)
+                                            MethodBase method, Arguments Arguments, Location loc)
                {
                        EmitCall (ec, is_base, instance_expr, method, Arguments, loc, false, false);
                }
@@ -4974,7 +4868,7 @@ namespace Mono.CSharp {
                // only have been evaluated once.
                public static void EmitCall (EmitContext ec, bool is_base,
                                             Expression instance_expr,
-                                            MethodBase method, ArrayList Arguments, Location loc,
+                                            MethodBase method, Arguments Arguments, Location loc,
                                             bool dup_args, bool omit_args)
                {
                        ILGenerator ig = ec.ig;
@@ -4990,7 +4884,7 @@ namespace Mono.CSharp {
                        bool is_static = method.IsStatic;
                        if (!is_static){
                                this_call = instance_expr is This;
-                               if (decl_type.IsValueType || (!this_call && instance_expr.Type.IsValueType))
+                               if (TypeManager.IsStruct (decl_type) || TypeManager.IsEnumType (decl_type))
                                        struct_call = true;
 
                                //
@@ -5003,12 +4897,12 @@ namespace Mono.CSharp {
                                        //
                                        // Push the instance expression
                                        //
-                                       if (TypeManager.IsValueType (iexpr_type)) {
+                                       if (TypeManager.IsValueType (iexpr_type) || TypeManager.IsGenericParameter (iexpr_type)) {
                                                //
                                                // Special case: calls to a function declared in a 
                                                // reference-type with a value-type argument need
                                                // to have their value boxed.
-                                               if (decl_type.IsValueType ||
+                                               if (TypeManager.IsStruct (decl_type) ||
                                                    TypeManager.IsGenericParameter (iexpr_type)) {
                                                        //
                                                        // If the expression implements IMemoryLocation, then
@@ -5032,6 +4926,9 @@ namespace Mono.CSharp {
                                                                t = TypeManager.GetReferenceType (iexpr_type);
                                                } else {
                                                        instance_expr.Emit (ec);
+                                                       
+                                                       // FIXME: should use instance_expr is IMemoryLocation + constraint.
+                                                       // to help JIT to produce better code
                                                        ig.Emit (OpCodes.Box, instance_expr.Type);
                                                        t = TypeManager.object_type;
                                                }
@@ -5050,19 +4947,20 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (!omit_args)
-                               EmitArguments (ec, Arguments, dup_args, this_arg);
-
-#if GMCS_SOURCE
-                       if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
-                               ig.Emit (OpCodes.Constrained, instance_expr.Type);
-#endif
+                       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))
+                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual)) {
                                call_op = OpCodes.Call;
-                       else
+                       } else {
                                call_op = OpCodes.Callvirt;
+                               
+#if GMCS_SOURCE
+                               if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
+                                       ig.Emit (OpCodes.Constrained, instance_expr.Type);
+#endif
+                       }
 
                        if ((method.CallingConvention & CallingConventions.VarArgs) != 0) {
                                Type[] varargs_types = GetVarargsTypes (method, Arguments);
@@ -5084,7 +4982,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       mg.EmitCall (ec, Arguments);
+                       mg.EmitCall (ec, arguments);
                }
                
                public override void EmitStatement (EmitContext ec)
@@ -5102,11 +5000,8 @@ namespace Mono.CSharp {
                {
                        Invocation target = (Invocation) t;
 
-                       if (Arguments != null) {
-                               target.Arguments = new ArrayList (Arguments.Count);
-                               foreach (Argument a in Arguments)
-                                       target.Arguments.Add (a.Clone (clonectx));
-                       }
+                       if (arguments != null)
+                               target.arguments = arguments.Clone (clonectx);
 
                        target.expr = expr.Clone (clonectx);
                }
@@ -5114,13 +5009,13 @@ namespace Mono.CSharp {
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        mg.MutateHoistedGenericType (storey);
-                       if (Arguments != null) {
-                               foreach (Argument a in Arguments)
-                                       a.Expr.MutateHoistedGenericType (storey);
+                       type = storey.MutateType (type);
+                       if (arguments != null) {
+                               arguments.MutateHoistedGenericType (storey);
                        }
                }
        }
-
+/*
        //
        // It's either a cast or delegate invocation
        //
@@ -5226,87 +5121,32 @@ namespace Mono.CSharp {
                        target.argument = argument.Clone (clonectx);
                }
        }
+*/
 
-       //
-       // This class is used to "disable" the code generation for the
-       // temporary variable when initializing value types.
-       //
-       sealed class EmptyAddressOf : EmptyExpression, IMemoryLocation {
-               public void AddressOf (EmitContext ec, AddressOp Mode)
-               {
-                       // nothing
-               }
-       }
-       
        /// <summary>
        ///    Implements the new expression 
        /// </summary>
        public class New : ExpressionStatement, IMemoryLocation {
-               ArrayList Arguments;
+               Arguments Arguments;
 
                //
                // During bootstrap, it contains the RequestedType,
                // but if `type' is not null, it *might* contain a NewDelegate
                // (because of field multi-initialization)
                //
-               public Expression RequestedType;
+               Expression RequestedType;
 
                MethodGroupExpr method;
 
-               //
-               // If set, the new expression is for a value_target, and
-               // we will not leave anything on the stack.
-               //
-               protected Expression value_target;
-               protected bool value_target_set;
-               bool is_type_parameter = false;
-               
-               public New (Expression requested_type, ArrayList arguments, Location l)
+               bool is_type_parameter;
+
+               public New (Expression requested_type, Arguments arguments, Location l)
                {
                        RequestedType = requested_type;
                        Arguments = arguments;
                        loc = l;
                }
 
-               public bool SetTargetVariable (Expression value)
-               {
-                       value_target = value;
-                       value_target_set = true;
-                       if (!(value_target is IMemoryLocation)){
-                               Error_UnexpectedKind (null, "variable", loc);
-                               return false;
-                       }
-                       return true;
-               }
-
-               //
-               // This function is used to disable the following code sequence for
-               // value type initialization:
-               //
-               // AddressOf (temporary)
-               // Construct/Init
-               // LoadTemporary
-               //
-               // Instead the provide will have provided us with the address on the
-               // stack to store the results.
-               //
-               static Expression MyEmptyExpression;
-               
-               public void DisableTemporaryValueType ()
-               {
-                       if (MyEmptyExpression == null)
-                               MyEmptyExpression = new EmptyAddressOf ();
-
-                       //
-                       // To enable this, look into:
-                       // test-34 and test-89 and self bootstrapping.
-                       //
-                       // For instance, we can avoid a copy by using `newobj'
-                       // instead of Call + Push-temp on value types.
-//                     value_target = MyEmptyExpression;
-               }
-
-
                /// <summary>
                /// Converts complex core type syntax like 'new int ()' to simple constant
                /// </summary>
@@ -5340,6 +5180,8 @@ namespace Mono.CSharp {
                                return new DecimalConstant (0, Location.Null);
                        if (TypeManager.IsEnumType (t))
                                return new EnumConstant (Constantify (TypeManager.GetEnumUnderlyingType (t)), t);
+                       if (TypeManager.IsNullableType (t))
+                               return Nullable.LiftedNull.Create (t, Location.Null);
 
                        return null;
                }
@@ -5369,21 +5211,13 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = Arguments == null ?
-                               new ArrayList (1) : new ArrayList (Arguments.Count + 1);
-
+                       Arguments args;
                        if (method == null) {
+                               args = new Arguments (1);
                                args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        } else {
-                               args.Add (new Argument (method.CreateExpressionTree (ec)));
-                               if (Arguments != null) {
-                                       Expression expr;
-                                       foreach (Argument a in Arguments) {
-                                               expr = a.Expr.CreateExpressionTree (ec);
-                                               if (expr != null)
-                                                       args.Add (new Argument (expr));
-                                       }
-                               }
+                               args = Arguments.CreateForExpressionTree (ec, Arguments,
+                                       method.CreateExpressionTree (ec));
                        }
 
                        return CreateExpressionFactoryCall ("New", args);
@@ -5427,8 +5261,7 @@ namespace Mono.CSharp {
                                return (new NewDelegate (type, Arguments, loc)).Resolve (ec);
                        }
 
-#if GMCS_SOURCE
-                       if (type.IsGenericParameter) {
+                       if (TypeManager.IsGenericParameter (type)) {
                                GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
 
                                if ((gc == null) || (!gc.HasConstructorConstraint && !gc.IsValueType)) {
@@ -5460,7 +5293,6 @@ namespace Mono.CSharp {
                                eclass = ExprClass.Value;
                                return this;
                        }
-#endif
 
                        if (type.IsAbstract && type.IsSealed) {
                                Report.SymbolRelatedToPreviousError (type);
@@ -5480,7 +5312,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       bool is_struct = type.IsValueType;
+                       bool is_struct = TypeManager.IsStruct (type);
                        eclass = ExprClass.Value;
 
                        //
@@ -5494,12 +5326,8 @@ namespace Mono.CSharp {
                        Expression ml = MemberLookupFinal (ec, type, type, ".ctor",
                                MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
 
-                       if (Arguments != null){
-                               foreach (Argument a in Arguments){
-                                       if (!a.Resolve (ec, loc))
-                                               return null;
-                               }
-                       }
+                       if (Arguments != null)
+                               Arguments.Resolve (ec);
 
                        if (ml == null)
                                return null;
@@ -5550,7 +5378,7 @@ namespace Mono.CSharp {
                        temp.AddressOf (ec, AddressOp.Store);
                        ig.Emit (OpCodes.Initobj, type);
                        temp.Emit (ec);
-                       ig.Emit (OpCodes.Br, label_end);
+                       ig.Emit (OpCodes.Br_S, label_end);
 
                        ig.MarkLabel (label_activator);
 
@@ -5563,14 +5391,10 @@ namespace Mono.CSharp {
                }
 
                //
-               // This DoEmit can be invoked in two contexts:
+               // This Emit can be invoked in two contexts:
                //    * As a mechanism that will leave a value on the stack (new object)
                //    * As one that wont (init struct)
                //
-               // You can control whether a value is required on the stack by passing
-               // need_value_on_stack.  The code *might* leave a value on the stack
-               // so it must be popped manually
-               //
                // If we are dealing with a ValueType, we have a few
                // situations to deal with:
                //
@@ -5586,68 +5410,81 @@ namespace Mono.CSharp {
                //
                // Returns whether a value is left on the stack
                //
-               bool DoEmit (EmitContext ec, bool need_value_on_stack)
+               // *** Implementation note ***
+               //
+               // To benefit from this optimization, each assignable expression
+               // has to manually cast to New and call this Emit.
+               //
+               // TODO: It's worth to implement it for arrays and fields
+               //
+               public virtual bool Emit (EmitContext ec, IMemoryLocation target)
                {
                        bool is_value_type = TypeManager.IsValueType (type);
                        ILGenerator ig = ec.ig;
+                       VariableReference vr = target as VariableReference;
 
-                       if (is_value_type){
-                               IMemoryLocation ml;
-
-                               // Allow DoEmit() to be called multiple times.
-                               // We need to create a new LocalTemporary each time since
-                               // you can't share LocalBuilders among ILGeneators.
-                               if (!value_target_set)
-                                       value_target = new LocalTemporary (type);
-
-                               ml = (IMemoryLocation) value_target;
-                               ml.AddressOf (ec, AddressOp.Store);
+                       if (target != null && is_value_type && (vr != null || method == null)) {
+                               target.AddressOf (ec, AddressOp.Store);
+                       } else if (vr != null && vr.IsRef) {
+                               vr.EmitLoad (ec);
                        }
+                       
+                       if (Arguments != null)
+                               Arguments.Emit (ec);
 
-                       if (method != null)
-                               method.EmitArguments (ec, Arguments);
-
-                       if (is_value_type){
-                               if (method == null)
+                       if (is_value_type) {
+                               if (method == null) {
                                        ig.Emit (OpCodes.Initobj, type);
-                               else
+                                       return false;
+                               }
+
+                               if (vr != null) {
                                        ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-                                if (need_value_on_stack){
-                                        value_target.Emit (ec);
-                                        return true;
-                                }
-                                return false;
-                       } else {
-                               ConstructorInfo ci = (ConstructorInfo) method;
+                                       return false;
+                               }
+                       }
+                       
+                       if (is_type_parameter)
+                               return DoEmitTypeParameter (ec);                        
+
+                       ConstructorInfo ci = (ConstructorInfo) method;
 #if MS_COMPATIBLE
-                               if (TypeManager.IsGenericType (type))
-                                       ci = TypeBuilder.GetConstructor (type, ci);
+                       if (TypeManager.IsGenericType (type))
+                               ci = TypeBuilder.GetConstructor (type, ci);
 #endif
-                               ig.Emit (OpCodes.Newobj, ci);
-                               return true;
-                       }
+
+                       ig.Emit (OpCodes.Newobj, ci);
+                       return true;
                }
 
                public override void Emit (EmitContext ec)
                {
-                       if (is_type_parameter)
-                               DoEmitTypeParameter (ec);
-                       else
-                               DoEmit (ec, true);
+                       LocalTemporary v = null;
+                       if (method == null && TypeManager.IsValueType (type)) {
+                               // TODO: Use temporary variable from pool
+                               v = new LocalTemporary (type);
+                       }
+
+                       if (!Emit (ec, v))
+                               v.Emit (ec);
                }
                
                public override void EmitStatement (EmitContext ec)
                {
-                       bool value_on_stack;
-
-                       if (is_type_parameter)
-                               value_on_stack = DoEmitTypeParameter (ec);
-                       else
-                               value_on_stack = DoEmit (ec, false);
+                       LocalTemporary v = null;
+                       if (method == null && TypeManager.IsValueType (type)) {
+                               // TODO: Use temporary variable from pool
+                               v = new LocalTemporary (type);
+                       }
 
-                       if (value_on_stack)
+                       if (Emit (ec, v))
                                ec.ig.Emit (OpCodes.Pop);
+               }
 
+               public bool IsDefaultValueType {
+                       get {
+                               return TypeManager.IsValueType (type) && !HasInitializer && Arguments == null;
+                       }
                }
 
                public virtual bool HasInitializer {
@@ -5656,17 +5493,23 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void AddressOf (EmitContext ec, AddressOp Mode)
+               public void AddressOf (EmitContext ec, AddressOp mode)
                {
+                       EmitAddressOf (ec, mode);
+               }
+
+               protected virtual IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp mode)
+               {
+                       LocalTemporary value_target = new LocalTemporary (type);
+
                        if (is_type_parameter) {
-                               LocalTemporary temp = new LocalTemporary (type);
                                DoEmitTypeParameter (ec);
-                               temp.Store (ec);
-                               temp.AddressOf (ec, Mode);
-                               return;
+                               value_target.Store (ec);
+                               value_target.AddressOf (ec, mode);
+                               return value_target;
                        }
 
-                       if (!type.IsValueType){
+                       if (!TypeManager.IsStruct (type)){
                                //
                                // We throw an exception.  So far, I believe we only need to support
                                // value types:
@@ -5676,19 +5519,19 @@ namespace Mono.CSharp {
                                throw new Exception ("AddressOf should not be used for classes");
                        }
 
-                       if (!value_target_set)
-                               value_target = new LocalTemporary (type);
-                       IMemoryLocation ml = (IMemoryLocation) value_target;
+                       value_target.AddressOf (ec, AddressOp.Store);
 
-                       ml.AddressOf (ec, AddressOp.Store);
                        if (method == null) {
                                ec.ig.Emit (OpCodes.Initobj, type);
                        } else {
-                               method.EmitArguments (ec, Arguments);
+                               if (Arguments != null)
+                                       Arguments.Emit (ec);
+
                                ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
                        }
                        
-                       ((IMemoryLocation) value_target).AddressOf (ec, Mode);
+                       value_target.AddressOf (ec, mode);
+                       return value_target;
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -5697,10 +5540,7 @@ namespace Mono.CSharp {
 
                        target.RequestedType = RequestedType.Clone (clonectx);
                        if (Arguments != null){
-                               target.Arguments = new ArrayList ();
-                               foreach (Argument a in Arguments){
-                                       target.Arguments.Add (a.Clone (clonectx));
-                               }
+                               target.Arguments = Arguments.Clone (clonectx);
                        }
                }
 
@@ -5709,8 +5549,7 @@ namespace Mono.CSharp {
                        if (method != null) {
                                method.MutateHoistedGenericType (storey);
                                if (Arguments != null) {
-                                       foreach (Argument a in Arguments)
-                                               a.Expr.MutateHoistedGenericType (storey);
+                                       Arguments.MutateHoistedGenericType (storey);
                                }
                        }
 
@@ -5762,7 +5601,7 @@ namespace Mono.CSharp {
                        arguments = new ArrayList (exprs.Count);
 
                        foreach (Expression e in exprs) {
-                               arguments.Add (new Argument (e, Argument.AType.Expression));
+                               arguments.Add (e);
                                num_arguments++;
                        }
                }
@@ -5791,64 +5630,51 @@ namespace Mono.CSharp {
                {
                        Report.Error (248, loc, "Cannot create an array with a negative size");
                }
-               
-               bool CheckIndices (EmitContext ec, ArrayList probe, int idx, bool specified_dims)
+
+               bool CheckIndices (EmitContext ec, ArrayList probe, int idx, bool specified_dims, int child_bounds)
                {
                        if (specified_dims) { 
-                               Argument a = (Argument) arguments [idx];
-
-                               if (!a.Resolve (ec, loc))
+                               Expression a = (Expression) arguments [idx];
+                               a = a.Resolve (ec);
+                               if (a == null)
                                        return false;
 
-                               Constant c = a.Expr as Constant;
+                               Constant c = a as Constant;
                                if (c != null) {
-                                       c = c.ImplicitConversionRequired (ec, TypeManager.int32_type, a.Expr.Location);
+                                       c = c.ImplicitConversionRequired (ec, TypeManager.int32_type, a.Location);
                                }
 
                                if (c == null) {
-                                       Report.Error (150, a.Expr.Location, "A constant value is expected");
+                                       Report.Error (150, a.Location, "A constant value is expected");
                                        return false;
                                }
 
                                int value = (int) c.GetValue ();
                                
                                if (value != probe.Count) {
-                                       Error_IncorrectArrayInitializer (loc);
+                                       Report.Error (847, loc, "An array initializer of length `{0}' was expected", value);
                                        return false;
                                }
                                
                                bounds [idx] = value;
                        }
 
-                       int child_bounds = -1;
                        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;
-                                       int current_bounds = sub_probe.Count;
-                                       
-                                       if (child_bounds == -1) 
-                                               child_bounds = current_bounds;
-
-                                       else if (child_bounds != current_bounds){
-                                               Error_IncorrectArrayInitializer (loc);
-                                               return false;
-                                       }
                                        if (idx + 1 >= dimensions){
                                                Error (623, "Array initializers can only be used in a variable or field initializer. Try using a new expression instead");
                                                return false;
                                        }
                                        
-                                       bool ret = CheckIndices (ec, sub_probe, idx + 1, specified_dims);
+                                       bool ret = CheckIndices (ec, sub_probe, idx + 1, specified_dims, child_bounds - 1);
                                        if (!ret)
                                                return false;
+                               } else if (child_bounds > 1) {
+                                       Report.Error (846, ((Expression) o).Location, "A nested array initializer was expected");
                                } else {
-                                       if (child_bounds != -1){
-                                               Error_IncorrectArrayInitializer (loc);
-                                               return false;
-                                       }
-                                       
                                        Expression element = ResolveArrayElement (ec, (Expression) o);
                                        if (element == null)
                                                continue;
@@ -5875,18 +5701,18 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args;
+                       Arguments args;
 
                        if (array_data == null) {
-                               args = new ArrayList (arguments.Count + 1);
+                               args = new Arguments (arguments.Count + 1);
                                args.Add (new Argument (new TypeOf (new TypeExpression (array_element_type, loc), loc)));
-                               foreach (Argument a in arguments) {
+                               foreach (Expression a in arguments) {
                                        if (arguments.Count == 1) {
-                                               Constant c = a.Expr as Constant;
+                                               Constant c = a as Constant;
                                                if (c.IsDefaultValue)
                                                        return CreateExpressionFactoryCall ("NewArrayInit", args);
                                        }
-                                       args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
+                                       args.Add (new Argument (a.CreateExpressionTree (ec)));
                                }
 
                                return CreateExpressionFactoryCall ("NewArrayBounds", args);
@@ -5897,7 +5723,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       args = new ArrayList (array_data == null ? 1 : array_data.Count + 1);
+                       args = new Arguments (array_data == null ? 1 : array_data.Count + 1);
                        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) {
@@ -5918,7 +5744,7 @@ namespace Mono.CSharp {
                        for (ArrayList probe = initializers; probe != null;) {
                                if (probe.Count > 0 && probe [0] is ArrayList) {
                                        Expression e = new IntConstant (probe.Count, Location.Null);
-                                       arguments.Add (new Argument (e, Argument.AType.Expression));
+                                       arguments.Add (e);
 
                                        bounds [i++] =  probe.Count;
                                        
@@ -5926,7 +5752,7 @@ namespace Mono.CSharp {
                                        
                                } else {
                                        Expression e = new IntConstant (probe.Count, Location.Null);
-                                       arguments.Add (new Argument (e, Argument.AType.Expression));
+                                       arguments.Add (e);
 
                                        bounds [i++] = probe.Count;
                                        return;
@@ -5969,11 +5795,11 @@ namespace Mono.CSharp {
                        bounds = new System.Collections.Specialized.HybridDictionary ();
                        
                        if (arguments != null)
-                               return CheckIndices (ec, initializers, 0, true);
+                               return CheckIndices (ec, initializers, 0, true, dimensions);
 
                        arguments = new ArrayList ();
 
-                       if (!CheckIndices (ec, initializers, 0, false))
+                       if (!CheckIndices (ec, initializers, 0, false, dimensions))
                                return false;
                                
                        UpdateIndices ();
@@ -6040,15 +5866,12 @@ namespace Mono.CSharp {
                        if (!ResolveInitializers (ec))
                                return null;
 
-                       if (arguments.Count != dimensions) {
-                               Error_IncorrectArrayInitializer (loc);
-                       }
-
-                       foreach (Argument a in arguments){
-                               if (!a.Resolve (ec, loc))
+                       for (int i = 0; i < arguments.Count; ++i) {
+                               Expression e = ((Expression) arguments[i]).Resolve (ec);
+                               if (e == null)
                                        continue;
 
-                               a.Expr = ConvertExpressionToArrayIndex (ec, a.Expr);
+                               arguments [i] = ConvertExpressionToArrayIndex (ec, e);
                        }
                                                        
                        eclass = ExprClass.Value;
@@ -6057,7 +5880,7 @@ namespace Mono.CSharp {
 
                MethodInfo GetArrayMethod (int arguments)
                {
-                       ModuleBuilder mb = CodeGen.Module.Builder;
+                       ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
 
                        Type[] arg_types = new Type[arguments];
                        for (int i = 0; i < arguments; i++)
@@ -6230,13 +6053,18 @@ namespace Mono.CSharp {
                        array_element_type = storey.MutateType (array_element_type);
                        type = storey.MutateType (type);
                        if (arguments != null) {
-                               foreach (Argument a in arguments)
-                                       a.Expr.MutateHoistedGenericType (storey);
+                               foreach (Expression e in arguments)
+                                       e.MutateHoistedGenericType (storey);
                        }
                        
                        if (array_data != null) {
-                               foreach (Expression e in array_data)
+                               foreach (Expression e in array_data) {
+                                       // Don't mutate values optimized away
+                                       if (e == null)
+                                               continue;
+
                                        e.MutateHoistedGenericType (storey);
+                               }
                        }
                }
 
@@ -6290,8 +6118,8 @@ namespace Mono.CSharp {
                                for (int j = 0; j < dims; j++)
                                        args [j] = TypeManager.int32_type;
                                args [dims] = array_element_type;
-                               
-                               set = CodeGen.Module.Builder.GetArrayMethod (
+
+                               set = RootContext.ToplevelTypes.Builder.GetArrayMethod (
                                        type, "Set",
                                        CallingConventions.HasThis | CallingConventions.Standard,
                                        TypeManager.void_type, args);
@@ -6314,18 +6142,9 @@ namespace Mono.CSharp {
                                        // If we are dealing with a struct, get the
                                        // address of it, so we can store it.
                                        //
-                                       if ((dims == 1) && etype.IsValueType &&
+                                       if ((dims == 1) && TypeManager.IsStruct (etype) &&
                                            (!TypeManager.IsBuiltinOrEnum (etype) ||
                                             etype == TypeManager.decimal_type)) {
-                                               if (e is New){
-                                                       New n = (New) e;
-
-                                                       //
-                                                       // Let new know that we are providing
-                                                       // the address where to store the results
-                                                       //
-                                                       n.DisableTemporaryValueType ();
-                                               }
 
                                                ig.Emit (OpCodes.Ldelema, etype);
                                        }
@@ -6367,8 +6186,8 @@ namespace Mono.CSharp {
                                first_emit_temp.Store (ec);
                        }
 
-                       foreach (Argument a in arguments)
-                               a.Emit (ec);
+                       foreach (Expression e in arguments)
+                               e.Emit (ec);
 
                        if (arguments.Count == 1)
                                ig.Emit (OpCodes.Newarr, array_element_type);
@@ -6404,7 +6223,7 @@ namespace Mono.CSharp {
                        }
 
                        if (array_data == null) {
-                               Constant c = (Constant)((Argument)arguments [0]).Expr;
+                               Constant c = (Constant) arguments [0];
                                if (c.IsDefaultValue) {
                                        value = Array.CreateInstance (array_element_type, 0);
                                        return true;
@@ -6442,8 +6261,8 @@ namespace Mono.CSharp {
 
                        if (arguments != null){
                                target.arguments = new ArrayList (arguments.Count);
-                               foreach (Argument a in arguments)
-                                       target.arguments.Add (a.Clone (clonectx));
+                               foreach (Expression e in arguments)
+                                       target.arguments.Add (e.Clone (clonectx));
                        }
 
                        if (initializers != null){
@@ -6489,7 +6308,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (array_element_type == null || array_element_type == TypeManager.null_type ||
-                               array_element_type == TypeManager.void_type || array_element_type == TypeManager.anonymous_method_type ||
+                               array_element_type == TypeManager.void_type || array_element_type == InternalType.AnonymousMethod ||
                                arguments.Count != dimensions) {
                                Error_NoBestType ();
                                return null;
@@ -6532,7 +6351,9 @@ namespace Mono.CSharp {
                                return null;
                        
                        if (array_element_type == null) {
-                               array_element_type = element.Type;
+                               if (element.Type != TypeManager.null_type)
+                                       array_element_type = element.Type;
+
                                return element;
                        }
 
@@ -6573,8 +6394,9 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return null; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return null;
                }
        }
        
@@ -6627,17 +6449,25 @@ namespace Mono.CSharp {
                        get { return false; }
                }
 
-               protected override bool IsHoistedEmitRequired (EmitContext ec)
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
                {
-                       //
-                       // Handle 'this' differently, it cannot be assigned hence
-                       // when we are not inside anonymous method we can emit direct access 
-                       //
-                       return ec.CurrentAnonymousMethod != null && base.IsHoistedEmitRequired (ec);
-               }
+                       // Is null when probing IsHoisted
+                       if (ec == null)
+                               return null;
+
+                       if (ec.CurrentAnonymousMethod == null)
+                               return null;
+
+                       AnonymousMethodStorey storey = ec.CurrentAnonymousMethod.Storey;
+                       while (storey != null) {
+                               AnonymousMethodStorey temp = storey.Parent as AnonymousMethodStorey;
+                               if (temp == null)
+                                       return storey.HoistedThis;
+
+                               storey = temp;
+                       }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return TopToplevelBlock.HoistedThisVariable; }
+                       return null;
                }
 
                public override bool IsRef {
@@ -6648,15 +6478,6 @@ namespace Mono.CSharp {
                        get { return ThisVariable.Instance; }
                }
 
-               // TODO: Move to ToplevelBlock
-               ToplevelBlock TopToplevelBlock {
-                       get {
-                               ToplevelBlock tl = block.Toplevel;
-                               while (tl.Parent != null) tl = tl.Parent.Toplevel;
-                               return tl;
-                       }
-               }
-
                public static bool IsThisAvailable (EmitContext ec)
                {
                        if (ec.IsStatic || ec.IsInFieldInitializer)
@@ -6700,24 +6521,8 @@ namespace Mono.CSharp {
                                        variable_info = block.Toplevel.ThisVariable.VariableInfo;
 
                                AnonymousExpression am = ec.CurrentAnonymousMethod;
-                               if (am != null) {
-                                       //
-                                       // this is hoisted to very top level block
-                                       //
-                                       if (ec.IsVariableCapturingRequired) {
-                                               //
-                                               // TODO: it should be optimized, see test-anon-75.cs
-                                               //
-                                               // `this' variable has its own scope which is mostly empty
-                                               // and causes creation of extraneous storey references.
-                                               // Also it's hard to remove `this' dependencies when we Undo
-                                               // this access.
-                                               //
-                                               AnonymousMethodStorey scope = TopToplevelBlock.Explicit.CreateAnonymousMethodStorey (ec);
-                                               if (HoistedVariable == null) {
-                                                       TopToplevelBlock.HoistedThisVariable = scope.CaptureThis (ec, this);
-                                               }
-                                       }
+                               if (am != null && ec.IsVariableCapturingRequired) {
+                                       am.SetHasThisAccess ();
                                }
                        }
                        
@@ -6729,7 +6534,7 @@ namespace Mono.CSharp {
                //
                public override void CheckMarshalByRefAccess (EmitContext ec)
                {
-                       if ((variable_info != null) && !(type.IsValueType && ec.OmitStructFlowAnalysis) &&
+                       if ((variable_info != null) && !(TypeManager.IsStruct (type) && ec.OmitStructFlowAnalysis) &&
                            !variable_info.IsAssigned (ec)) {
                                Error (188, "The `this' object cannot be used before all of its " +
                                       "fields are assigned to");
@@ -6739,9 +6544,11 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (1);
                        args.Add (new Argument (this));
-                       args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+                       
+                       // Use typeless constant for ldarg.0 to save some
+                       // space and avoid problems with anonymous stories
                        return CreateExpressionFactoryCall ("Constant", args);
                }
                
@@ -6804,11 +6611,6 @@ namespace Mono.CSharp {
                        target.block = clonectx.LookupBlock (block);
                }
 
-               public void RemoveHoisting ()
-               {
-                       TopToplevelBlock.HoistedThisVariable = null;
-               }
-
                public override void SetHasAddressTaken ()
                {
                        // Nothing
@@ -6839,7 +6641,7 @@ namespace Mono.CSharp {
                        {
                                Error (190, "The __arglist construct is valid only within " +
                                       "a variable argument method");
-                               return null;
+                               return this;
                        }
 
                        return this;
@@ -6859,28 +6661,32 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Represents the `__arglist (....)' construct
        /// </summary>
-       public class Arglist : Expression
+       class Arglist : Expression
        {
-               Argument[] Arguments;
+               Arguments Arguments;
 
                public Arglist (Location loc)
-                       : this (Argument.Empty, loc)
+                       : this (null, loc)
                {
                }
 
-               public Arglist (Argument[] args, Location l)
+               public Arglist (Arguments args, Location l)
                {
                        Arguments = args;
                        loc = l;
                }
 
                public Type[] ArgumentTypes {
-                       get {
-                               Type[] retval = new Type [Arguments.Length];
-                               for (int i = 0; i < Arguments.Length; i++)
-                                       retval [i] = Arguments [i].Type;
-                               return retval;
-                       }
+                   get {
+                               if (Arguments == null)
+                                       return Type.EmptyTypes;
+
+                       Type[] retval = new Type [Arguments.Count];
+                       for (int i = 0; i < retval.Length; i++)
+                           retval [i] = Arguments [i].Expr.Type;
+
+                       return retval;
+                   }
                }
                
                public override Expression CreateExpressionTree (EmitContext ec)
@@ -6892,35 +6698,31 @@ namespace Mono.CSharp {
                public override Expression DoResolve (EmitContext ec)
                {
                        eclass = ExprClass.Variable;
-                       type = TypeManager.runtime_argument_handle_type;
-
-                       foreach (Argument arg in Arguments) {
-                               if (!arg.Resolve (ec, loc))
-                                       return null;
-                       }
+                       type = InternalType.Arglist;
+                       if (Arguments != null)
+                               Arguments.Resolve (ec);
 
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
-                       foreach (Argument arg in Arguments)
-                               arg.Emit (ec);
+                       if (Arguments != null)
+                               Arguments.Emit (ec);
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       foreach (Argument arg in Arguments)
-                               arg.Expr.MutateHoistedGenericType (storey);
+                       if (Arguments != null)
+                               Arguments.MutateHoistedGenericType (storey);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        Arglist target = (Arglist) t;
 
-                       target.Arguments = new Argument [Arguments.Length];
-                       for (int i = 0; i < Arguments.Length; i++)
-                               target.Arguments [i] = Arguments [i].Clone (clonectx);
+                       if (Arguments != null)
+                               target.Arguments = Arguments.Clone (clonectx);
                }
        }
 
@@ -6939,7 +6741,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (this));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        return CreateExpressionFactoryCall ("Constant", args);
@@ -7100,7 +6902,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (this));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        return CreateExpressionFactoryCall ("Constant", args);
@@ -7275,7 +7077,7 @@ namespace Mono.CSharp {
                public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
                        if (alias == GlobalAlias) {
-                               expr = RootNamespace.Global;
+                               expr = GlobalRootNamespace.Instance;
                                return base.ResolveAsTypeStep (ec, silent);
                        }
 
@@ -7355,8 +7157,6 @@ namespace Mono.CSharp {
                        this.expr = expr;
                }
 
-               // TODO: this method has very poor performace for Enum fields and
-               // probably for other constants as well
                Expression DoResolve (EmitContext ec, Expression right_side)
                {
                        if (type != null)
@@ -7379,22 +7179,30 @@ namespace Mono.CSharp {
 
                        string LookupIdentifier = MemberName.MakeName (Name, targs);
 
-                       if (expr_resolved is Namespace) {
-                               Namespace ns = (Namespace) expr_resolved;
+                       Namespace ns = expr_resolved as Namespace;
+                       if (ns != null) {
                                FullNamedExpression retval = ns.Lookup (ec.DeclContainer, LookupIdentifier, loc);
-#if GMCS_SOURCE
-                               if ((retval != null) && (targs != null))
-                                       retval = new ConstructedType (retval, targs, loc).ResolveAsTypeStep (ec, false);
-#endif
 
                                if (retval == null)
-                                       ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, Name);
+                                       ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, LookupIdentifier);
+                               else if (targs != null)
+                                       retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
+
                                return retval;
                        }
 
                        Type expr_type = expr_resolved.Type;
+                       if (expr_type == InternalType.Dynamic) {
+                               Arguments args = new Arguments (2);
+                               args.Add (new Argument (expr_resolved.Resolve (ec)));
+                               if (right_side != null)
+                                       args.Add (new Argument (right_side));
+
+                               return new DynamicMemberBinder (right_side != null, Name, args, loc).Resolve (ec);
+                       }
+
                        if (expr_type.IsPointer || expr_type == TypeManager.void_type ||
-                               expr_resolved is NullLiteral || expr_type == TypeManager.anonymous_method_type) {
+                               expr_type == TypeManager.null_type || expr_type == InternalType.AnonymousMethod) {
                                Unary.Error_OperatorCannotBeApplied (loc, ".", expr_type);
                                return null;
                        }
@@ -7413,12 +7221,12 @@ namespace Mono.CSharp {
                        Expression member_lookup;
                        member_lookup = MemberLookup (
                                ec.ContainerType, expr_type, expr_type, Name, loc);
-#if GMCS_SOURCE
-                       if ((member_lookup == null) && (targs != null)) {
+
+                       if (member_lookup == null && targs != null) {
                                member_lookup = MemberLookup (
                                        ec.ContainerType, expr_type, expr_type, LookupIdentifier, loc);
                        }
-#endif
+
                        if (member_lookup == null) {
                                ExprClass expr_eclass = expr_resolved.eclass;
 
@@ -7441,10 +7249,11 @@ namespace Mono.CSharp {
                                }
 
                                expr = expr_resolved;
-                               Error_MemberLookupFailed (
+                               member_lookup = Error_MemberLookupFailed (
                                        ec.ContainerType, expr_type, expr_type, Name, null,
                                        AllMemberTypes, AllBindingFlags);
-                               return null;
+                               if (member_lookup == null)
+                                       return null;
                        }
 
                        TypeExpr texpr = member_lookup as TypeExpr;
@@ -7462,8 +7271,7 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-#if GMCS_SOURCE
-                               ConstructedType ct = expr_resolved as ConstructedType;
+                               GenericTypeExpr ct = expr_resolved as GenericTypeExpr;
                                if (ct != null) {
                                        //
                                        // When looking up a nested type in a generic instance
@@ -7472,12 +7280,12 @@ namespace Mono.CSharp {
                                        //
                                        // See gtest-172-lib.cs and gtest-172.cs for an example.
                                        //
-                                       ct = new ConstructedType (
+                                       ct = new GenericTypeExpr (
                                                member_lookup.Type, ct.TypeArguments, loc);
 
                                        return ct.ResolveAsTypeStep (ec, false);
                                }
-#endif
+
                                return member_lookup;
                        }
 
@@ -7524,26 +7332,26 @@ namespace Mono.CSharp {
 
                public FullNamedExpression ResolveNamespaceOrType (IResolveContext rc, bool silent)
                {
-                       FullNamedExpression new_expr = expr.ResolveAsTypeStep (rc, silent);
+                       FullNamedExpression expr_resolved = expr.ResolveAsTypeStep (rc, silent);
 
-                       if (new_expr == null)
+                       if (expr_resolved == null)
                                return null;
 
                        string LookupIdentifier = MemberName.MakeName (Name, targs);
 
-                       if (new_expr is Namespace) {
-                               Namespace ns = (Namespace) new_expr;
+                       Namespace ns = expr_resolved as Namespace;
+                       if (ns != null) {
                                FullNamedExpression retval = ns.Lookup (rc.DeclContainer, LookupIdentifier, loc);
-#if GMCS_SOURCE
-                               if ((retval != null) && (targs != null))
-                                       retval = new ConstructedType (retval, targs, loc).ResolveAsTypeStep (rc, false);
-#endif
-                               if (!silent && retval == null)
+
+                               if (retval == null && !silent)
                                        ns.Error_NamespaceDoesNotExist (rc.DeclContainer, loc, LookupIdentifier);
+                               else if (targs != null)
+                                       retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
+
                                return retval;
                        }
 
-                       TypeExpr tnew_expr = new_expr.ResolveAsTypeTerminal (rc, false);
+                       TypeExpr tnew_expr = expr_resolved.ResolveAsTypeTerminal (rc, false);
                        if (tnew_expr == null)
                                return null;
 
@@ -7561,7 +7369,7 @@ namespace Mono.CSharp {
                                if (silent)
                                        return null;
 
-                               Error_IdentifierNotFound (rc, new_expr, LookupIdentifier);
+                               Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
                                return null;
                        }
 
@@ -7569,15 +7377,14 @@ namespace Mono.CSharp {
                        if (texpr == null)
                                return null;
 
-#if GMCS_SOURCE
                        TypeArguments the_args = targs;
                        Type declaring_type = texpr.Type.DeclaringType;
-                       if (TypeManager.HasGenericArguments (declaring_type)) {
+                       if (TypeManager.HasGenericArguments (declaring_type) && !TypeManager.IsGenericTypeDefinition (expr_type)) {
                                while (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (expr_type), declaring_type)) {
                                        expr_type = expr_type.BaseType;
                                }
                                
-                               TypeArguments new_args = new TypeArguments (loc);
+                               TypeArguments new_args = new TypeArguments ();
                                foreach (Type decl in TypeManager.GetTypeArguments (expr_type))
                                        new_args.Add (new TypeExpression (decl, loc));
 
@@ -7588,10 +7395,9 @@ namespace Mono.CSharp {
                        }
 
                        if (the_args != null) {
-                               ConstructedType ctype = new ConstructedType (texpr.Type, the_args, loc);
+                               GenericTypeExpr ctype = new GenericTypeExpr (texpr.Type, the_args, loc);
                                return ctype.ResolveAsTypeStep (rc, false);
                        }
-#endif
 
                        return texpr;
                }
@@ -7607,7 +7413,7 @@ namespace Mono.CSharp {
                                if (expr_type == null)
                                        return;
 
-                               Namespace.Error_TypeArgumentsCannotBeUsed (expr_type.Type, loc);
+                               Namespace.Error_TypeArgumentsCannotBeUsed (expr_type, loc);
                                return;
                        }
 
@@ -7678,7 +7484,7 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return null;
 
-                       if (Expr is Constant || Expr is MethodGroupExpr || Expr is AnonymousMethodExpression)
+                       if (Expr is Constant || Expr is MethodGroupExpr || Expr is AnonymousMethodExpression || Expr is DefaultValueExpression)
                                return Expr;
                        
                        eclass = Expr.eclass;
@@ -7738,7 +7544,7 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return null;
 
-                       if (Expr is Constant || Expr is MethodGroupExpr || Expr is AnonymousMethodExpression)
+                       if (Expr is Constant || Expr is MethodGroupExpr || Expr is AnonymousMethodExpression || Expr is DefaultValueExpression)
                                return Expr;
                        
                        eclass = Expr.eclass;
@@ -7778,43 +7584,30 @@ namespace Mono.CSharp {
        ///   IndexerAccess, ArrayAccess or a PointerArithmetic.
        /// </summary>
        public class ElementAccess : Expression {
-               public ArrayList  Arguments;
+               public Arguments Arguments;
                public Expression Expr;
-               
-               public ElementAccess (Expression e, ArrayList e_list)
+
+               public ElementAccess (Expression e, Arguments args)
                {
                        Expr = e;
                        loc  = e.Location;
-                       
-                       if (e_list == null)
-                               return;
-                       
-                       Arguments = new ArrayList (e_list.Count);
-                       foreach (Expression tmp in e_list)
-                               Arguments.Add (new Argument (tmp, Argument.AType.Expression));
+                       this.Arguments = args;
                }
 
                bool CommonResolve (EmitContext ec)
                {
                        Expr = Expr.Resolve (ec);
 
-                       if (Arguments == null)
-                               return false;
-
-                       foreach (Argument a in Arguments){
-                               if (!a.Resolve (ec, loc))
-                                       return false;
-                       }
+                       if (Arguments != null)
+                               Arguments.Resolve (ec);
 
                        return Expr != null;
                }
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (Arguments.Count + 1);
-                       args.Add (new Argument (Expr.CreateExpressionTree (ec)));
-                       foreach (Argument a in Arguments)
-                               args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
+                       Arguments args = Arguments.CreateForExpressionTree (ec, Arguments,
+                               Expr.CreateExpressionTree (ec));
 
                        return CreateExpressionFactoryCall ("ArrayIndex", args);
                }
@@ -7826,7 +7619,10 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       Expression p = new PointerArithmetic (Binary.Operator.Addition, Expr, ((Argument) Arguments [0]).Expr, t, loc).Resolve (ec);
+                       if (Arguments [0] is NamedArgument)
+                               Error_NamedArgument ((NamedArgument) Arguments[0]);
+
+                       Expression p = new PointerArithmetic (Binary.Operator.Addition, Expr, Arguments [0].Expr, t, loc).Resolve (ec);
                        if (p == null)
                                return null;
                        return new Indirection (p, loc).Resolve (ec);
@@ -7855,6 +7651,13 @@ namespace Mono.CSharp {
                        if (t.IsPointer)
                                return MakePointerAccess (ec, t);
 
+                       if (t == InternalType.Dynamic) {
+                               Arguments args = new Arguments (Arguments.Count + 1);
+                               args.Add (new Argument (Expr));
+                               args.AddRange (Arguments);
+                               return new DynamicIndexBinder (false, args, loc).Resolve (ec);
+                       }
+
                        FieldExpr fe = Expr as FieldExpr;
                        if (fe != null) {
                                IFixedBuffer ff = AttributeTester.GetFixedBuffer (fe.FieldInfo);
@@ -7877,7 +7680,15 @@ namespace Mono.CSharp {
                        if (type.IsPointer)
                                return MakePointerAccess (ec, type);
 
-                       if (Expr.eclass != ExprClass.Variable && type.IsValueType)
+                       if (type == InternalType.Dynamic) {
+                               Arguments args = new Arguments (Arguments.Count + 2);
+                               args.Add (new Argument (Expr));
+                               args.AddRange (Arguments);
+                               args.Add (new Argument (right_side));
+                               return new DynamicIndexBinder (true, args, loc).Resolve (ec);
+                       }
+
+                       if (Expr.eclass != ExprClass.Variable && TypeManager.IsStruct (type))
                                Error_CannotModifyIntermediateExpressionValue (ec);
 
                        return (new IndexerAccess (this, loc)).DoResolveLValue (ec, right_side);
@@ -7888,6 +7699,11 @@ namespace Mono.CSharp {
                        throw new Exception ("Should never be reached");
                }
 
+               public static void Error_NamedArgument (NamedArgument na)
+               {
+                       Report.Error (1742, na.Name.Location, "An element access expression cannot use named argument");
+               }
+
                public override string GetSignatureForError ()
                {
                        return Expr.GetSignatureForError ();
@@ -7898,9 +7714,8 @@ namespace Mono.CSharp {
                        ElementAccess target = (ElementAccess) t;
 
                        target.Expr = Expr.Clone (clonectx);
-                       target.Arguments = new ArrayList (Arguments.Count);
-                       foreach (Argument a in Arguments)
-                               target.Arguments.Add (a.Clone (clonectx));
+                       if (Arguments != null)
+                               target.Arguments = Arguments.Clone (clonectx);
                }
        }
 
@@ -7964,6 +7779,9 @@ namespace Mono.CSharp {
                        }
 
                        foreach (Argument a in ea.Arguments) {
+                               if (a is NamedArgument)
+                                       ElementAccess.Error_NamedArgument ((NamedArgument) a);
+
                                a.Expr = ConvertExpressionToArrayIndex (ec, a.Expr);
                        }
                        
@@ -8008,7 +7826,7 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Ldelem_I);
                        else if (TypeManager.IsEnumType (type)){
                                EmitLoadOpcode (ig, TypeManager.GetEnumUnderlyingType (type), rank);
-                       } else if (type.IsValueType){
+                       } else if (TypeManager.IsStruct (type)){
                                ig.Emit (OpCodes.Ldelema, type);
                                ig.Emit (OpCodes.Ldobj, type);
 #if GMCS_SOURCE
@@ -8055,7 +7873,7 @@ namespace Mono.CSharp {
                                 has_type_arg = true;
                                is_stobj = true;
                                 return OpCodes.Stobj;
-                       } else if (t.IsValueType) {
+                       } else if (TypeManager.IsStruct (t)) {
                                has_type_arg = true;
                                is_stobj = true;
                                return OpCodes.Stobj;
@@ -8073,7 +7891,7 @@ namespace Mono.CSharp {
 
                MethodInfo FetchGetMethod ()
                {
-                       ModuleBuilder mb = CodeGen.Module.Builder;
+                       ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
                        int arg_count = ea.Arguments.Count;
                        Type [] args = new Type [arg_count];
                        MethodInfo get;
@@ -8094,7 +7912,7 @@ namespace Mono.CSharp {
 
                MethodInfo FetchAddressMethod ()
                {
-                       ModuleBuilder mb = CodeGen.Module.Builder;
+                       ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
                        int arg_count = ea.Arguments.Count;
                        Type [] args = new Type [arg_count];
                        MethodInfo address;
@@ -8124,7 +7942,7 @@ namespace Mono.CSharp {
                        ea.Expr.Emit (ec);
 
                        for (int i = 0; i < ea.Arguments.Count; ++i) {
-                               ((Argument)ea.Arguments [i]).Emit (ec);
+                               ea.Arguments [i].Emit (ec);
                        }
                }
 
@@ -8214,7 +8032,7 @@ namespace Mono.CSharp {
                                        }
                                        args [arg_count] = type;
 
-                                       MethodInfo set = CodeGen.Module.Builder.GetArrayMethod (
+                                       MethodInfo set = RootContext.ToplevelTypes.Builder.GetArrayMethod (
                                                ea.Expr.Type, "Set",
                                                CallingConventions.HasThis |
                                                CallingConventions.Standard,
@@ -8230,6 +8048,18 @@ namespace Mono.CSharp {
                        }
                }
 
+               public void EmitNew (EmitContext ec, New source, bool leave_copy)
+               {
+                       if (!source.Emit (ec, this)) {
+                               if (leave_copy)
+                                       throw new NotImplementedException ();
+
+                               return;
+                       }
+
+                       throw new NotImplementedException ();
+               }
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        int rank = ea.Expr.Type.GetArrayRank ();
@@ -8330,14 +8160,18 @@ namespace Mono.CSharp {
                        {
                                Indexers ix = new Indexers ();
 
-       #if GMCS_SOURCE
-                               if (lookup_type.IsGenericParameter) {
+                               if (TypeManager.IsGenericParameter (lookup_type)) {
                                        GenericConstraints gc = TypeManager.GetTypeParameterConstraints (lookup_type);
                                        if (gc == null)
                                                return ix;
 
-                                       if (gc.HasClassConstraint)
-                                               ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, gc.ClassConstraint));
+                                       if (gc.HasClassConstraint) {
+                                               Type class_contraint = gc.ClassConstraint;
+                                               while (class_contraint != TypeManager.object_type && class_contraint != null) {
+                                                       ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, class_contraint));
+                                                       class_contraint = class_contraint.BaseType;
+                                               }
+                                       }
 
                                        Type[] ifaces = gc.InterfaceConstraints;
                                        foreach (Type itype in ifaces)
@@ -8345,7 +8179,6 @@ namespace Mono.CSharp {
 
                                        return ix;
                                }
-       #endif
 
                                Type copy = lookup_type;
                                while (copy != TypeManager.object_type && copy != null){
@@ -8384,7 +8217,7 @@ namespace Mono.CSharp {
                protected Type indexer_type;
                protected Type current_type;
                protected Expression instance_expr;
-               protected ArrayList arguments;
+               protected Arguments arguments;
                
                public IndexerAccess (ElementAccess ea, Location loc)
                        : this (ea.Expr, false, loc)
@@ -8414,11 +8247,9 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (arguments.Count + 2);
-                       args.Add (new Argument (instance_expr.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOfMethodInfo (get, loc)));
-                       foreach (Argument a in arguments)
-                               args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
+                       Arguments args = Arguments.CreateForExpressionTree (ec, arguments,
+                               instance_expr.CreateExpressionTree (ec),
+                               new TypeOfMethodInfo (get, loc));
 
                        return CreateExpressionFactoryCall ("Call", args);
                }
@@ -8584,7 +8415,9 @@ namespace Mono.CSharp {
                                value = temp;
                        }
                        
-                       arguments.Add (new Argument (value, Argument.AType.Expression));
+                       if (!prepared)
+                               arguments.Add (new Argument (value));
+
                        Invocation.EmitCall (ec, is_base_indexer, instance_expr, set, arguments, loc, false, prepared);
                        
                        if (temp != null) {
@@ -8611,8 +8444,8 @@ namespace Mono.CSharp {
                                set = storey.MutateGenericMethod (set);
 
                        instance_expr.MutateHoistedGenericType (storey);
-                       foreach (Argument a in arguments)
-                               a.Expr.MutateHoistedGenericType (storey);
+                       if (arguments != null)
+                               arguments.MutateHoistedGenericType (storey);
 
                        type = storey.MutateType (type);
                }
@@ -8621,11 +8454,9 @@ namespace Mono.CSharp {
                {
                        IndexerAccess target = (IndexerAccess) t;
 
-                       if (arguments != null){
-                               target.arguments = new ArrayList ();
-                               foreach (Argument a in arguments)
-                                       target.arguments.Add (a.Clone (clonectx));
-                       }
+                       if (arguments != null)
+                               target.arguments = arguments.Clone (clonectx);
+
                        if (instance_expr != null)
                                target.instance_expr = instance_expr.Clone (clonectx);
                }
@@ -8748,12 +8579,10 @@ namespace Mono.CSharp {
        ///   The base indexer operator
        /// </summary>
        public class BaseIndexerAccess : IndexerAccess {
-               public BaseIndexerAccess (ArrayList args, Location loc)
+               public BaseIndexerAccess (Arguments args, Location loc)
                        : base (null, true, loc)
                {
-                       arguments = new ArrayList ();
-                       foreach (Expression tmp in args)
-                               arguments.Add (new Argument (tmp, Argument.AType.Expression));
+                       this.arguments = args;
                }
 
                protected override bool CommonResolve (EmitContext ec)
@@ -8763,10 +8592,7 @@ namespace Mono.CSharp {
                        current_type = ec.ContainerType.BaseType;
                        indexer_type = current_type;
 
-                       foreach (Argument a in arguments){
-                               if (!a.Resolve (ec, loc))
-                                       return false;
-                       }
+                       arguments.Resolve (ec);
 
                        return true;
                }
@@ -8809,9 +8635,9 @@ namespace Mono.CSharp {
                        temp = e;
                }
 
-               // TODO: should be protected
-               public EmptyExpression ()
+               EmptyExpression ()
                {
+                       // FIXME: Don't set to object
                        type = TypeManager.object_type;
                        eclass = ExprClass.Value;
                        loc = Location.Null;
@@ -8863,7 +8689,6 @@ namespace Mono.CSharp {
 
                private EmptyExpressionStatement ()
                {
-                       type = TypeManager.object_type;
                        eclass = ExprClass.Value;
                        loc = Location.Null;
                }
@@ -8880,6 +8705,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       type = TypeManager.object_type;
                        return this;
                }
 
@@ -8909,7 +8735,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (3);
+                       Arguments args = new Arguments (3);
                        args.Add (new Argument (source.CreateExpressionTree (ec)));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
                        args.Add (new Argument (new TypeOfMethodInfo (method, loc)));
@@ -8973,14 +8799,12 @@ namespace Mono.CSharp {
                                return null;
 
                        Type ltype = lexpr.Type;
-#if GMCS_SOURCE
                        if ((dim.Length > 0) && (dim [0] == '?')) {
-                               TypeExpr nullable = new Nullable.NullableType (left, loc);
+                               TypeExpr nullable = new Nullable.NullableType (lexpr, loc);
                                if (dim.Length > 1)
                                        nullable = new ComposedCast (nullable, dim.Substring (1), loc);
                                return nullable.ResolveAsTypeTerminal (ec, false);
                        }
-#endif
 
                        if (dim == "*" && !TypeManager.VerifyUnManaged (ltype, loc))
                                return null;
@@ -9019,13 +8843,6 @@ namespace Mono.CSharp {
                        return left.GetSignatureForError () + dim;
                }
 
-               protected override void CloneTo (CloneContext clonectx, Expression t)
-               {
-                       ComposedCast target = (ComposedCast) t;
-
-                       target.left = (FullNamedExpression)left.Clone (clonectx);
-               }
-               
                public override TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
                {
                        return ResolveAsBaseTerminal (ec, silent);
@@ -9101,7 +8918,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       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 ("ConvertChecked", args);
@@ -9228,7 +9045,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        FieldExpr fe = target as FieldExpr;
                        if (fe != null)
                                args.Add (new Argument (fe.CreateTypeOfExpression ()));
@@ -9277,12 +9094,12 @@ namespace Mono.CSharp {
                        //
                        Constant c = source as Constant;
                        if (c != null && c.IsDefaultInitializer (type) && target.eclass == ExprClass.Variable)
-                               return EmptyExpressionStatement.Instance;
+                               return EmptyExpressionStatement.Instance.DoResolve (ec);
 
                        return expr;
                }
 
-               protected override Expression Error_MemberLookupFailed (MemberInfo[] members)
+               protected override Expression Error_MemberLookupFailed (Type type, MemberInfo[] members)
                {
                        MemberInfo member = members [0];
                        if (member.MemberType != MemberTypes.Property && member.MemberType != MemberTypes.Field)
@@ -9307,7 +9124,7 @@ namespace Mono.CSharp {
        //
        // A collection initializer expression
        //
-       public class CollectionElementInitializer : Invocation
+       class CollectionElementInitializer : Invocation
        {
                public class ElementInitializerArgument : Argument
                {
@@ -9334,26 +9151,29 @@ namespace Mono.CSharp {
                }
 
                public CollectionElementInitializer (Expression argument)
-                       : base (null, new ArrayList (1), true)
+                       : base (null, new Arguments (1), true)
                {
-                       Arguments.Add (argument);
+                       base.arguments.Add (new ElementInitializerArgument (argument));
                        this.loc = argument.Location;
                }
 
                public CollectionElementInitializer (ArrayList arguments, Location loc)
-                       : base (null, arguments, true)
+                       : base (null, new Arguments (arguments.Count), true)
                {
+                       foreach (Expression e in arguments)
+                               base.arguments.Add (new ElementInitializerArgument (e));
+
                        this.loc = loc;
                }
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (mg.CreateExpressionTree (ec)));
 
-                       ArrayList expr_initializers = new ArrayList (Arguments.Count);
-                       foreach (Argument a in Arguments)
-                               expr_initializers.Add (a.Expr.CreateExpressionTree (ec));
+                       ArrayList expr_initializers = new ArrayList (arguments.Count);
+                       foreach (Argument a in arguments)
+                               expr_initializers.Add (a.CreateExpressionTree (ec));
 
                        args.Add (new Argument (new ArrayCreation (
                                CreateExpressionTypeExpression (loc), "[]", expr_initializers, loc)));
@@ -9363,10 +9183,8 @@ namespace Mono.CSharp {
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        CollectionElementInitializer target = (CollectionElementInitializer) t;
-
-                       target.Arguments = new ArrayList (Arguments.Count);
-                       foreach (Expression e in Arguments)
-                               target.Arguments.Add (e.Clone (clonectx));
+                       if (arguments != null)
+                               target.arguments = arguments.Clone (clonectx);
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -9376,18 +9194,8 @@ namespace Mono.CSharp {
 
                        // TODO: We could call a constructor which takes element count argument,
                        // for known types like List<T>, Dictionary<T, U>
-                       
-                       for (int i = 0; i < Arguments.Count; ++i) {
-                               Expression expr = Arguments [i] as Expression;
-                               if (expr == null)
-                                       return null;
 
-                               expr = expr.Resolve (ec);
-                               if (expr == null)
-                                       return null;
-
-                               Arguments [i] = new ElementInitializerArgument (expr);
-                       }
+                       arguments.Resolve (ec);
 
                        base.expr = new AddMemberAccess (ec.CurrentInitializerVariable, loc);
 
@@ -9401,6 +9209,7 @@ namespace Mono.CSharp {
        public class CollectionOrObjectInitializers : ExpressionStatement
        {
                ArrayList initializers;
+               bool is_collection_initialization;
                
                public static readonly CollectionOrObjectInitializers Empty = 
                        new CollectionOrObjectInitializers (new ArrayList (0), Location.Null);
@@ -9419,7 +9228,7 @@ namespace Mono.CSharp {
 
                public bool IsCollectionInitializer {
                        get {
-                               return type == typeof (CollectionOrObjectInitializers);
+                               return is_collection_initialization;
                        }
                }
 
@@ -9449,7 +9258,6 @@ namespace Mono.CSharp {
                        if (eclass != ExprClass.Invalid)
                                return this;
 
-                       bool is_collection_initialization = false;
                        ArrayList element_names = null;
                        for (int i = 0; i < initializers.Count; ++i) {
                                Expression initializer = (Expression) initializers [i];
@@ -9459,9 +9267,11 @@ namespace Mono.CSharp {
                                        if (element_initializer != null) {
                                                element_names = new ArrayList (initializers.Count);
                                                element_names.Add (element_initializer.Name);
+                                       } else if (initializer is CompletingExpression){
+                                               initializer.Resolve (ec);
+                                               throw new InternalErrorException ("This line should never be reached");
                                        } else {
-                                               if (!TypeManager.ImplementsInterface (ec.CurrentInitializerVariable.Type,
-                                                       TypeManager.ienumerable_type)) {
+                                               if (!TypeManager.ImplementsInterface (ec.CurrentInitializerVariable.Type, TypeManager.ienumerable_type)) {
                                                        Report.Error (1922, loc, "A field or property `{0}' cannot be initialized with a collection " +
                                                                "object initializer because type `{1}' does not implement `{2}' interface",
                                                                ec.CurrentInitializerVariable.GetSignatureForError (),
@@ -9496,15 +9306,12 @@ namespace Mono.CSharp {
                                        initializers [i] = e;
                        }
 
+                       type = ec.CurrentInitializerVariable.Type;
                        if (is_collection_initialization) {
-                               if (TypeManager.HasElementType (ec.CurrentInitializerVariable.Type)) {
+                               if (TypeManager.HasElementType (type)) {
                                        Report.Error (1925, loc, "Cannot initialize object of type `{0}' with a collection initializer",
-                                               TypeManager.CSharpName (ec.CurrentInitializerVariable.Type));
+                                               TypeManager.CSharpName (type));
                                }
-
-                               type = typeof (CollectionOrObjectInitializers);
-                       } else {
-                               type = typeof (ElementInitializer);
                        }
 
                        eclass = ExprClass.Variable;
@@ -9569,27 +9376,39 @@ namespace Mono.CSharp {
 
                        public override void Emit (EmitContext ec)
                        {
-                               new_instance.value_target.Emit (ec);
+                               Expression e = (Expression) new_instance.instance;
+                               e.Emit (ec);
                        }
 
                        #region IMemoryLocation Members
 
                        public void AddressOf (EmitContext ec, AddressOp mode)
                        {
-                               ((IMemoryLocation)new_instance.value_target).AddressOf (ec, mode);
+                               new_instance.instance.AddressOf (ec, mode);
                        }
 
                        #endregion
                }
 
                CollectionOrObjectInitializers initializers;
+               IMemoryLocation instance;
 
-               public NewInitialize (Expression requested_type, ArrayList arguments, CollectionOrObjectInitializers initializers, Location l)
+               public NewInitialize (Expression requested_type, Arguments arguments, CollectionOrObjectInitializers initializers, Location l)
                        : base (requested_type, arguments, l)
                {
                        this.initializers = initializers;
                }
 
+               protected override IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp Mode)
+               {
+                       instance = base.EmitAddressOf (ec, Mode);
+
+                       if (!initializers.IsEmpty)
+                               initializers.Emit (ec);
+
+                       return instance;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        base.CloneTo (clonectx, t);
@@ -9600,7 +9419,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (base.CreateExpressionTree (ec)));
                        if (!initializers.IsEmpty)
                                args.Add (new Argument (initializers.CreateExpressionTree (ec)));
@@ -9619,12 +9438,6 @@ namespace Mono.CSharp {
                        if (type == null)
                                return null;
 
-                       // Empty initializer can be optimized to simple new
-                       if (initializers.IsEmpty) {
-                               initializers.Resolve (ec);
-                               return ReducedExpression.Create (e, this).Resolve (ec);
-                       }
-
                        Expression previous = ec.CurrentInitializerVariable;
                        ec.CurrentInitializerVariable = new InitializerTargetExpression (this);
                        initializers.Resolve (ec);
@@ -9632,51 +9445,41 @@ namespace Mono.CSharp {
                        return e;
                }
 
-               public override void Emit (EmitContext ec)
+               public override bool Emit (EmitContext ec, IMemoryLocation target)
                {
-                       base.Emit (ec);
+                       bool left_on_stack = base.Emit (ec, target);
 
-                       //
-                       // If target is non-hoisted variable, let's use it
-                       //
-                       VariableReference variable = value_target as VariableReference;
-                       if (variable != null && variable.HoistedVariable == null) {
-                               if (variable.IsRef)
-                                       StoreFromPtr (ec.ig, type);
-                               else
-                                       variable.EmitAssign (ec, EmptyExpression.Null, false, false);
-                       } else {
-                               variable = null;
-                               if (value_target == null || value_target_set)
-                                       value_target = new LocalTemporary (type);
+                       if (initializers.IsEmpty)
+                               return left_on_stack;
 
-                               ((LocalTemporary) value_target).Store (ec);
-                       }
+                       LocalTemporary temp = target as LocalTemporary;
+                       if (temp == null) {
+                               if (!left_on_stack) {
+                                       VariableReference vr = target as VariableReference;
+                                       
+                                       // FIXME: This still does not work correctly for pre-set variables
+                                       if (vr != null && vr.IsRef)
+                                               target.AddressOf (ec, AddressOp.Load);
 
-                       initializers.Emit (ec);
+                                       ((Expression) target).Emit (ec);
+                                       left_on_stack = true;
+                               }
 
-                       if (variable == null) {
-                               value_target.Emit (ec);
-                               value_target = null;
+                               temp = new LocalTemporary (type);
                        }
-               }
 
-               public override void EmitStatement (EmitContext ec)
-               {
-                       if (initializers.IsEmpty) {
-                               base.EmitStatement (ec);
-                               return;
-                       }
+                       instance = temp;
+                       if (left_on_stack)
+                               temp.Store (ec);
 
-                       base.Emit (ec);
+                       initializers.Emit (ec);
 
-                       if (value_target == null) {
-                               LocalTemporary variable = new LocalTemporary (type);
-                               variable.Store (ec);
-                               value_target = variable;
+                       if (left_on_stack) {
+                               temp.Emit (ec);
+                               temp.Release (ec);
                        }
 
-                       initializers.EmitStatement (ec);
+                       return left_on_stack;
                }
 
                public override bool HasInitializer {
@@ -9718,7 +9521,7 @@ namespace Mono.CSharp {
 
                AnonymousTypeClass CreateAnonymousType (ArrayList parameters)
                {
-                       AnonymousTypeClass type = RootContext.ToplevelTypes.GetAnonymousType (parameters);
+                       AnonymousTypeClass type = parent.Module.GetAnonymousType (parameters);
                        if (type != null)
                                return type;
 
@@ -9732,7 +9535,7 @@ namespace Mono.CSharp {
                        if (Report.Errors == 0)
                                type.CloseType ();
 
-                       RootContext.ToplevelTypes.AddAnonymousType (type);
+                       parent.Module.AddAnonymousType (type);
                        return type;
                }
 
@@ -9757,7 +9560,7 @@ namespace Mono.CSharp {
                        }
 
                        bool error = false;
-                       ArrayList arguments = new ArrayList (parameters.Count);
+                       Arguments 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);
@@ -9777,8 +9580,8 @@ namespace Mono.CSharp {
                        if (anonymous_type == null)
                                return null;
 
-                       ConstructedType te = new ConstructedType (anonymous_type.TypeBuilder,
-                               new TypeArguments (loc, t_args), loc);
+                       GenericTypeExpr te = new GenericTypeExpr (anonymous_type.TypeBuilder,
+                               new TypeArguments (t_args), loc);
 
                        return new New (te, arguments, loc).Resolve (ec);
                }
@@ -9843,7 +9646,7 @@ namespace Mono.CSharp {
 
                        type = e.Type;
                        if (type == TypeManager.void_type || type == TypeManager.null_type ||
-                               type == TypeManager.anonymous_method_type || type.IsPointer) {
+                               type == InternalType.AnonymousMethod || type.IsPointer) {
                                Error_InvalidInitializer (e.GetSignatureForError ());
                                return null;
                        }