2010-06-01 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / statement.cs
index 880ec5670e0e9ce4d00a44c74f3bf91924097170..3548ebfe94d875beb808c04098fe424628942b4b 100644 (file)
@@ -15,8 +15,7 @@ using System.Text;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
-using System.Collections;
-using System.Collections.Specialized;
+using System.Collections.Generic;
 
 namespace Mono.CSharp {
        
@@ -27,7 +26,7 @@ namespace Mono.CSharp {
                ///   Resolves the statement, true means that all sub-statements
                ///   did resolve ok.
                //  </summary>
-               public virtual bool Resolve (EmitContext ec)
+               public virtual bool Resolve (BlockContext ec)
                {
                        return true;
                }
@@ -36,7 +35,7 @@ namespace Mono.CSharp {
                ///   We already know that the statement is unreachable, but we still
                ///   need to resolve it to catch errors.
                /// </summary>
-               public virtual bool ResolveUnreachable (EmitContext ec, bool warn)
+               public virtual bool ResolveUnreachable (BlockContext ec, bool warn)
                {
                        //
                        // This conflicts with csc's way of doing this, but IMHO it's
@@ -48,7 +47,7 @@ namespace Mono.CSharp {
                        //
 
                        if (warn)
-                               Report.Warning (162, 2, loc, "Unreachable code detected");
+                               ec.Report.Warning (162, 2, loc, "Unreachable code detected");
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
                        bool ok = Resolve (ec);
@@ -62,22 +61,6 @@ namespace Mono.CSharp {
                /// </summary>
                protected abstract void DoEmit (EmitContext ec);
 
-               /// <summary>
-               ///   Utility wrapper routine for Error, just to beautify the code
-               /// </summary>
-               public void Error (int error, string format, params object[] args)
-               {
-                       Error (error, String.Format (format, args));
-               }
-
-               public void Error (int error, string s)
-               {
-                       if (!loc.IsNull)
-                               Report.Error (error, loc, s);
-                       else
-                               Report.Error (error, s);
-               }
-
                public virtual void Emit (EmitContext ec)
                {
                        ec.Mark (loc);
@@ -97,9 +80,9 @@ namespace Mono.CSharp {
                        return s;
                }
 
-               public virtual Expression CreateExpressionTree (EmitContext ec)
+               public virtual Expression CreateExpressionTree (ResolveContext ec)
                {
-                       Report.Error (834, loc, "A lambda expression with statement body cannot be converted to an expresion tree");
+                       ec.Report.Error (834, loc, "A lambda expression with statement body cannot be converted to an expresion tree");
                        return null;
                }
 
@@ -109,96 +92,32 @@ namespace Mono.CSharp {
 
                        return Clone (clonectx);
                }
-
-               public abstract void MutateHoistedGenericType (AnonymousMethodStorey storey);
        }
 
-       //
-       // This class is used during the Statement.Clone operation
-       // to remap objects that have been cloned.
-       //
-       // Since blocks are cloned by Block.Clone, we need a way for
-       // expressions that must reference the block to be cloned
-       // pointing to the new cloned block.
-       //
-       public class CloneContext {
-               Hashtable block_map = new Hashtable ();
-               Hashtable variable_map;
-               
-               public void AddBlockMap (Block from, Block to)
-               {
-                       if (block_map.Contains (from))
-                               return;
-                       block_map [from] = to;
-               }
-               
-               public Block LookupBlock (Block from)
-               {
-                       Block result = (Block) block_map [from];
-
-                       if (result == null){
-                               result = (Block) from.Clone (this);
-                               block_map [from] = result;
-                       }
-
-                       return result;
-               }
-
-               ///
-               /// Remaps block to cloned copy if one exists.
-               ///
-               public Block RemapBlockCopy (Block from)
-               {
-                       Block mapped_to = (Block)block_map[from];
-                       if (mapped_to == null)
-                               return from;
-
-                       return mapped_to;
-               }
-
-               public void AddVariableMap (LocalInfo from, LocalInfo to)
+       public sealed class EmptyStatement : Statement
+       {
+               public EmptyStatement (Location loc)
                {
-                       if (variable_map == null)
-                               variable_map = new Hashtable ();
-                       
-                       if (variable_map.Contains (from))
-                               return;
-                       variable_map [from] = to;
+                       this.loc = loc;
                }
                
-               public LocalInfo LookupVariable (LocalInfo from)
-               {
-                       LocalInfo result = (LocalInfo) variable_map [from];
-
-                       if (result == null)
-                               throw new Exception ("LookupVariable: looking up a variable that has not been registered yet");
-
-                       return result;
-               }
-       }
-       
-       public sealed class EmptyStatement : Statement {
-               
-               private EmptyStatement () {}
-               
-               public static readonly EmptyStatement Value = new EmptyStatement ();
-               
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        return true;
                }
 
-               public override bool ResolveUnreachable (EmitContext ec, bool warn)
+               public override bool ResolveUnreachable (BlockContext ec, bool warn)
                {
                        return true;
                }
 
-               protected override void DoEmit (EmitContext ec)
+               public override void Emit (EmitContext ec)
                {
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               protected override void DoEmit (EmitContext ec)
                {
+                       throw new NotSupportedException ();
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement target)
@@ -213,77 +132,61 @@ namespace Mono.CSharp {
                public Statement FalseStatement;
 
                bool is_true_ret;
-               
-               public If (Expression expr, Statement true_statement, Location l)
+
+               public If (Expression bool_expr, Statement true_statement, Location l)
+                       : this (bool_expr, true_statement, null, l)
                {
-                       this.expr = expr;
-                       TrueStatement = true_statement;
-                       loc = l;
                }
 
-               public If (Expression expr,
+               public If (Expression bool_expr,
                           Statement true_statement,
                           Statement false_statement,
                           Location l)
                {
-                       this.expr = expr;
+                       this.expr = bool_expr;
                        TrueStatement = true_statement;
                        FalseStatement = false_statement;
                        loc = l;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       TrueStatement.MutateHoistedGenericType (storey);
-                       if (FalseStatement != null)
-                               FalseStatement.MutateHoistedGenericType (storey);
-               }
-
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
                        Report.Debug (1, "START IF BLOCK", loc);
 
-                       expr = Expression.ResolveBoolean (ec, expr, loc);
-                       if (expr == null){
+                       expr = expr.Resolve (ec);
+                       if (expr == null) {
                                ok = false;
-                               goto skip;
-                       }
-
-                       Assign ass = expr as Assign;
-                       if (ass != null && ass.Source is Constant) {
-                               Report.Warning (665, 3, loc, "Assignment in conditional expression is always constant; did you mean to use == instead of = ?");
-                       }
+                       } else {
+                               //
+                               // Dead code elimination
+                               //
+                               if (expr is Constant) {
+                                       bool take = !((Constant) expr).IsDefaultValue;
 
-                       //
-                       // Dead code elimination
-                       //
-                       if (expr is Constant){
-                               bool take = !((Constant) expr).IsDefaultValue;
+                                       if (take) {
+                                               if (!TrueStatement.Resolve (ec))
+                                                       return false;
 
-                               if (take){
-                                       if (!TrueStatement.Resolve (ec))
-                                               return false;
+                                               if ((FalseStatement != null) &&
+                                                       !FalseStatement.ResolveUnreachable (ec, true))
+                                                       return false;
+                                               FalseStatement = null;
+                                       } else {
+                                               if (!TrueStatement.ResolveUnreachable (ec, true))
+                                                       return false;
+                                               TrueStatement = null;
 
-                                       if ((FalseStatement != null) &&
-                                           !FalseStatement.ResolveUnreachable (ec, true))
-                                               return false;
-                                       FalseStatement = null;
-                               } else {
-                                       if (!TrueStatement.ResolveUnreachable (ec, true))
-                                               return false;
-                                       TrueStatement = null;
+                                               if ((FalseStatement != null) &&
+                                                       !FalseStatement.Resolve (ec))
+                                                       return false;
+                                       }
 
-                                       if ((FalseStatement != null) &&
-                                           !FalseStatement.Resolve (ec))
-                                               return false;
+                                       return true;
                                }
-
-                               return true;
                        }
-               skip:
+
                        ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
                        
                        ok &= TrueStatement.Resolve (ec);
@@ -304,8 +207,7 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label false_target = ig.DefineLabel ();
+                       Label false_target = ec.DefineLabel ();
                        Label end;
 
                        //
@@ -331,19 +233,19 @@ namespace Mono.CSharp {
                        if (FalseStatement != null){
                                bool branch_emitted = false;
                                
-                               end = ig.DefineLabel ();
+                               end = ec.DefineLabel ();
                                if (!is_true_ret){
-                                       ig.Emit (OpCodes.Br, end);
+                                       ec.Emit (OpCodes.Br, end);
                                        branch_emitted = true;
                                }
 
-                               ig.MarkLabel (false_target);
+                               ec.MarkLabel (false_target);
                                FalseStatement.Emit (ec);
 
                                if (branch_emitted)
-                                       ig.MarkLabel (end);
+                                       ec.MarkLabel (end);
                        } else {
-                               ig.MarkLabel (false_target);
+                               ec.MarkLabel (false_target);
                        }
                }
 
@@ -361,15 +263,15 @@ namespace Mono.CSharp {
        public class Do : Statement {
                public Expression expr;
                public Statement  EmbeddedStatement;
-               
-               public Do (Statement statement, Expression bool_expr, Location l)
+
+               public Do (Statement statement, BooleanExpression bool_expr, Location l)
                {
                        expr = bool_expr;
                        EmbeddedStatement = statement;
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
@@ -383,9 +285,9 @@ namespace Mono.CSharp {
                        ec.EndFlowBranching ();
 
                        if (ec.CurrentBranching.CurrentUsageVector.IsUnreachable && !was_unreachable)
-                               Report.Warning (162, 2, expr.Location, "Unreachable code detected");
+                               ec.Report.Warning (162, 2, expr.Location, "Unreachable code detected");
 
-                       expr = Expression.ResolveBoolean (ec, expr, loc);
+                       expr = expr.Resolve (ec);
                        if (expr == null)
                                ok = false;
                        else if (expr is Constant){
@@ -401,17 +303,16 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label loop = ig.DefineLabel ();
+                       Label loop = ec.DefineLabel ();
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
                        
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
                                
-                       ig.MarkLabel (loop);
+                       ec.MarkLabel (loop);
                        EmbeddedStatement.Emit (ec);
-                       ig.MarkLabel (ec.LoopBegin);
+                       ec.MarkLabel (ec.LoopBegin);
 
                        //
                        // Dead code elimination
@@ -421,22 +322,16 @@ namespace Mono.CSharp {
 
                                expr.EmitSideEffect (ec);
                                if (res)
-                                       ec.ig.Emit (OpCodes.Br, loop); 
+                                       ec.Emit (OpCodes.Br, loop); 
                        } else
                                expr.EmitBranchable (ec, loop, true);
                        
-                       ig.MarkLabel (ec.LoopEnd);
+                       ec.MarkLabel (ec.LoopEnd);
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       EmbeddedStatement.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Do target = (Do) t;
@@ -450,21 +345,21 @@ namespace Mono.CSharp {
                public Expression expr;
                public Statement Statement;
                bool infinite, empty;
-               
-               public While (Expression bool_expr, Statement statement, Location l)
+
+               public While (BooleanExpression bool_expr, Statement statement, Location l)
                {
                        this.expr = bool_expr;
                        Statement = statement;
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
-                       expr = Expression.ResolveBoolean (ec, expr, loc);
+                       expr = expr.Resolve (ec);
                        if (expr == null)
-                               return false;
+                               ok = false;
 
                        //
                        // Inform whether we are infinite or not
@@ -505,42 +400,41 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       ILGenerator ig = ec.ig;
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
                        
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
 
                        //
                        // Inform whether we are infinite or not
                        //
                        if (expr is Constant){
                                // expr is 'true', since the 'empty' case above handles the 'false' case
-                               ig.MarkLabel (ec.LoopBegin);
+                               ec.MarkLabel (ec.LoopBegin);
                                expr.EmitSideEffect (ec);
                                Statement.Emit (ec);
-                               ig.Emit (OpCodes.Br, ec.LoopBegin);
+                               ec.Emit (OpCodes.Br, ec.LoopBegin);
                                        
                                //
                                // Inform that we are infinite (ie, `we return'), only
                                // if we do not `break' inside the code.
                                //
-                               ig.MarkLabel (ec.LoopEnd);
+                               ec.MarkLabel (ec.LoopEnd);
                        } else {
-                               Label while_loop = ig.DefineLabel ();
+                               Label while_loop = ec.DefineLabel ();
 
-                               ig.Emit (OpCodes.Br, ec.LoopBegin);
-                               ig.MarkLabel (while_loop);
+                               ec.Emit (OpCodes.Br, ec.LoopBegin);
+                               ec.MarkLabel (while_loop);
 
                                Statement.Emit (ec);
                        
-                               ig.MarkLabel (ec.LoopBegin);
+                               ec.MarkLabel (ec.LoopBegin);
                                ec.Mark (loc);
 
                                expr.EmitBranchable (ec, while_loop, true);
                                
-                               ig.MarkLabel (ec.LoopEnd);
+                               ec.MarkLabel (ec.LoopEnd);
                        }       
 
                        ec.LoopBegin = old_begin;
@@ -559,12 +453,6 @@ namespace Mono.CSharp {
                        target.expr = expr.Clone (clonectx);
                        target.Statement = Statement.Clone (clonectx);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       Statement.MutateHoistedGenericType (storey);
-               }
        }
 
        public class For : Statement {
@@ -575,7 +463,7 @@ namespace Mono.CSharp {
                bool infinite, empty;
                
                public For (Statement init_statement,
-                           Expression test,
+                           BooleanExpression test,
                            Statement increment,
                            Statement statement,
                            Location l)
@@ -587,7 +475,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
@@ -597,7 +485,7 @@ namespace Mono.CSharp {
                        }
 
                        if (Test != null){
-                               Test = Expression.ResolveBoolean (ec, Test, loc);
+                               Test = Test.Resolve (ec);
                                if (Test == null)
                                        ok = false;
                                else if (Test is Constant){
@@ -648,7 +536,7 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       if (InitStatement != null && InitStatement != EmptyStatement.Value)
+                       if (InitStatement != null)
                                InitStatement.Emit (ec);
 
                        if (empty) {
@@ -656,24 +544,22 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       ILGenerator ig = ec.ig;
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
-                       Label loop = ig.DefineLabel ();
-                       Label test = ig.DefineLabel ();
+                       Label loop = ec.DefineLabel ();
+                       Label test = ec.DefineLabel ();
 
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
 
-                       ig.Emit (OpCodes.Br, test);
-                       ig.MarkLabel (loop);
+                       ec.Emit (OpCodes.Br, test);
+                       ec.MarkLabel (loop);
                        Statement.Emit (ec);
 
-                       ig.MarkLabel (ec.LoopBegin);
-                       if (Increment != EmptyStatement.Value)
-                               Increment.Emit (ec);
+                       ec.MarkLabel (ec.LoopBegin);
+                       Increment.Emit (ec);
 
-                       ig.MarkLabel (test);
+                       ec.MarkLabel (test);
                        //
                        // If test is null, there is no test, and we are just
                        // an infinite loop
@@ -686,31 +572,19 @@ namespace Mono.CSharp {
                                //
                                if (Test is Constant) {
                                        Test.EmitSideEffect (ec);
-                                       ig.Emit (OpCodes.Br, loop);
+                                       ec.Emit (OpCodes.Br, loop);
                                } else {
                                        Test.EmitBranchable (ec, loop, true);
                                }
                                
                        } else
-                               ig.Emit (OpCodes.Br, loop);
-                       ig.MarkLabel (ec.LoopEnd);
+                               ec.Emit (OpCodes.Br, loop);
+                       ec.MarkLabel (ec.LoopEnd);
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (InitStatement != null)
-                               InitStatement.MutateHoistedGenericType (storey);
-                       if (Test != null)
-                               Test.MutateHoistedGenericType (storey);
-                       if (Increment != null)
-                               Increment.MutateHoistedGenericType (storey);
-
-                       Statement.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        For target = (For) t;
@@ -734,10 +608,9 @@ namespace Mono.CSharp {
                        loc = expr.Location;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       if (expr != null)
-                               expr = expr.ResolveStatement (ec);
+                       expr = expr.ResolveStatement (ec);
                        return expr != null;
                }
                
@@ -746,11 +619,6 @@ namespace Mono.CSharp {
                        expr.EmitStatement (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-               }
-
                public override string ToString ()
                {
                        return "StatementExpression (" + expr + ")";
@@ -768,14 +636,14 @@ namespace Mono.CSharp {
        public abstract class ExitStatement : Statement
        {
                protected bool unwind_protect;
-               protected abstract bool DoResolve (EmitContext ec);
+               protected abstract bool DoResolve (BlockContext ec);
 
-               public virtual void Error_FinallyClause ()
+               public virtual void Error_FinallyClause (Report Report)
                {
                        Report.Error (157, loc, "Control cannot leave the body of a finally clause");
                }
 
-               public sealed override bool Resolve (EmitContext ec)
+               public sealed override bool Resolve (BlockContext ec)
                {
                        if (!DoResolve (ec))
                                return false;
@@ -799,55 +667,48 @@ namespace Mono.CSharp {
                        loc = l;
                }
                
-               protected override bool DoResolve (EmitContext ec)
+               protected override bool DoResolve (BlockContext ec)
                {
                        if (Expr == null) {
                                if (ec.ReturnType == TypeManager.void_type)
                                        return true;
                                
-                               Error (126, "An object of a type convertible to `{0}' is required " +
-                                          "for the return statement",
-                                          TypeManager.CSharpName (ec.ReturnType));
+                               ec.Report.Error (126, loc,
+                                       "An object of a type convertible to `{0}' is required for the return statement",
+                                       TypeManager.CSharpName (ec.ReturnType));
                                return false;
                        }
 
                        if (ec.CurrentBlock.Toplevel.IsIterator) {
-                               Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return " +
+                               ec.Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return " +
                                                  "statement to return a value, or yield break to end the iteration");
                        }
 
                        AnonymousExpression am = ec.CurrentAnonymousMethod;
                        if (am == null && ec.ReturnType == TypeManager.void_type) {
-                               MemberCore mc = ec.ResolveContext as MemberCore;
-                               Report.Error (127, loc, "`{0}': A return keyword must not be followed by any expression when method returns void",
-                                       mc.GetSignatureForError ());
+                               ec.Report.Error (127, loc, "`{0}': A return keyword must not be followed by any expression when method returns void",
+                                       ec.GetSignatureForError ());
                        }
 
                        Expr = Expr.Resolve (ec);
                        if (Expr == null)
                                return false;
 
+                       if (ec.HasSet (ResolveContext.Options.InferReturnType)) {
+                               ec.ReturnTypeInference.AddCommonTypeBound (Expr.Type);
+                               return true;
+                       }
+
                        if (Expr.Type != ec.ReturnType) {
-                               if (ec.InferReturnType) {
-                                       //
-                                       // void cannot be used in contextual return
-                                       //
-                                       if (Expr.Type == TypeManager.void_type)
-                                               return false;
+                               Expr = Convert.ImplicitConversionRequired (ec, Expr, ec.ReturnType, loc);
 
-                                       ec.ReturnType = Expr.Type;
-                               } else {
-                                       Expr = Convert.ImplicitConversionRequired (
-                                               ec, Expr, ec.ReturnType, loc);
-
-                                       if (Expr == null) {
-                                               if (am != null) {
-                                                       Report.Error (1662, loc,
-                                                               "Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type",
-                                                               am.ContainerType, am.GetSignatureForError ());
-                                               }
-                                               return false;
+                               if (Expr == null) {
+                                       if (am != null) {
+                                               ec.Report.Error (1662, loc,
+                                                       "Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type",
+                                                       am.ContainerType, am.GetSignatureForError ());
                                        }
+                                       return false;
                                }
                        }
 
@@ -860,19 +721,13 @@ namespace Mono.CSharp {
                                Expr.Emit (ec);
 
                                if (unwind_protect)
-                                       ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
+                                       ec.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
                        }
 
                        if (unwind_protect)
-                               ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
+                               ec.Emit (OpCodes.Leave, ec.ReturnLabel);
                        else
-                               ec.ig.Emit (OpCodes.Ret);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (Expr != null)
-                               Expr.MutateHoistedGenericType (storey);
+                               ec.Emit (OpCodes.Ret);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -888,13 +743,12 @@ namespace Mono.CSharp {
                string target;
                LabeledStatement label;
                bool unwind_protect;
-               
-               public override bool Resolve (EmitContext ec)
+
+               public override bool Resolve (BlockContext ec)
                {
-                       int errors = Report.Errors;
                        unwind_protect = ec.CurrentBranching.AddGotoOrigin (ec.CurrentBranching.CurrentUsageVector, this);
                        ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return errors == Report.Errors;
+                       return true;
                }
                
                public Goto (string label, Location l)
@@ -923,11 +777,7 @@ namespace Mono.CSharp {
                        if (label == null)
                                throw new InternalErrorException ("goto emitted before target resolved");
                        Label l = label.LabelTarget (ec);
-                       ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
                }
        }
 
@@ -936,7 +786,6 @@ namespace Mono.CSharp {
                bool defined;
                bool referenced;
                Label label;
-               ILGenerator ig;
 
                FlowBranching.UsageVector vectors;
                
@@ -950,10 +799,9 @@ namespace Mono.CSharp {
                {
                        if (defined)
                                return label;
-                       ig = ec.ig;
-                       label = ec.ig.DefineLabel ();
-                       defined = true;
 
+                       label = ec.DefineLabel ();
+                       defined = true;
                        return label;
                }
 
@@ -985,7 +833,7 @@ namespace Mono.CSharp {
                        // nothing to clone
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        // this flow-branching will be terminated when the surrounding block ends
                        ec.StartFlowBranching (this);
@@ -994,14 +842,8 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       if (ig != null && ig != ec.ig)
-                               throw new InternalErrorException ("cannot happen");
                        LabelTarget (ec);
-                       ec.ig.MarkLabel (label);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.MarkLabel (label);
                }
 
                public void AddReference ()
@@ -1026,28 +868,26 @@ namespace Mono.CSharp {
                        // nothing to clone
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return true;
-               }
 
-               protected override void DoEmit (EmitContext ec)
-               {
-                       if (ec.Switch == null){
-                               Report.Error (153, loc, "A goto case is only valid inside a switch statement");
-                               return;
+                       if (ec.Switch == null) {
+                               ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+                               return false;
                        }
 
-                       if (!ec.Switch.GotDefault){
-                               FlowBranchingBlock.Error_UnknownLabel (loc, "default");
-                               return;
+                       if (!ec.Switch.GotDefault) {
+                               FlowBranchingBlock.Error_UnknownLabel (loc, "default", ec.Report);
+                               return false;
                        }
-                       ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
+
+                       return true;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               protected override void DoEmit (EmitContext ec)
                {
+                       ec.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
                }
        }
 
@@ -1064,10 +904,10 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        if (ec.Switch == null){
-                               Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+                               ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
                                return false;
                        }
 
@@ -1079,11 +919,11 @@ namespace Mono.CSharp {
 
                        Constant c = expr as Constant;
                        if (c == null) {
-                               Error (150, "A constant value is expected");
+                               ec.Report.Error (150, expr.Location, "A constant value is expected");
                                return false;
                        }
 
-                       Type type = ec.Switch.SwitchType;
+                       TypeSpec type = ec.Switch.SwitchType;
                        Constant res = c.TryReduce (ec, type, c.Location);
                        if (res == null) {
                                c.Error_ValueCannotBeConverted (ec, loc, type, true);
@@ -1091,7 +931,7 @@ namespace Mono.CSharp {
                        }
 
                        if (!Convert.ImplicitStandardConversionExists (c, type))
-                               Report.Warning (469, 2, loc,
+                               ec.Report.Warning (469, 2, loc,
                                        "The `goto case' value is not implicitly convertible to type `{0}'",
                                        TypeManager.CSharpName (type));
 
@@ -1099,11 +939,9 @@ namespace Mono.CSharp {
                        if (val == null)
                                val = SwitchLabel.NullStringCase;
                                        
-                       sl = (SwitchLabel) ec.Switch.Elements [val];
-
-                       if (sl == null){
+                       if (!ec.Switch.Elements.TryGetValue (val, out sl)) {
                                FlowBranchingBlock.Error_UnknownLabel (loc, "case " + 
-                                       (c.GetValue () == null ? "null" : val.ToString ()));
+                                       (c.GetValue () == null ? "null" : val.ToString ()), ec.Report);
                                return false;
                        }
 
@@ -1112,12 +950,7 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
+                       ec.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -1137,7 +970,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        if (expr == null) {
                                ec.CurrentBranching.CurrentUsageVector.Goto ();
@@ -1153,7 +986,7 @@ namespace Mono.CSharp {
                        if (Convert.ImplicitConversionExists (ec, expr, TypeManager.exception_type))
                                expr = Convert.ImplicitConversion (ec, expr, TypeManager.exception_type, loc);
                        else
-                               Report.Error (155, expr.Location, "The type caught or thrown must be derived from System.Exception");
+                               ec.Report.Error (155, expr.Location, "The type caught or thrown must be derived from System.Exception");
 
                        return true;
                }
@@ -1161,20 +994,14 @@ namespace Mono.CSharp {
                protected override void DoEmit (EmitContext ec)
                {
                        if (expr == null)
-                               ec.ig.Emit (OpCodes.Rethrow);
+                               ec.Emit (OpCodes.Rethrow);
                        else {
                                expr.Emit (ec);
 
-                               ec.ig.Emit (OpCodes.Throw);
+                               ec.Emit (OpCodes.Throw);
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (expr != null)
-                               expr.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Throw target = (Throw) t;
@@ -1193,23 +1020,18 @@ namespace Mono.CSharp {
 
                bool unwind_protect;
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       int errors = Report.Errors;
                        unwind_protect = ec.CurrentBranching.AddBreakOrigin (ec.CurrentBranching.CurrentUsageVector, loc);
                        ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return errors == Report.Errors;
+                       return true;
                }
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-               }
-               
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        // nothing needed
@@ -1225,21 +1047,16 @@ namespace Mono.CSharp {
 
                bool unwind_protect;
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       int errors = Report.Errors;
                        unwind_protect = ec.CurrentBranching.AddContinueOrigin (ec.CurrentBranching.CurrentUsageVector, loc);
                        ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return errors == Report.Errors;
+                       return true;
                }
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -1266,13 +1083,13 @@ namespace Mono.CSharp {
        public class LocalInfo : IKnownVariable, ILocalVariable {
                public readonly FullNamedExpression Type;
 
-               public Type VariableType;
+               public TypeSpec VariableType;
                public readonly string Name;
                public readonly Location Location;
                public readonly Block Block;
 
                public VariableInfo VariableInfo;
-               public HoistedVariable HoistedVariableReference;
+               HoistedVariable hoisted_variant;
 
                [Flags]
                enum Flags : byte {
@@ -1303,43 +1120,36 @@ namespace Mono.CSharp {
                        Location = l;
                }
 
-               public LocalInfo (DeclSpace ds, Block block, Location l)
+               public LocalInfo (TypeContainer ds, Block block, Location l)
                {
-                       VariableType = ds.IsGeneric ? ds.CurrentType : ds.TypeBuilder;
+                       VariableType = ds.IsGeneric ? ds.CurrentType : ds.Definition;
                        Block = block;
                        Location = l;
                }
 
                public void ResolveVariable (EmitContext ec)
                {
-                       if (HoistedVariableReference != null)
+                       if (HoistedVariant != null)
                                return;
 
                        if (builder == null) {
-                               if (Pinned)
-                                       //
-                                       // This is needed to compile on both .NET 1.x and .NET 2.x
-                                       // the later introduced `DeclareLocal (Type t, bool pinned)'
-                                       //
-                                       builder = TypeManager.DeclareLocalPinned (ec.ig, VariableType);
-                               else
-                                       builder = ec.ig.DeclareLocal (TypeManager.TypeToReflectionType (VariableType));
+                               builder = ec.DeclareLocal (VariableType, Pinned);
                        }
                }
 
                public void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldloc, builder);
+                       ec.Emit (OpCodes.Ldloc, builder);
                }
 
                public void EmitAssign (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Stloc, builder);
+                       ec.Emit (OpCodes.Stloc, builder);
                }
 
                public void EmitAddressOf (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldloca, builder);
+                       ec.Emit (OpCodes.Ldloca, builder);
                }
 
                public void EmitSymbolInfo (EmitContext ec)
@@ -1348,7 +1158,19 @@ namespace Mono.CSharp {
                                ec.DefineLocalVariable (Name, builder);
                }
 
-               public bool IsThisAssigned (EmitContext ec)
+               //
+               // Hoisted local variable variant
+               //
+               public HoistedVariable HoistedVariant {
+                       get {
+                               return hoisted_variant;
+                       }
+                       set {
+                               hoisted_variant = value;
+                       }
+               }
+
+               public bool IsThisAssigned (BlockContext ec, Block block)
                {
                        if (VariableInfo == null)
                                throw new Exception ();
@@ -1356,10 +1178,10 @@ namespace Mono.CSharp {
                        if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))
                                return true;
 
-                       return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, ec.loc);
+                       return VariableInfo.TypeInfo.IsFullyInitialized (ec, VariableInfo, block.StartLocation);
                }
 
-               public bool IsAssigned (EmitContext ec)
+               public bool IsAssigned (BlockContext ec)
                {
                        if (VariableInfo == null)
                                throw new Exception ();
@@ -1367,7 +1189,7 @@ namespace Mono.CSharp {
                        return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);
                }
 
-               public bool Resolve (EmitContext ec)
+               public bool Resolve (ResolveContext ec)
                {
                        if (VariableType != null)
                                return true;
@@ -1378,16 +1200,13 @@ namespace Mono.CSharp {
                                
                        VariableType = texpr.Type;
 
-                       if (TypeManager.IsGenericParameter (VariableType))
-                               return true;
-
-                       if (VariableType.IsAbstract && VariableType.IsSealed) {
-                               FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType);
+                       if (VariableType.IsStatic) {
+                               FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType, ec.Report);
                                return false;
                        }
 
-                       if (VariableType.IsPointer && !ec.InUnsafe)
-                               Expression.UnsafeError (Location);
+                       if (VariableType.IsPointer && !ec.IsUnsafe)
+                               Expression.UnsafeError (ec, Location);
 
                        return true;
                }
@@ -1506,7 +1325,8 @@ namespace Mono.CSharp {
                public ToplevelBlock Toplevel; // TODO: Use Explicit
 
                [Flags]
-               public enum Flags : byte {
+               public enum Flags
+               {
                        Unchecked = 1,
                        BlockUsed = 2,
                        VariablesInitialized = 4,
@@ -1514,8 +1334,10 @@ namespace Mono.CSharp {
                        Unsafe = 16,
                        IsIterator = 32,
                        HasCapturedVariable = 64,
-                       HasCapturedThis = 128
+                       HasCapturedThis = 1 << 7,
+                       IsExpressionTree = 1 << 8
                }
+
                protected Flags flags;
 
                public bool Unchecked {
@@ -1531,7 +1353,7 @@ namespace Mono.CSharp {
                //
                // The statements in this block
                //
-               protected ArrayList statements;
+               protected List<Statement> statements;
 
                //
                // An array of Blocks.  We keep track of children just
@@ -1540,35 +1362,37 @@ namespace Mono.CSharp {
                // Statements and child statements are handled through the
                // statements.
                //
-               ArrayList children;
+               List<Block> children;
 
                //
                // Labels.  (label, block) pairs.
                //
-               protected HybridDictionary labels;
+               protected Dictionary<string, LabeledStatement> labels;
 
                //
                // Keeps track of (name, type) pairs
                //
-               IDictionary variables;
+               Dictionary<string, LocalInfo> variables;
 
                //
                // Keeps track of constants
-               HybridDictionary constants;
+               Dictionary<string, Expression> constants;
 
                //
                // Temporary variables.
                //
-               ArrayList temporary_variables;
+               List<LocalInfo> temporary_variables;
                
                //
                // If this is a switch section, the enclosing switch block.
                //
                Block switch_block;
 
-               protected ArrayList scope_initializers;
+               protected List<Statement> scope_initializers;
 
-               ArrayList anonymous_children;
+               List<ToplevelBlock> anonymous_children;
+
+               int? resolving_init_idx;
 
                protected static int id;
 
@@ -1620,7 +1444,7 @@ namespace Mono.CSharp {
                        this.EndLocation = end;
                        this.loc = start;
                        this_id = id++;
-                       statements = new ArrayList (4);
+                       statements = new List<Statement> (4);
                }
 
                public Block CreateSwitchBlock (Location start)
@@ -1635,10 +1459,10 @@ namespace Mono.CSharp {
                        get { return this_id; }
                }
 
-               public IDictionary Variables {
+               public IDictionary<string, LocalInfo> Variables {
                        get {
                                if (variables == null)
-                                       variables = new ListDictionary ();
+                                       variables = new Dictionary<string, LocalInfo> ();
                                return variables;
                        }
                }
@@ -1646,7 +1470,7 @@ namespace Mono.CSharp {
                void AddChild (Block b)
                {
                        if (children == null)
-                               children = new ArrayList (1);
+                               children = new List<Block> (1);
                        
                        children.Add (b);
                }
@@ -1656,9 +1480,9 @@ namespace Mono.CSharp {
                        EndLocation = loc;
                }
 
-               protected static void Error_158 (string name, Location loc)
+               protected void Error_158 (string name, Location loc)
                {
-                       Report.Error (158, loc, "The label `{0}' shadows another label " +
+                       Toplevel.Report.Error (158, loc, "The label `{0}' shadows another label " +
                                      "by the same name in a contained scope", name);
                }
 
@@ -1682,8 +1506,8 @@ namespace Mono.CSharp {
                        while (cur != null) {
                                LabeledStatement s = cur.DoLookupLabel (name);
                                if (s != null) {
-                                       Report.SymbolRelatedToPreviousError (s.loc, s.Name);
-                                       Report.Error (140, target.loc, "The label `{0}' is a duplicate", name);
+                                       Toplevel.Report.SymbolRelatedToPreviousError (s.loc, s.Name);
+                                       Toplevel.Report.Error (140, target.loc, "The label `{0}' is a duplicate", name);
                                        return false;
                                }
 
@@ -1705,7 +1529,7 @@ namespace Mono.CSharp {
                                                if (s == null)
                                                        continue;
 
-                                               Report.SymbolRelatedToPreviousError (s.loc, s.Name);
+                                               Toplevel.Report.SymbolRelatedToPreviousError (s.loc, s.Name);
                                                Error_158 (name, target.loc);
                                                return false;
                                        }
@@ -1717,7 +1541,7 @@ namespace Mono.CSharp {
                        Toplevel.CheckError158 (name, target.loc);
 
                        if (labels == null)
-                               labels = new HybridDictionary();
+                               labels = new Dictionary<string, LabeledStatement> ();
 
                        labels.Add (name, target);
                        return true;
@@ -1750,8 +1574,8 @@ namespace Mono.CSharp {
                                return switch_block.LookupLabel (name);
 
                        if (labels != null)
-                               if (labels.Contains (name))
-                                       return ((LabeledStatement) labels [name]);
+                               if (labels.ContainsKey (name))
+                                       return labels [name];
 
                        return null;
                }
@@ -1777,8 +1601,8 @@ namespace Mono.CSharp {
                                // block, we violate the invariant meaning in a block.
                                //
                                if (b == this) {
-                                       Report.SymbolRelatedToPreviousError (kvi.Location, name);
-                                       Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", name);
+                                       Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
+                                       Toplevel.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", name);
                                        return false;
                                }
 
@@ -1802,8 +1626,8 @@ namespace Mono.CSharp {
                                return true;
 
                        if (this is ToplevelBlock) {
-                               Report.SymbolRelatedToPreviousError (kvi.Location, name);
-                               e.Error_VariableIsUsedBeforeItIsDeclared (name);
+                               Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
+                               e.Error_VariableIsUsedBeforeItIsDeclared (Toplevel.Report, name);
                                return false;
                        }
 
@@ -1811,16 +1635,16 @@ namespace Mono.CSharp {
                        // Even though we detected the error when the name is used, we
                        // treat it as if the variable declaration was in error.
                        //
-                       Report.SymbolRelatedToPreviousError (loc, name);
+                       Toplevel.Report.SymbolRelatedToPreviousError (loc, name);
                        Error_AlreadyDeclared (kvi.Location, name, "parent or current");
                        return false;
                }
 
-               protected virtual bool CheckParentConflictName (ToplevelBlock block, string name, Location l)
+               protected bool CheckParentConflictName (ToplevelBlock block, string name, Location l)
                {
                        LocalInfo vi = GetLocalInfo (name);
                        if (vi != null) {
-                               Report.SymbolRelatedToPreviousError (vi.Location, name);
+                               block.Report.SymbolRelatedToPreviousError (vi.Location, name);
                                if (Explicit == vi.Block.Explicit) {
                                        Error_AlreadyDeclared (l, name, null);
                                } else {
@@ -1831,13 +1655,13 @@ namespace Mono.CSharp {
                        }
 
                        if (block != null) {
-                               Expression e = block.GetParameterReference (name, Location.Null);
-                               if (e != null) {
-                                       ParameterReference pr = e as ParameterReference;
-                                       if (this is Linq.QueryBlock && (pr != null && pr.Parameter is Linq.QueryBlock.ImplicitQueryParameter || e is MemberAccess))
+                               var tblock = block.CheckParameterNameConflict (name);
+                               if (tblock != null) {
+                                       if (block == tblock && block is Linq.QueryBlock)
                                                Error_AlreadyDeclared (loc, name);
                                        else
                                                Error_AlreadyDeclared (loc, name, "parent or current");
+
                                        return false;
                                }
                        }
@@ -1850,19 +1674,9 @@ namespace Mono.CSharp {
                        if (!CheckParentConflictName (Toplevel, name, l))
                                return null;
 
-                       if (Toplevel.GenericMethod != null) {
-                               foreach (TypeParameter tp in Toplevel.GenericMethod.CurrentTypeParameters) {
-                                       if (tp.Name == name) {
-                                               Report.SymbolRelatedToPreviousError (tp);
-                                               Error_AlreadyDeclaredTypeParameter (loc, name, "local variable");
-                                               return null;
-                                       }
-                               }
-                       }                       
-
                        IKnownVariable kvi = Explicit.GetKnownVariable (name);
                        if (kvi != null) {
-                               Report.SymbolRelatedToPreviousError (kvi.Location, name);
+                               Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
                                Error_AlreadyDeclared (l, name, "child");
                                return null;
                        }
@@ -1889,7 +1703,7 @@ namespace Mono.CSharp {
                                return;
                        }
                        
-                       Report.Error (136, loc, "A local variable named `{0}' cannot be declared " +
+                       Toplevel.Report.Error (136, loc, "A local variable named `{0}' cannot be declared " +
                                      "in this scope because it would give a different meaning " +
                                      "to `{0}', which is already used in a `{1}' scope " +
                                      "to denote something else", var, reason);
@@ -1897,13 +1711,13 @@ namespace Mono.CSharp {
 
                protected virtual void Error_AlreadyDeclared (Location loc, string name)
                {
-                       Report.Error (128, loc,
+                       Toplevel.Report.Error (128, loc,
                                "A local variable named `{0}' is already defined in this scope", name);
                }
                                        
                public virtual void Error_AlreadyDeclaredTypeParameter (Location loc, string name, string conflict)
                {
-                       Report.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
+                       Toplevel.Report.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
                                name, conflict);
                }
 
@@ -1913,7 +1727,7 @@ namespace Mono.CSharp {
                                return false;
                        
                        if (constants == null)
-                               constants = new HybridDictionary();
+                               constants = new Dictionary<string, Expression> ();
 
                        constants.Add (name, value);
 
@@ -1929,7 +1743,7 @@ namespace Mono.CSharp {
                        Report.Debug (64, "ADD TEMPORARY", this, Toplevel, loc);
 
                        if (temporary_variables == null)
-                               temporary_variables = new ArrayList ();
+                               temporary_variables = new List<LocalInfo> ();
 
                        int id = ++next_temp_id;
                        string name = "$s_" + id.ToString ();
@@ -1944,10 +1758,8 @@ namespace Mono.CSharp {
                {
                        LocalInfo ret;
                        for (Block b = this; b != null; b = b.Parent) {
-                               if (b.variables != null) {
-                                       ret = (LocalInfo) b.variables [name];
-                                       if (ret != null)
-                                               return ret;
+                               if (b.variables != null && b.variables.TryGetValue (name, out ret)) {
+                                       return ret;
                                }
                        }
 
@@ -1962,10 +1774,10 @@ namespace Mono.CSharp {
 
                public Expression GetConstantExpression (string name)
                {
+                       Expression ret;
                        for (Block b = this; b != null; b = b.Parent) {
                                if (b.constants != null) {
-                                       Expression ret = b.constants [name] as Expression;
-                                       if (ret != null)
+                                       if (b.constants.TryGetValue (name, out ret))
                                                return ret;
                                }
                        }
@@ -1979,9 +1791,20 @@ namespace Mono.CSharp {
                public void AddScopeStatement (Statement s)
                {
                        if (scope_initializers == null)
-                               scope_initializers = new ArrayList ();
+                               scope_initializers = new List<Statement> ();
 
-                       scope_initializers.Add (s);
+                       //
+                       // Simple recursive helper, when resolve scope initializer another
+                       // new scope initializer can be added, this ensures it's initialized
+                       // before existing one. For now this can happen with expression trees
+                       // in base ctor initializer only
+                       //
+                       if (resolving_init_idx.HasValue) {
+                               scope_initializers.Insert (resolving_init_idx.Value, s);
+                               ++resolving_init_idx;
+                       } else {
+                               scope_initializers.Add (s);
+                       }
                }
                
                public void AddStatement (Statement s)
@@ -2012,19 +1835,19 @@ namespace Mono.CSharp {
                        }
                }
 
-               public ArrayList AnonymousChildren {
+               public IList<ToplevelBlock> AnonymousChildren {
                        get { return anonymous_children; }
                }
 
                public void AddAnonymousChild (ToplevelBlock b)
                {
                        if (anonymous_children == null)
-                               anonymous_children = new ArrayList ();
+                               anonymous_children = new List<ToplevelBlock> ();
 
                        anonymous_children.Add (b);
                }
 
-               void DoResolveConstants (EmitContext ec)
+               void DoResolveConstants (BlockContext ec)
                {
                        if (constants == null)
                                return;
@@ -2032,20 +1855,20 @@ namespace Mono.CSharp {
                        if (variables == null)
                                throw new InternalErrorException ("cannot happen");
 
-                       foreach (DictionaryEntry de in variables) {
-                               string name = (string) de.Key;
-                               LocalInfo vi = (LocalInfo) de.Value;
-                               Type variable_type = vi.VariableType;
+                       foreach (var de in variables) {
+                               string name = de.Key;
+                               LocalInfo vi = de.Value;
+                               TypeSpec variable_type = vi.VariableType;
 
                                if (variable_type == null) {
                                        if (vi.Type is VarExpr)
-                                               Report.Error (822, vi.Type.Location, "An implicitly typed local variable cannot be a constant");
+                                               ec.Report.Error (822, vi.Type.Location, "An implicitly typed local variable cannot be a constant");
 
                                        continue;
                                }
 
-                               Expression cv = (Expression) constants [name];
-                               if (cv == null)
+                               Expression cv;
+                               if (!constants.TryGetValue (name, out cv))
                                        continue;
 
                                // Don't let 'const int Foo = Foo;' succeed.
@@ -2053,14 +1876,14 @@ namespace Mono.CSharp {
                                // which in turn causes the 'must be constant' error to be triggered.
                                constants.Remove (name);
 
-                               if (!Const.IsConstantTypeValid (variable_type)) {
-                                       Const.Error_InvalidConstantType (variable_type, loc);
+                               if (!variable_type.IsConstantCompatible) {
+                                       Const.Error_InvalidConstantType (variable_type, loc, ec.Report);
                                        continue;
                                }
 
                                ec.CurrentBlock = this;
                                Expression e;
-                               using (ec.With (EmitContext.Flags.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
+                               using (ec.With (ResolveContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
                                        e = cv.Resolve (ec);
                                }
                                if (e == null)
@@ -2068,14 +1891,14 @@ namespace Mono.CSharp {
 
                                Constant ce = e as Constant;
                                if (ce == null) {
-                                       Const.Error_ExpressionMustBeConstant (vi.Location, name);
+                                       e.Error_ExpressionMustBeConstant (ec, vi.Location, name);
                                        continue;
                                }
 
-                               e = ce.ConvertImplicitly (variable_type);
+                               e = ce.ConvertImplicitly (ec, variable_type);
                                if (e == null) {
                                        if (TypeManager.IsReferenceType (variable_type))
-                                               Const.Error_ConstantCanBeInitializedWithNullOnly (variable_type, vi.Location, vi.Name);
+                                               ce.Error_ConstantCanBeInitializedWithNullOnly (ec, variable_type, vi.Location, vi.Name);
                                        else
                                                ce.Error_ValueCannotBeConverted (ec, vi.Location, variable_type, false);
                                        continue;
@@ -2086,13 +1909,13 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected void ResolveMeta (EmitContext ec, int offset)
+               protected void ResolveMeta (BlockContext ec, int offset)
                {
                        Report.Debug (64, "BLOCK RESOLVE META", this, Parent);
 
                        // If some parent block was unsafe, we remain unsafe even if this block
                        // isn't explicitly marked as such.
-                       using (ec.With (EmitContext.Flags.InUnsafe, ec.InUnsafe | Unsafe)) {
+                       using (ec.With (ResolveContext.Options.UnsafeScope, ec.IsUnsafe | Unsafe)) {
                                flags |= Flags.VariablesInitialized;
 
                                if (variables != null) {
@@ -2135,27 +1958,27 @@ namespace Mono.CSharp {
                        }
                }
 
-               void UsageWarning ()
+               void UsageWarning (BlockContext ec)
                {
-                       if (variables == null || Report.WarningLevel < 3)
+                       if (variables == null || ec.Report.WarningLevel < 3)
                                return;
 
-                       foreach (DictionaryEntry de in variables) {
-                               LocalInfo vi = (LocalInfo) de.Value;
+                       foreach (var de in variables) {
+                               LocalInfo vi = de.Value;
 
                                if (!vi.Used) {
-                                       string name = (string) de.Key;
+                                       string name = de.Key;
 
                                        // vi.VariableInfo can be null for 'catch' variables
                                        if (vi.VariableInfo != null && vi.VariableInfo.IsEverAssigned)
-                                               Report.Warning (219, 3, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
+                                               ec.Report.Warning (219, 3, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
                                        else
-                                               Report.Warning (168, 3, vi.Location, "The variable `{0}' is declared but never used", name);
+                                               ec.Report.Warning (168, 3, vi.Location, "The variable `{0}' is declared but never used", name);
                                }
                        }
                }
 
-               static void CheckPossibleMistakenEmptyStatement (Statement s)
+               static void CheckPossibleMistakenEmptyStatement (BlockContext ec, Statement s)
                {
                        Statement body;
 
@@ -2184,21 +2007,32 @@ namespace Mono.CSharp {
                                return;
 
                        if (body == null || body is EmptyStatement)
-                               Report.Warning (642, 3, s.loc, "Possible mistaken empty statement");
+                               ec.Report.Warning (642, 3, s.loc, "Possible mistaken empty statement");
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        Block prev_block = ec.CurrentBlock;
                        bool ok = true;
 
-                       int errors = Report.Errors;
+                       int errors = ec.Report.Errors;
 
                        ec.CurrentBlock = this;
                        ec.StartFlowBranching (this);
 
                        Report.Debug (4, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
 
+                       //
+                       // Compiler generated scope statements
+                       //
+                       if (scope_initializers != null) {
+                               for (resolving_init_idx = 0; resolving_init_idx < scope_initializers.Count; ++resolving_init_idx) {
+                                       scope_initializers[resolving_init_idx.Value].Resolve (ec);
+                               }
+
+                               resolving_init_idx = null;
+                       }
+
                        //
                        // This flag is used to notate nested statements as unreachable from the beginning of this block.
                        // For the purposes of this resolution, it doesn't matter that the whole block is unreachable 
@@ -2207,12 +2041,11 @@ namespace Mono.CSharp {
                        //
                        int statement_count = statements.Count;
                        for (int ix = 0; ix < statement_count; ix++){
-                               Statement s = (Statement) statements [ix];
+                               Statement s = statements [ix];
                                // Check possible empty statement (CS0642)
-                               if (Report.WarningLevel >= 3 &&
-                                       ix + 1 < statement_count &&
-                                               statements [ix + 1] is ExplicitBlock)
-                                       CheckPossibleMistakenEmptyStatement (s);
+                               if (ix + 1 < statement_count && ec.Report.WarningLevel >= 3 &&
+                                       statements [ix + 1] is ExplicitBlock)
+                                       CheckPossibleMistakenEmptyStatement (ec, s);
 
                                //
                                // Warn if we detect unreachable code.
@@ -2222,7 +2055,7 @@ namespace Mono.CSharp {
                                                continue;
 
                                        if (!unreachable_shown && !(s is LabeledStatement)) {
-                                               Report.Warning (162, 2, s.loc, "Unreachable code detected");
+                                               ec.Report.Warning (162, 2, s.loc, "Unreachable code detected");
                                                unreachable_shown = true;
                                        }
 
@@ -2244,12 +2077,12 @@ namespace Mono.CSharp {
                                        if (ec.IsInProbingMode)
                                                break;
 
-                                       statements [ix] = EmptyStatement.Value;
+                                       statements [ix] = new EmptyStatement (s.loc);
                                        continue;
                                }
 
                                if (unreachable && !(s is LabeledStatement) && !(s is Block))
-                                       statements [ix] = EmptyStatement.Value;
+                                       statements [ix] = new EmptyStatement (s.loc);
 
                                unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
                                if (unreachable && s is LabeledStatement)
@@ -2274,25 +2107,25 @@ namespace Mono.CSharp {
                        if (this == Toplevel && !Toplevel.IsThisAssigned (ec) && !flow_unreachable)
                                ok = false;
 
-                       if ((labels != null) && (Report.WarningLevel >= 2)) {
+                       if ((labels != null) && (ec.Report.WarningLevel >= 2)) {
                                foreach (LabeledStatement label in labels.Values)
                                        if (!label.HasBeenReferenced)
-                                               Report.Warning (164, 2, label.loc, "This label has not been referenced");
+                                               ec.Report.Warning (164, 2, label.loc, "This label has not been referenced");
                        }
 
-                       if (ok && errors == Report.Errors)
-                               UsageWarning ();
+                       if (ok && errors == ec.Report.Errors)
+                               UsageWarning (ec);
 
                        return ok;
                }
 
-               public override bool ResolveUnreachable (EmitContext ec, bool warn)
+               public override bool ResolveUnreachable (BlockContext ec, bool warn)
                {
                        unreachable_shown = true;
                        unreachable = true;
 
                        if (warn)
-                               Report.Warning (162, 2, loc, "Unreachable code detected");
+                               ec.Report.Warning (162, 2, loc, "Unreachable code detected");
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
                        bool ok = Resolve (ec);
@@ -2311,9 +2144,6 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       Block prev_block = ec.CurrentBlock;
-                       ec.CurrentBlock = this;
-
                        if (scope_initializers != null)
                                EmitScopeInitializers (ec);
 
@@ -2322,20 +2152,18 @@ namespace Mono.CSharp {
 
                        if (SymbolWriter.HasSymbolWriter)
                                EmitSymbolInfo (ec);
-
-                       ec.CurrentBlock = prev_block;
                }
 
                protected void EmitScopeInitializers (EmitContext ec)
                {
-                       SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.OpenCompilerGeneratedBlock (ec);
 
-                       using (ec.Set (EmitContext.Flags.OmitDebuggingInfo)) {
+                       using (ec.With (EmitContext.Options.OmitDebugInfo, true)) {
                                foreach (Statement s in scope_initializers)
                                        s.Emit (ec);
                        }
 
-                       SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.CloseCompilerGeneratedBlock (ec);
                }
 
                protected virtual void EmitSymbolInfo (EmitContext ec)
@@ -2347,36 +2175,9 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       MutateVariables (storey);
-
-                       if (scope_initializers != null) {
-                               foreach (Statement s in scope_initializers)
-                                       s.MutateHoistedGenericType (storey);
-                       }
-
-                       foreach (Statement s in statements)
-                               s.MutateHoistedGenericType (storey);
-               }
-
-               void MutateVariables (AnonymousMethodStorey storey)
-               {
-                       if (variables != null) {
-                               foreach (LocalInfo vi in variables.Values) {
-                                       vi.VariableType = storey.MutateType (vi.VariableType);
-                               }
-                       }
-
-                       if (temporary_variables != null) {
-                               foreach (LocalInfo vi in temporary_variables)
-                                       vi.VariableType = storey.MutateType (vi.VariableType);
-                       }
-               }
-
                public override string ToString ()
                {
-                       return String.Format ("{0} ({1}:{2})", GetType (),ID, StartLocation);
+                       return String.Format ("{0} ({1}:{2})", GetType (), this_id, StartLocation);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -2385,27 +2186,27 @@ namespace Mono.CSharp {
 
                        clonectx.AddBlockMap (this, target);
 
-                       //target.Toplevel = (ToplevelBlock) clonectx.LookupBlock (Toplevel);
+                       target.Toplevel = (ToplevelBlock) clonectx.LookupBlock (Toplevel);
                        target.Explicit = (ExplicitBlock) clonectx.LookupBlock (Explicit);
                        if (Parent != null)
                                target.Parent = clonectx.RemapBlockCopy (Parent);
 
                        if (variables != null){
-                               target.variables = new Hashtable ();
+                               target.variables = new Dictionary<string, LocalInfo> ();
 
-                               foreach (DictionaryEntry de in variables){
-                                       LocalInfo newlocal = ((LocalInfo) de.Value).Clone (clonectx);
+                               foreach (var de in variables){
+                                       LocalInfo newlocal = de.Value.Clone (clonectx);
                                        target.variables [de.Key] = newlocal;
-                                       clonectx.AddVariableMap ((LocalInfo) de.Value, newlocal);
+                                       clonectx.AddVariableMap (de.Value, newlocal);
                                }
                        }
 
-                       target.statements = new ArrayList (statements.Count);
+                       target.statements = new List<Statement> (statements.Count);
                        foreach (Statement s in statements)
                                target.statements.Add (s.Clone (clonectx));
 
                        if (target.children != null){
-                               target.children = new ArrayList (children.Count);
+                               target.children = new List<Block> (children.Count);
                                foreach (Block b in children){
                                        target.children.Add (clonectx.LookupBlock (b));
                                }
@@ -2417,8 +2218,9 @@ namespace Mono.CSharp {
                }
        }
 
-       public class ExplicitBlock : Block {
-               HybridDictionary known_variables;
+       public class ExplicitBlock : Block
+       {
+               Dictionary<string, IKnownVariable> known_variables;
                protected AnonymousMethodStorey am_storey;
 
                public ExplicitBlock (Block parent, Location start, Location end)
@@ -2440,7 +2242,7 @@ namespace Mono.CSharp {
                internal void AddKnownVariable (string name, IKnownVariable info)
                {
                        if (known_variables == null)
-                               known_variables = new HybridDictionary();
+                               known_variables = new Dictionary<string, IKnownVariable> ();
 
                        known_variables [name] = info;
 
@@ -2455,7 +2257,7 @@ namespace Mono.CSharp {
                //
                // Creates anonymous method storey in current block
                //
-               public AnonymousMethodStorey CreateAnonymousMethodStorey (EmitContext ec)
+               public AnonymousMethodStorey CreateAnonymousMethodStorey (ResolveContext ec)
                {
                        //
                        // When referencing a variable in iterator storey from children anonymous method
@@ -2471,13 +2273,13 @@ namespace Mono.CSharp {
                            return ec.CurrentIterator.Storey;
 
                        if (am_storey == null) {
-                               MemberBase mc = ec.ResolveContext as MemberBase;
+                               MemberBase mc = ec.MemberContext as MemberBase;
                                GenericMethod gm = mc == null ? null : mc.GenericMethod;
 
                                //
                                // Creates anonymous method storey for this block
                                //
-                               am_storey = new AnonymousMethodStorey (this, ec.TypeContainer, mc, gm, "AnonStorey");
+                               am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, gm, "AnonStorey");
                        }
 
                        return am_storey;
@@ -2517,23 +2319,30 @@ namespace Mono.CSharp {
                                                while (parent.am_storey == null || parent.am_storey.Parent is AnonymousMethodStorey)
                                                        parent = parent.Parent.Explicit;
 
-                                               am_storey.AddParentStoreyReference (parent.am_storey);
+                                               am_storey.AddParentStoreyReference (ec, parent.am_storey);
                                        }
 
-                                       am_storey.ChangeParentStorey (ec.CurrentAnonymousMethod.Storey);
+                                       am_storey.SetNestedStoryParent (ec.CurrentAnonymousMethod.Storey);
+
+                                       // TODO MemberCache: Review
+                                       am_storey.Mutator = ec.CurrentAnonymousMethod.Storey.Mutator;
                                }
 
+                               am_storey.CreateType ();
+                               if (am_storey.Mutator == null && ec.CurrentTypeParameters != null)
+                                       am_storey.Mutator = new TypeParameterMutator (ec.CurrentTypeParameters, am_storey.CurrentTypeParameters);
+
                                am_storey.DefineType ();
-                               am_storey.ResolveType ();
+                               am_storey.ResolveTypeParameters ();
                                am_storey.Define ();
                                am_storey.Parent.PartialContainer.AddCompilerGeneratedClass (am_storey);
 
-                               ArrayList ref_blocks = am_storey.ReferencesFromChildrenBlock;
+                               var ref_blocks = am_storey.ReferencesFromChildrenBlock;
                                if (ref_blocks != null) {
                                        foreach (ExplicitBlock ref_block in ref_blocks) {
                                                for (ExplicitBlock b = ref_block.Explicit; b != this; b = b.Parent.Explicit) {
                                                        if (b.am_storey != null) {
-                                                               b.am_storey.AddParentStoreyReference (am_storey);
+                                                               b.am_storey.AddParentStoreyReference (ec, am_storey);
 
                                                                // Stop propagation inside same top block
                                                                if (b.Toplevel == Toplevel)
@@ -2550,9 +2359,14 @@ namespace Mono.CSharp {
                        base.EmitMeta (ec);
                }
 
-               internal IKnownVariable GetKnownVariable (string name)
+               public IKnownVariable GetKnownVariable (string name)
                {
-                       return known_variables == null ? null : (IKnownVariable) known_variables [name];
+                       if (known_variables == null)
+                               return null;
+
+                       IKnownVariable kw;
+                       known_variables.TryGetValue (name, out kw);
+                       return kw;
                }
 
                public bool HasCapturedThis
@@ -2587,7 +2401,7 @@ namespace Mono.CSharp {
                        get { return Block.Parameters [Index]; }
                }
 
-               public Type ParameterType {
+               public TypeSpec ParameterType {
                        get { return Block.Parameters.Types [Index]; }
                }
 
@@ -2626,17 +2440,16 @@ namespace Mono.CSharp {
                                this.block = block;
                        }
 
-                       public override Expression CreateExpressionTree (EmitContext ec)
+                       public override Expression CreateExpressionTree (ResolveContext ec)
                        {
                                throw new NotSupportedException ();
                        }
 
-                       public override Expression DoResolve (EmitContext ec)
+                       protected override Expression DoResolve (ResolveContext ec)
                        {
                                if (child == null)
                                        return null;
                                
-                               block.ResolveMeta (ec, ParametersCompiled.EmptyReadOnlyParameters);
                                child = child.Resolve (ec);
                                if (child == null)
                                        return null;
@@ -2652,23 +2465,23 @@ namespace Mono.CSharp {
                                block.EmitScopeInitializers (ec);
                                child.Emit (ec);
                        }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               type = storey.MutateType (type);
-                               child.MutateHoistedGenericType (storey);
-                               block.MutateHoistedGenericType (storey);
-                       }
                }
 
-               GenericMethod generic;
-               FlowBranchingToplevel top_level_branching;
                protected ParametersCompiled parameters;
-               ToplevelParameterInfo[] parameter_info;
+               protected ToplevelParameterInfo[] parameter_info;
                LocalInfo this_variable;
+               bool resolved;
+               bool unreachable;
+               CompilerContext compiler;
 
                public HoistedVariable HoistedThisVariable;
 
+               public bool Resolved {
+                       get {
+                               return resolved;
+                       }
+               }
+
                //
                // The parameters for the block.
                //
@@ -2676,40 +2489,35 @@ namespace Mono.CSharp {
                        get { return parameters; }
                }
 
-               public GenericMethod GenericMethod {
-                       get { return generic; }
+               public Report Report {
+                       get { return compiler.Report; }
                }
 
                public ToplevelBlock Container {
                        get { return Parent == null ? null : Parent.Toplevel; }
                }
 
-               public ToplevelBlock (Block parent, ParametersCompiled parameters, Location start) :
-                       this (parent, (Flags) 0, parameters, start)
+               public ToplevelBlock (CompilerContext ctx, Block parent, ParametersCompiled parameters, Location start) :
+                       this (ctx, parent, (Flags) 0, parameters, start)
                {
                }
 
-               public ToplevelBlock (Block parent, ParametersCompiled parameters, GenericMethod generic, Location start) :
-                       this (parent, parameters, start)
-               {
-                       this.generic = generic;
-               }
-               
-               public ToplevelBlock (ParametersCompiled parameters, Location start) :
-                       this (null, (Flags) 0, parameters, start)
+               public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start) :
+                       this (ctx, null, (Flags) 0, parameters, start)
                {
                }
 
-               ToplevelBlock (Flags flags, ParametersCompiled parameters, Location start) :
-                       this (null, flags, parameters, start)
+               ToplevelBlock (CompilerContext ctx, Flags flags, ParametersCompiled parameters, Location start) :
+                       this (ctx, null, flags, parameters, start)
                {
                }
 
                // We use 'Parent' to hook up to the containing block, but don't want to register the current block as a child.
                // So, we use a two-stage setup -- first pass a null parent to the base constructor, and then override 'Parent'.
-               public ToplevelBlock (Block parent, Flags flags, ParametersCompiled parameters, Location start) :
+               public ToplevelBlock (CompilerContext ctx, Block parent, Flags flags, ParametersCompiled parameters, Location start) :
                        base (null, flags, start, Location.Null)
                {
+                       this.compiler = ctx;
                        this.Toplevel = this;
 
                        this.parameters = parameters;
@@ -2721,8 +2529,8 @@ namespace Mono.CSharp {
                                ProcessParameters ();
                }
 
-               public ToplevelBlock (Location loc)
-                       : this (null, (Flags) 0, ParametersCompiled.EmptyReadOnlyParameters, loc)
+               public ToplevelBlock (CompilerContext ctx, Location loc)
+                       : this (ctx, null, (Flags) 0, ParametersCompiled.EmptyReadOnlyParameters, loc)
                {
                }
 
@@ -2731,10 +2539,11 @@ namespace Mono.CSharp {
                        ToplevelBlock target = (ToplevelBlock) t;
                        base.CloneTo (clonectx, t);
 
-                       if (parameters.Count != 0)
-                               target.parameter_info = new ToplevelParameterInfo [parameters.Count];
-                       for (int i = 0; i < parameters.Count; ++i)
-                               target.parameter_info [i] = new ToplevelParameterInfo (target, i);
+                       if (parameters.Count != 0) {
+                               target.parameter_info = new ToplevelParameterInfo[parameters.Count];
+                               for (int i = 0; i < parameters.Count; ++i)
+                                       target.parameter_info[i] = new ToplevelParameterInfo (target, i);
+                       }
                }
 
                public bool CheckError158 (string name, Location loc)
@@ -2788,7 +2597,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public override Expression CreateExpressionTree (EmitContext ec)
+               public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        if (statements.Count == 1) {
                                Expression expr = ((Statement) statements[0]).CreateExpressionTree (ec);
@@ -2811,7 +2620,7 @@ namespace Mono.CSharp {
                        // Creates block with original statements
                        AddStatement (new IteratorStatement (iterator, new Block (this, source)));
 
-                       source.statements = new ArrayList (1);
+                       source.statements = new List<Statement> (1);
                        source.AddStatement (new Return (iterator, iterator.Location));
                        source.IsIterator = false;
 
@@ -2820,10 +2629,6 @@ namespace Mono.CSharp {
                        return iterator_storey;
                }
 
-               public FlowBranchingToplevel TopLevelBranching {
-                       get { return top_level_branching; }
-               }
-
                //
                // Returns a parameter reference expression for the given name,
                // or null if there is no such parameter
@@ -2831,6 +2636,9 @@ namespace Mono.CSharp {
                public Expression GetParameterReference (string name, Location loc)
                {
                        for (ToplevelBlock t = this; t != null; t = t.Container) {
+                               if (t.parameters.IsEmpty)
+                                       continue;
+
                                Expression expr = t.GetParameterReferenceExpression (name, loc);
                                if (expr != null)
                                        return expr;
@@ -2846,6 +2654,21 @@ namespace Mono.CSharp {
                                null : new ParameterReference (parameter_info [idx], loc);
                }
 
+               public ToplevelBlock CheckParameterNameConflict (string name)
+               {
+                       for (ToplevelBlock t = this; t != null; t = t.Container) {
+                               if (t.HasParameterWithName (name))
+                                       return t;
+                       }
+
+                       return null;
+               }
+
+               protected virtual bool HasParameterWithName (string name)
+               {
+                       return parameters.GetParameterIndexByName (name) >= 0;
+               }
+
                // <summary>
                //   Returns the "this" instance variable of this block.
                //   See AddThisVariable() for more information.
@@ -2861,7 +2684,7 @@ namespace Mono.CSharp {
                //   analysis code to ensure that it's been fully initialized before control
                //   leaves the constructor.
                // </summary>
-               public LocalInfo AddThisVariable (DeclSpace ds, Location l)
+               public LocalInfo AddThisVariable (TypeContainer ds, Location l)
                {
                        if (this_variable == null) {
                                this_variable = new LocalInfo (ds, this, l);
@@ -2879,19 +2702,70 @@ namespace Mono.CSharp {
                        set { flags = value ? flags | Flags.IsIterator : flags & ~Flags.IsIterator; }
                }
 
-               public bool IsThisAssigned (EmitContext ec)
-               {
-                       return this_variable == null || this_variable.IsThisAssigned (ec);
+               //
+               // Block has been converted to expression tree
+               //
+               public bool IsExpressionTree {
+                       get { return (flags & Flags.IsExpressionTree) != 0; }
                }
 
-               public bool ResolveMeta (EmitContext ec, ParametersCompiled ip)
+               public bool IsThisAssigned (BlockContext ec)
                {
-                       int errors = Report.Errors;
-                       int orig_count = parameters.Count;
+                       return this_variable == null || this_variable.IsThisAssigned (ec, this);
+               }
 
-                       if (top_level_branching != null)
+               public bool Resolve (FlowBranching parent, BlockContext rc, ParametersCompiled ip, IMethodData md)
+               {
+                       if (resolved)
                                return true;
 
+                       resolved = true;
+
+                       if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion))
+                               flags |= Flags.IsExpressionTree;
+
+                       try {
+                               if (!ResolveMeta (rc, ip))
+                                       return false;
+
+                               using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) {
+                                       FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);
+
+                                       if (!Resolve (rc))
+                                               return false;
+
+                                       unreachable = top_level.End ();
+                               }
+                       } catch (Exception e) {
+                               if (rc.CurrentBlock != null) {
+                                       rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message);
+                               } else {
+                                       rc.Report.Error (587, "Internal compiler error: {0}", e.Message);
+                               }
+
+                               if (Report.DebugFlags > 0)
+                                       throw;
+                       }
+
+                       if (rc.ReturnType != TypeManager.void_type && !unreachable) {
+                               if (rc.CurrentAnonymousMethod == null) {
+                                       rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
+                                       return false;
+                               } else if (!rc.CurrentAnonymousMethod.IsIterator) {
+                                       rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
+                                                         rc.CurrentAnonymousMethod.GetSignatureForError ());
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               bool ResolveMeta (BlockContext ec, ParametersCompiled ip)
+               {
+                       int errors = ec.Report.Errors;
+                       int orig_count = parameters.Count;
+
                        if (ip != null)
                                parameters = ip;
 
@@ -2914,9 +2788,7 @@ namespace Mono.CSharp {
 
                        ResolveMeta (ec, offset);
 
-                       top_level_branching = ec.StartFlowBranching (this);
-
-                       return Report.Errors == errors;
+                       return ec.Report.Errors == errors;
                }
 
                // <summary>
@@ -2943,10 +2815,63 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void EmitMeta (EmitContext ec)
+               public override void Emit (EmitContext ec)
                {
-                       parameters.ResolveVariable ();
+                       if (Report.Errors > 0)
+                               return;
+
+#if PRODUCTION
+                       try {
+#endif
+                       EmitMeta (ec);
+
+                       if (ec.HasReturnLabel)
+                               ec.ReturnLabel = ec.DefineLabel ();
 
+                       base.Emit (ec);
+
+                       ec.Mark (EndLocation);
+
+                       if (ec.HasReturnLabel)
+                               ec.MarkLabel (ec.ReturnLabel);
+
+                       if (ec.return_value != null) {
+                               ec.Emit (OpCodes.Ldloc, ec.return_value);
+                               ec.Emit (OpCodes.Ret);
+                       } else {
+                               //
+                               // If `HasReturnLabel' is set, then we already emitted a
+                               // jump to the end of the method, so we must emit a `ret'
+                               // there.
+                               //
+                               // Unfortunately, System.Reflection.Emit automatically emits
+                               // a leave to the end of a finally block.  This is a problem
+                               // if no code is following the try/finally block since we may
+                               // jump to a point after the end of the method.
+                               // As a workaround, we're always creating a return label in
+                               // this case.
+                               //
+
+                               if (ec.HasReturnLabel || !unreachable) {
+                                       if (ec.ReturnType != TypeManager.void_type)
+                                               ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
+                                       ec.Emit (OpCodes.Ret);
+                               }
+                       }
+
+#if PRODUCTION
+                       } catch (Exception e){
+                               Console.WriteLine ("Exception caught by the compiler while emitting:");
+                               Console.WriteLine ("   Block that caused the problem begin at: " + block.loc);
+                                       
+                               Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+                               throw;
+                       }
+#endif
+               }
+
+               public override void EmitMeta (EmitContext ec)
+               {
                        // Avoid declaring an IL variable for this_variable since it is not accessed
                        // from the generated IL
                        if (this_variable != null)
@@ -2962,12 +2887,6 @@ namespace Mono.CSharp {
 
                        base.EmitSymbolInfo (ec);
                }
-
-               public override void Emit (EmitContext ec)
-               {
-                       base.Emit (ec);
-                       ec.Mark (EndLocation);
-               }
        }
        
        public class SwitchLabel {
@@ -3010,7 +2929,7 @@ namespace Mono.CSharp {
                public Label GetILLabel (EmitContext ec)
                {
                        if (!il_label_set){
-                               il_label = ec.ig.DefineLabel ();
+                               il_label = ec.DefineLabel ();
                                il_label_set = true;
                        }
                        return il_label;
@@ -3019,7 +2938,7 @@ namespace Mono.CSharp {
                public Label GetILLabelCode (EmitContext ec)
                {
                        if (!il_label_code_set){
-                               il_label_code = ec.ig.DefineLabel ();
+                               il_label_code = ec.DefineLabel ();
                                il_label_code_set = true;
                        }
                        return il_label_code;
@@ -3029,7 +2948,7 @@ namespace Mono.CSharp {
                // Resolves the expression, reduces it to a literal if possible
                // and then converts it to the requested type.
                //
-               public bool ResolveAndReduce (EmitContext ec, Type required_type, bool allow_nullable)
+               public bool ResolveAndReduce (ResolveContext ec, TypeSpec required_type, bool allow_nullable)
                {       
                        Expression e = label.Resolve (ec);
 
@@ -3038,7 +2957,7 @@ namespace Mono.CSharp {
 
                        Constant c = e as Constant;
                        if (c == null){
-                               Report.Error (150, loc, "A constant value is expected");
+                               ec.Report.Error (150, loc, "A constant value is expected");
                                return false;
                        }
 
@@ -3060,7 +2979,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public void Error_AlreadyOccurs (Type switch_type, SwitchLabel collision_with)
+               public void Error_AlreadyOccurs (ResolveContext ec, TypeSpec switch_type, SwitchLabel collision_with)
                {
                        string label;
                        if (converted == null)
@@ -3070,8 +2989,8 @@ namespace Mono.CSharp {
                        else
                                label = converted.ToString ();
                        
-                       Report.SymbolRelatedToPreviousError (collision_with.loc, null);
-                       Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label);
+                       ec.Report.SymbolRelatedToPreviousError (collision_with.loc, null);
+                       ec.Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label);
                }
 
                public SwitchLabel Clone (CloneContext clonectx)
@@ -3082,10 +3001,10 @@ namespace Mono.CSharp {
 
        public class SwitchSection {
                // An array of SwitchLabels.
-               public readonly ArrayList Labels;
+               public readonly List<SwitchLabel> Labels;
                public readonly Block Block;
                
-               public SwitchSection (ArrayList labels, Block block)
+               public SwitchSection (List<SwitchLabel> labels, Block block)
                {
                        Labels = labels;
                        Block = block;
@@ -3093,7 +3012,7 @@ namespace Mono.CSharp {
 
                public SwitchSection Clone (CloneContext clonectx)
                {
-                       ArrayList cloned_labels = new ArrayList ();
+                       var cloned_labels = new List<SwitchLabel> ();
 
                        foreach (SwitchLabel sl in cloned_labels)
                                cloned_labels.Add (sl.Clone (clonectx));
@@ -3103,18 +3022,18 @@ namespace Mono.CSharp {
        }
        
        public class Switch : Statement {
-               public ArrayList Sections;
+               public List<SwitchSection> Sections;
                public Expression Expr;
 
                /// <summary>
                ///   Maps constants whose type type SwitchType to their  SwitchLabels.
                /// </summary>
-               public IDictionary Elements;
+               public IDictionary<object, SwitchLabel> Elements;
 
                /// <summary>
                ///   The governing switch type
                /// </summary>
-               public Type SwitchType;
+               public TypeSpec SwitchType;
 
                //
                // Computed
@@ -3144,9 +3063,9 @@ namespace Mono.CSharp {
                // The types allowed to be implicitly cast from
                // on the governing type
                //
-               static Type [] allowed_types;
-               
-               public Switch (Expression e, ArrayList sects, Location l)
+               static TypeSpec [] allowed_types;
+
+               public Switch (Expression e, List<SwitchSection> sects, Location l)
                {
                        Expr = e;
                        Sections = sects;
@@ -3171,9 +3090,9 @@ namespace Mono.CSharp {
                // expression that includes any potential conversions to the
                // integral types or to string.
                //
-               Expression SwitchGoverningType (EmitContext ec, Expression expr)
+               Expression SwitchGoverningType (ResolveContext ec, Expression expr)
                {
-                       Type t = expr.Type;
+                       TypeSpec t = expr.Type;
 
                        if (t == TypeManager.byte_type ||
                            t == TypeManager.sbyte_type ||
@@ -3190,7 +3109,7 @@ namespace Mono.CSharp {
                                return expr;
 
                        if (allowed_types == null){
-                               allowed_types = new Type [] {
+                               allowed_types = new TypeSpec [] {
                                        TypeManager.sbyte_type,
                                        TypeManager.byte_type,
                                        TypeManager.short_type,
@@ -3211,7 +3130,7 @@ namespace Mono.CSharp {
                        // conversions, we have to report an error
                        //
                        Expression converted = null;
-                       foreach (Type tt in allowed_types){
+                       foreach (TypeSpec tt in allowed_types){
                                Expression e;
                                
                                e = Convert.ImplicitUserConversion (ec, expr, tt, loc);
@@ -3226,7 +3145,7 @@ namespace Mono.CSharp {
                                        continue;
 
                                if (converted != null){
-                                       Report.ExtraInformation (loc, "(Ambiguous implicit user defined conversion in previous ");
+                                       ec.Report.ExtraInformation (loc, "(Ambiguous implicit user defined conversion in previous ");
                                        return null;
                                }
 
@@ -3242,18 +3161,16 @@ namespace Mono.CSharp {
                // It also returns a hashtable with the keys that we will later
                // use to compute the switch tables
                //
-               bool CheckSwitch (EmitContext ec)
+               bool CheckSwitch (ResolveContext ec)
                {
                        bool error = false;
-                       Elements = Sections.Count > 10 ? 
-                               (IDictionary)new Hashtable () : 
-                               (IDictionary)new ListDictionary ();
+                       Elements = new Dictionary<object, SwitchLabel> ();
                                
                        foreach (SwitchSection ss in Sections){
                                foreach (SwitchLabel sl in ss.Labels){
                                        if (sl.Label == null){
                                                if (default_section != null){
-                                                       sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)default_section.Labels [0]);
+                                                       sl.Error_AlreadyOccurs (ec, SwitchType, (SwitchLabel)default_section.Labels [0]);
                                                        error = true;
                                                }
                                                default_section = ss;
@@ -3272,7 +3189,7 @@ namespace Mono.CSharp {
                                        try {
                                                Elements.Add (key, sl);
                                        } catch (ArgumentException) {
-                                               sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)Elements [key]);
+                                               sl.Error_AlreadyOccurs (ec, SwitchType, Elements [key]);
                                                error = true;
                                        }
                                }
@@ -3280,50 +3197,50 @@ namespace Mono.CSharp {
                        return !error;
                }
 
-               void EmitObjectInteger (ILGenerator ig, object k)
+               void EmitObjectInteger (EmitContext ec, object k)
                {
                        if (k is int)
-                               IntConstant.EmitInt (ig, (int) k);
+                               ec.EmitInt ((int) k);
                        else if (k is Constant) {
-                               EmitObjectInteger (ig, ((Constant) k).GetValue ());
+                               EmitObjectInteger (ec, ((Constant) k).GetValue ());
                        } 
                        else if (k is uint)
-                               IntConstant.EmitInt (ig, unchecked ((int) (uint) k));
+                               ec.EmitInt (unchecked ((int) (uint) k));
                        else if (k is long)
                        {
                                if ((long) k >= int.MinValue && (long) k <= int.MaxValue)
                                {
-                                       IntConstant.EmitInt (ig, (int) (long) k);
-                                       ig.Emit (OpCodes.Conv_I8);
+                                       ec.EmitInt ((int) (long) k);
+                                       ec.Emit (OpCodes.Conv_I8);
                                }
                                else
-                                       LongConstant.EmitLong (ig, (long) k);
+                                       ec.EmitLong ((long) k);
                        }
                        else if (k is ulong)
                        {
                                ulong ul = (ulong) k;
                                if (ul < (1L<<32))
                                {
-                                       IntConstant.EmitInt (ig, unchecked ((int) ul));
-                                       ig.Emit (OpCodes.Conv_U8);
+                                       ec.EmitInt (unchecked ((int) ul));
+                                       ec.Emit (OpCodes.Conv_U8);
                                }
                                else
                                {
-                                       LongConstant.EmitLong (ig, unchecked ((long) ul));
+                                       ec.EmitLong (unchecked ((long) ul));
                                }
                        }
                        else if (k is char)
-                               IntConstant.EmitInt (ig, (int) ((char) k));
+                               ec.EmitInt ((int) ((char) k));
                        else if (k is sbyte)
-                               IntConstant.EmitInt (ig, (int) ((sbyte) k));
+                               ec.EmitInt ((int) ((sbyte) k));
                        else if (k is byte)
-                               IntConstant.EmitInt (ig, (int) ((byte) k));
+                               ec.EmitInt ((int) ((byte) k));
                        else if (k is short)
-                               IntConstant.EmitInt (ig, (int) ((short) k));
+                               ec.EmitInt ((int) ((short) k));
                        else if (k is ushort)
-                               IntConstant.EmitInt (ig, (int) ((ushort) k));
+                               ec.EmitInt ((int) ((ushort) k));
                        else if (k is bool)
-                               IntConstant.EmitInt (ig, ((bool) k) ? 1 : 0);
+                               ec.EmitInt (((bool) k) ? 1 : 0);
                        else
                                throw new Exception ("Unhandled case");
                }
@@ -3337,7 +3254,7 @@ namespace Mono.CSharp {
                        }
                        public long first;
                        public long last;
-                       public ArrayList element_keys = null;
+                       public List<object> element_keys;
                        // how many items are in the bucket
                        public int Size = 1;
                        public int Length
@@ -3377,7 +3294,7 @@ namespace Mono.CSharp {
                        Array.Sort (element_keys);
 
                        // initialize the block list with one element per key
-                       ArrayList key_blocks = new ArrayList (element_count);
+                       var key_blocks = new List<KeyBlock> (element_count);
                        foreach (object key in element_keys)
                                key_blocks.Add (new KeyBlock (System.Convert.ToInt64 (key)));
 
@@ -3386,7 +3303,7 @@ namespace Mono.CSharp {
                        // there's probably a really cool way to do this with a tree...
                        while (key_blocks.Count > 1)
                        {
-                               ArrayList key_blocks_new = new ArrayList ();
+                               var key_blocks_new = new List<KeyBlock> ();
                                current_kb = (KeyBlock) key_blocks [0];
                                for (int ikb = 1; ikb < key_blocks.Count; ikb++)
                                {
@@ -3412,7 +3329,7 @@ namespace Mono.CSharp {
 
                        // initialize the key lists
                        foreach (KeyBlock kb in key_blocks)
-                               kb.element_keys = new ArrayList ();
+                               kb.element_keys = new List<object> ();
 
                        // fill the key lists
                        int iBlockCurr = 0;
@@ -3432,25 +3349,24 @@ namespace Mono.CSharp {
                        key_blocks.Sort ();
 
                        // okay now we can start...
-                       ILGenerator ig = ec.ig;
-                       Label lbl_end = ig.DefineLabel ();      // at the end ;-)
+                       Label lbl_end = ec.DefineLabel ();      // at the end ;-)
                        Label lbl_default = default_target;
 
                        Type type_keys = null;
                        if (element_keys.Length > 0)
                                type_keys = element_keys [0].GetType ();        // used for conversions
 
-                       Type compare_type;
+                       TypeSpec compare_type;
                        
                        if (TypeManager.IsEnumType (SwitchType))
-                               compare_type = TypeManager.GetEnumUnderlyingType (SwitchType);
+                               compare_type = EnumSpec.GetUnderlyingType (SwitchType);
                        else
                                compare_type = SwitchType;
                        
                        for (int iBlock = key_blocks.Count - 1; iBlock >= 0; --iBlock)
                        {
                                KeyBlock kb = ((KeyBlock) key_blocks [iBlock]);
-                               lbl_default = (iBlock == 0) ? default_target : ig.DefineLabel ();
+                               lbl_default = (iBlock == 0) ? default_target : ec.DefineLabel ();
                                if (kb.Length <= 2)
                                {
                                        foreach (object key in kb.element_keys) {
@@ -3459,8 +3375,8 @@ namespace Mono.CSharp {
                                                        val.EmitBranchable (ec, sl.GetILLabel (ec), false);
                                                } else {
                                                        val.Emit (ec);
-                                                       EmitObjectInteger (ig, key);
-                                                       ig.Emit (OpCodes.Beq, sl.GetILLabel (ec));
+                                                       EmitObjectInteger (ec, key);
+                                                       ec.Emit (OpCodes.Beq, sl.GetILLabel (ec));
                                                }
                                        }
                                }
@@ -3475,20 +3391,20 @@ namespace Mono.CSharp {
 
                                                // check block range (could be > 2^31)
                                                val.Emit (ec);
-                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
-                                               ig.Emit (OpCodes.Blt, lbl_default);
+                                               EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
+                                               ec.Emit (OpCodes.Blt, lbl_default);
                                                val.Emit (ec);
-                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.last, type_keys));
-                                               ig.Emit (OpCodes.Bgt, lbl_default);
+                                               EmitObjectInteger (ec, System.Convert.ChangeType (kb.last, type_keys));
+                                               ec.Emit (OpCodes.Bgt, lbl_default);
 
                                                // normalize range
                                                val.Emit (ec);
                                                if (kb.first != 0)
                                                {
-                                                       EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
-                                                       ig.Emit (OpCodes.Sub);
+                                                       EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
+                                                       ec.Emit (OpCodes.Sub);
                                                }
-                                               ig.Emit (OpCodes.Conv_I4);      // assumes < 2^31 labels!
+                                               ec.Emit (OpCodes.Conv_I4);      // assumes < 2^31 labels!
                                        }
                                        else
                                        {
@@ -3497,13 +3413,13 @@ namespace Mono.CSharp {
                                                int first = (int) kb.first;
                                                if (first > 0)
                                                {
-                                                       IntConstant.EmitInt (ig, first);
-                                                       ig.Emit (OpCodes.Sub);
+                                                       ec.EmitInt (first);
+                                                       ec.Emit (OpCodes.Sub);
                                                }
                                                else if (first < 0)
                                                {
-                                                       IntConstant.EmitInt (ig, -first);
-                                                       ig.Emit (OpCodes.Add);
+                                                       ec.EmitInt (-first);
+                                                       ec.Emit (OpCodes.Add);
                                                }
                                        }
 
@@ -3524,12 +3440,12 @@ namespace Mono.CSharp {
                                                        switch_labels [iJump] = lbl_default;
                                        }
                                        // emit the switch opcode
-                                       ig.Emit (OpCodes.Switch, switch_labels);
+                                       ec.Emit (OpCodes.Switch, switch_labels);
                                }
 
                                // mark the default for this block
                                if (iBlock != 0)
-                                       ig.MarkLabel (lbl_default);
+                                       ec.MarkLabel (lbl_default);
                        }
 
                        // TODO: find the default case and emit it here,
@@ -3538,7 +3454,7 @@ namespace Mono.CSharp {
 
                        // the last default just goes to the end
                        if (element_keys.Length > 0)
-                               ig.Emit (OpCodes.Br, lbl_default);
+                               ec.Emit (OpCodes.Br, lbl_default);
 
                        // now emit the code for the sections
                        bool found_default = false;
@@ -3546,27 +3462,27 @@ namespace Mono.CSharp {
                        foreach (SwitchSection ss in Sections) {
                                foreach (SwitchLabel sl in ss.Labels) {
                                        if (sl.Converted == SwitchLabel.NullStringCase) {
-                                               ig.MarkLabel (null_target);
+                                               ec.MarkLabel (null_target);
                                        } else if (sl.Label == null) {
-                                               ig.MarkLabel (lbl_default);
+                                               ec.MarkLabel (lbl_default);
                                                found_default = true;
                                                if (!has_null_case)
-                                                       ig.MarkLabel (null_target);
+                                                       ec.MarkLabel (null_target);
                                        }
-                                       ig.MarkLabel (sl.GetILLabel (ec));
-                                       ig.MarkLabel (sl.GetILLabelCode (ec));
+                                       ec.MarkLabel (sl.GetILLabel (ec));
+                                       ec.MarkLabel (sl.GetILLabelCode (ec));
                                }
                                ss.Block.Emit (ec);
                        }
                        
                        if (!found_default) {
-                               ig.MarkLabel (lbl_default);
+                               ec.MarkLabel (lbl_default);
                                if (!has_null_case) {
-                                       ig.MarkLabel (null_target);
+                                       ec.MarkLabel (null_target);
                                }
                        }
                        
-                       ig.MarkLabel (lbl_end);
+                       ec.MarkLabel (lbl_end);
                }
 
                SwitchSection FindSection (SwitchLabel label)
@@ -3581,19 +3497,13 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       foreach (SwitchSection ss in Sections)
-                               ss.Block.MutateHoistedGenericType (storey);
-               }
-
                public static void Reset ()
                {
                        unique_counter = 0;
                        allowed_types = null;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        Expr = Expr.Resolve (ec);
                        if (Expr == null)
@@ -3610,7 +3520,7 @@ namespace Mono.CSharp {
                        }
 
                        if (new_expr == null){
-                               Report.Error (151, loc,
+                               ec.Report.Error (151, loc,
                                        "A switch expression of type `{0}' cannot be converted to an integral type, bool, char, string, enum or nullable type",
                                        TypeManager.CSharpName (Expr.Type));
                                return false;
@@ -3620,7 +3530,7 @@ namespace Mono.CSharp {
                        SwitchType = new_expr.Type;
 
                        if (RootContext.Version == LanguageVersion.ISO_1 && SwitchType == TypeManager.bool_type) {
-                               Report.FeatureIsNotAvailable (loc, "switch expression of boolean type");
+                               ec.Report.FeatureIsNotAvailable (loc, "switch expression of boolean type");
                                return false;
                        }
 
@@ -3637,12 +3547,14 @@ namespace Mono.CSharp {
                        Report.Debug (1, "START OF SWITCH BLOCK", loc, ec.CurrentBranching);
                        ec.StartFlowBranching (FlowBranching.BranchingType.Switch, loc);
 
-                       is_constant = new_expr is Constant;
-                       if (is_constant) {
-                               object key = ((Constant) new_expr).GetValue ();
-                               SwitchLabel label = (SwitchLabel) Elements [key];
+                       var constant = new_expr as Constant;
+                       if (constant != null) {
+                               is_constant = true;
+                               object key = constant.GetValue ();
+                               SwitchLabel label;
+                               if (Elements.TryGetValue (key, out label))
+                                       constant_section = FindSection (label);
 
-                               constant_section = FindSection (label);
                                if (constant_section == null)
                                        constant_section = default_section;
                        }
@@ -3690,7 +3602,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               void ResolveStringSwitchMap (EmitContext ec)
+               void ResolveStringSwitchMap (ResolveContext ec)
                {
                        FullNamedExpression string_dictionary_type;
                        if (TypeManager.generic_ienumerable_type != null) {
@@ -3708,14 +3620,15 @@ namespace Mono.CSharp {
                                string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc);
                        }
 
-                       Field field = new Field (ec.TypeContainer, string_dictionary_type,
+                       var ctype = ec.CurrentMemberDefinition.Parent.PartialContainer;
+                       Field field = new Field (ctype, string_dictionary_type,
                                Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED,
                                new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null);
                        if (!field.Define ())
                                return;
-                       ec.TypeContainer.PartialContainer.AddField (field);
+                       ctype.AddField (field);
 
-                       ArrayList init = new ArrayList ();
+                       var init = new List<Expression> ();
                        int counter = 0;
                        Elements.Clear ();
                        string value = null;
@@ -3726,7 +3639,7 @@ namespace Mono.CSharp {
                                                continue;
 
                                        value = (string) sl.Converted;
-                                       ArrayList init_args = new ArrayList (2);
+                                       var init_args = new List<Expression> (2);
                                        init_args.Add (new StringLiteral (value, sl.Location));
                                        init_args.Add (new IntConstant (counter, loc));
                                        init.Add (new CollectionElementInitializer (init_args, loc));
@@ -3747,14 +3660,13 @@ namespace Mono.CSharp {
                        Expression initializer = new NewInitialize (string_dictionary_type, args,
                                new CollectionOrObjectInitializers (init, loc), loc);
 
-                       switch_cache_field = new FieldExpr (field.FieldBuilder, loc);
+                       switch_cache_field = new FieldExpr (field, loc);
                        string_dictionary = new SimpleAssign (switch_cache_field, initializer.Resolve (ec));
                }
 
                void DoEmitStringSwitch (LocalTemporary value, EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label l_initialized = ig.DefineLabel ();
+                       Label l_initialized = ec.DefineLabel ();
 
                        //
                        // Skip initialization when value is null
@@ -3766,15 +3678,17 @@ namespace Mono.CSharp {
                        //
                        switch_cache_field.EmitBranchable (ec, l_initialized, true);
                        string_dictionary.EmitStatement (ec);
-                       ig.MarkLabel (l_initialized);
+                       ec.MarkLabel (l_initialized);
 
                        LocalTemporary string_switch_variable = new LocalTemporary (TypeManager.int32_type);
 
+                       ResolveContext rc = new ResolveContext (ec.MemberContext);
+
                        if (TypeManager.generic_ienumerable_type != null) {
                                Arguments get_value_args = new Arguments (2);
                                get_value_args.Add (new Argument (value));
                                get_value_args.Add (new Argument (string_switch_variable, Argument.AType.Out));
-                               Expression get_item = new Invocation (new MemberAccess (switch_cache_field, "TryGetValue", loc), get_value_args).Resolve (ec);
+                               Expression get_item = new Invocation (new MemberAccess (switch_cache_field, "TryGetValue", loc), get_value_args).Resolve (rc);
                                if (get_item == null)
                                        return;
 
@@ -3786,16 +3700,16 @@ namespace Mono.CSharp {
                                Arguments get_value_args = new Arguments (1);
                                get_value_args.Add (new Argument (value));
 
-                               Expression get_item = new IndexerAccess (new ElementAccess (switch_cache_field, get_value_args), loc).Resolve (ec);
+                               Expression get_item = new IndexerAccess (new ElementAccess (switch_cache_field, get_value_args), loc).Resolve (rc);
                                if (get_item == null)
                                        return;
 
                                LocalTemporary get_item_object = new LocalTemporary (TypeManager.object_type);
                                get_item_object.EmitAssign (ec, get_item, true, false);
-                               ec.ig.Emit (OpCodes.Brfalse, default_target);
+                               ec.Emit (OpCodes.Brfalse, default_target);
 
                                ExpressionStatement get_item_int = (ExpressionStatement) new SimpleAssign (string_switch_variable,
-                                       new Cast (new TypeExpression (TypeManager.int32_type, loc), get_item_object, loc)).Resolve (ec);
+                                       new Cast (new TypeExpression (TypeManager.int32_type, loc), get_item_object, loc)).Resolve (rc);
 
                                get_item_int.EmitStatement (ec);
                                get_item_object.Release (ec);
@@ -3807,10 +3721,8 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
-                       default_target = ig.DefineLabel ();
-                       null_target = ig.DefineLabel ();
+                       default_target = ec.DefineLabel ();
+                       null_target = ec.DefineLabel ();
 
                        // Store variable for comparission purposes
                        // TODO: Don't duplicate non-captured VariableReference
@@ -3818,7 +3730,7 @@ namespace Mono.CSharp {
                        if (HaveUnwrap) {
                                value = new LocalTemporary (SwitchType);
                                unwrap.EmitCheck (ec);
-                               ig.Emit (OpCodes.Brfalse, null_target);
+                               ec.Emit (OpCodes.Brfalse, null_target);
                                new_expr.Emit (ec);
                                value.Store (ec);
                        } else if (!is_constant) {
@@ -3834,7 +3746,7 @@ namespace Mono.CSharp {
                        Label old_end = ec.LoopEnd;
                        Switch old_switch = ec.Switch;
                        
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
                        ec.Switch = this;
 
                        // Emit Code.
@@ -3851,7 +3763,7 @@ namespace Mono.CSharp {
                                value.Release (ec);
 
                        // Restore context state. 
-                       ig.MarkLabel (ec.LoopEnd);
+                       ec.MarkLabel (ec.LoopEnd);
 
                        //
                        // Restore the previous context
@@ -3865,7 +3777,7 @@ namespace Mono.CSharp {
                        Switch target = (Switch) t;
 
                        target.Expr = Expr.Clone (clonectx);
-                       target.Sections = new ArrayList ();
+                       target.Sections = new List<SwitchSection> ();
                        foreach (SwitchSection ss in Sections){
                                target.Sections.Add (ss.Clone (clonectx));
                        }
@@ -3882,7 +3794,7 @@ namespace Mono.CSharp {
                {
                        if (!prepared) {
                                prepared = true;
-                               resume_point = ec.ig.DefineLabel ();
+                               resume_point = ec.DefineLabel ();
                        }
                        return resume_point;
                }
@@ -3900,6 +3812,9 @@ namespace Mono.CSharp {
        public abstract class ExceptionStatement : ResumableStatement
        {
                bool code_follows;
+               Iterator iter;
+               List<ResumableStatement> resume_points;
+               int first_resume_pc;
 
                protected abstract void EmitPreTryBody (EmitContext ec);
                protected abstract void EmitTryBody (EmitContext ec);
@@ -3907,47 +3822,45 @@ namespace Mono.CSharp {
 
                protected sealed override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        EmitPreTryBody (ec);
 
                        if (resume_points != null) {
-                               IntConstant.EmitInt (ig, (int) Iterator.State.Running);
-                               ig.Emit (OpCodes.Stloc, ec.CurrentIterator.CurrentPC);
+                               ec.EmitInt ((int) Iterator.State.Running);
+                               ec.Emit (OpCodes.Stloc, iter.CurrentPC);
                        }
 
-                       ig.BeginExceptionBlock ();
+                       ec.BeginExceptionBlock ();
 
                        if (resume_points != null) {
-                               ig.MarkLabel (resume_point);
+                               ec.MarkLabel (resume_point);
 
                                // For normal control flow, we want to fall-through the Switch
                                // So, we use CurrentPC rather than the $PC field, and initialize it to an outside value above
-                               ig.Emit (OpCodes.Ldloc, ec.CurrentIterator.CurrentPC);
-                               IntConstant.EmitInt (ig, first_resume_pc);
-                               ig.Emit (OpCodes.Sub);
+                               ec.Emit (OpCodes.Ldloc, iter.CurrentPC);
+                               ec.EmitInt (first_resume_pc);
+                               ec.Emit (OpCodes.Sub);
 
                                Label [] labels = new Label [resume_points.Count];
                                for (int i = 0; i < resume_points.Count; ++i)
                                        labels [i] = ((ResumableStatement) resume_points [i]).PrepareForEmit (ec);
-                               ig.Emit (OpCodes.Switch, labels);
+                               ec.Emit (OpCodes.Switch, labels);
                        }
 
                        EmitTryBody (ec);
 
-                       ig.BeginFinallyBlock ();
+                       ec.BeginFinallyBlock ();
 
-                       Label start_finally = ec.ig.DefineLabel ();
+                       Label start_finally = ec.DefineLabel ();
                        if (resume_points != null) {
-                               ig.Emit (OpCodes.Ldloc, ec.CurrentIterator.SkipFinally);
-                               ig.Emit (OpCodes.Brfalse_S, start_finally);
-                               ig.Emit (OpCodes.Endfinally);
+                               ec.Emit (OpCodes.Ldloc, iter.SkipFinally);
+                               ec.Emit (OpCodes.Brfalse_S, start_finally);
+                               ec.Emit (OpCodes.Endfinally);
                        }
 
-                       ig.MarkLabel (start_finally);
+                       ec.MarkLabel (start_finally);
                        EmitFinallyBody (ec);
 
-                       ig.EndExceptionBlock ();
+                       ec.EndExceptionBlock ();
                }
 
                public void SomeCodeFollows ()
@@ -3955,21 +3868,21 @@ namespace Mono.CSharp {
                        code_follows = true;
                }
 
-               protected void ResolveReachability (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        // System.Reflection.Emit automatically emits a 'leave' at the end of a try clause
                        // So, ensure there's some IL code after this statement.
                        if (!code_follows && resume_points == null && ec.CurrentBranching.CurrentUsageVector.IsUnreachable)
                                ec.NeedReturnLabel ();
 
+                       iter = ec.CurrentIterator;
+                       return true;
                }
 
-               ArrayList resume_points;
-               int first_resume_pc;
                public void AddResumePoint (ResumableStatement stmt, int pc)
                {
                        if (resume_points == null) {
-                               resume_points = new ArrayList ();
+                               resume_points = new List<ResumableStatement> ();
                                first_resume_pc = pc;
                        }
 
@@ -3985,7 +3898,7 @@ namespace Mono.CSharp {
                {
                        if (!prepared_for_dispose) {
                                prepared_for_dispose = true;
-                               dispose_try_block = ec.ig.DefineLabel ();
+                               dispose_try_block = ec.DefineLabel ();
                        }
                        return dispose_try_block;
                }
@@ -3997,17 +3910,15 @@ namespace Mono.CSharp {
 
                        emitted_dispose = true;
 
-                       ILGenerator ig = ec.ig;
-
-                       Label end_of_try = ig.DefineLabel ();
+                       Label end_of_try = ec.DefineLabel ();
 
                        // Ensure that the only way we can get into this code is through a dispatcher
                        if (have_dispatcher)
-                               ig.Emit (OpCodes.Br, end);
+                               ec.Emit (OpCodes.Br, end);
 
-                       ig.BeginExceptionBlock ();
+                       ec.BeginExceptionBlock ();
 
-                       ig.MarkLabel (dispose_try_block);
+                       ec.MarkLabel (dispose_try_block);
 
                        Label [] labels = null;
                        for (int i = 0; i < resume_points.Count; ++i) {
@@ -4032,10 +3943,10 @@ namespace Mono.CSharp {
 
                                if (emit_dispatcher) {
                                        //SymbolWriter.StartIteratorDispatcher (ec.ig);
-                                       ig.Emit (OpCodes.Ldloc, iterator.CurrentPC);
-                                       IntConstant.EmitInt (ig, first_resume_pc);
-                                       ig.Emit (OpCodes.Sub);
-                                       ig.Emit (OpCodes.Switch, labels);
+                                       ec.Emit (OpCodes.Ldloc, iterator.CurrentPC);
+                                       ec.EmitInt (first_resume_pc);
+                                       ec.Emit (OpCodes.Sub);
+                                       ec.Emit (OpCodes.Switch, labels);
                                        //SymbolWriter.EndIteratorDispatcher (ec.ig);
                                }
 
@@ -4043,13 +3954,13 @@ namespace Mono.CSharp {
                                        s.EmitForDispose (ec, iterator, end_of_try, emit_dispatcher);
                        }
 
-                       ig.MarkLabel (end_of_try);
+                       ec.MarkLabel (end_of_try);
 
-                       ig.BeginFinallyBlock ();
+                       ec.BeginFinallyBlock ();
 
                        EmitFinallyBody (ec);
 
-                       ig.EndExceptionBlock ();
+                       ec.EndExceptionBlock ();
                }
        }
 
@@ -4065,14 +3976,14 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
                                return false;
 
                        if (!TypeManager.IsReferenceType (expr.Type)){
-                               Report.Error (185, loc,
+                               ec.Report.Error (185, loc,
                                              "`{0}' is not a reference type as required by the lock statement",
                                              TypeManager.CSharpName (expr.Type));
                                return false;
@@ -4082,11 +3993,11 @@ namespace Mono.CSharp {
                        bool ok = Statement.Resolve (ec);
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
+                       ok &= base.Resolve (ec);
 
                        // Avoid creating libraries that reference the internal
                        // mcs NullType:
-                       Type t = expr.Type;
+                       TypeSpec t = expr.Type;
                        if (t == TypeManager.null_type)
                                t = TypeManager.object_type;
                        
@@ -4094,7 +4005,7 @@ namespace Mono.CSharp {
                        temp.Resolve (ec);
 
                        if (TypeManager.void_monitor_enter_object == null || TypeManager.void_monitor_exit_object == null) {
-                               Type monitor_type = TypeManager.CoreLookupType ("System.Threading", "Monitor", Kind.Class, true);
+                               TypeSpec monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", MemberKind.Class, true);
                                TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
                                        monitor_type, "Enter", loc, TypeManager.object_type);
                                TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
@@ -4106,11 +4017,9 @@ namespace Mono.CSharp {
                
                protected override void EmitPreTryBody (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        temp.EmitAssign (ec, expr);
                        temp.Emit (ec);
-                       ig.Emit (OpCodes.Call, TypeManager.void_monitor_enter_object);
+                       ec.Emit (OpCodes.Call, TypeManager.void_monitor_enter_object);
                }
 
                protected override void EmitTryBody (EmitContext ec)
@@ -4121,16 +4030,9 @@ namespace Mono.CSharp {
                protected override void EmitFinallyBody (EmitContext ec)
                {
                        temp.Emit (ec);
-                       ec.ig.Emit (OpCodes.Call, TypeManager.void_monitor_exit_object);
+                       ec.Emit (OpCodes.Call, TypeManager.void_monitor_exit_object);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       temp.MutateHoistedGenericType (storey);
-                       Statement.MutateHoistedGenericType (storey);
-               }
-               
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Lock target = (Lock) t;
@@ -4149,23 +4051,18 @@ namespace Mono.CSharp {
                        b.Unchecked = true;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (ResolveContext.Options.AllCheckStateFlags, false))
                                return Block.Resolve (ec);
                }
                
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
                                Block.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Unchecked target = (Unchecked) t;
@@ -4183,23 +4080,18 @@ namespace Mono.CSharp {
                        b.Unchecked = false;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
-                               return Block.Resolve (ec);
+                       using (ec.With (ResolveContext.Options.AllCheckStateFlags, true))
+                               return Block.Resolve (ec);
                }
 
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
+                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
                                Block.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Checked target = (Checked) t;
@@ -4215,23 +4107,21 @@ namespace Mono.CSharp {
                {
                        Block = b;
                        Block.Unsafe = true;
+                       loc = b.StartLocation;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Flags.InUnsafe, true))
+                       if (ec.CurrentIterator != null)
+                               ec.Report.Error (1629, loc, "Unsafe code may not appear in iterators");
+
+                       using (ec.Set (ResolveContext.Options.UnsafeScope))
                                return Block.Resolve (ec);
                }
                
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Flags.InUnsafe, true))
-                               Block.Emit (ec);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
+                       Block.Emit (ec);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -4247,9 +4137,9 @@ namespace Mono.CSharp {
        //
        public class Fixed : Statement {
                Expression type;
-               ArrayList declarators;
+               List<KeyValuePair<LocalInfo, Expression>> declarators;
                Statement statement;
-               Type expr_type;
+               TypeSpec expr_type;
                Emitter[] data;
                bool has_ret;
 
@@ -4284,8 +4174,8 @@ namespace Mono.CSharp {
 
                        public override void EmitExit (EmitContext ec)
                        {
-                               ec.ig.Emit (OpCodes.Ldc_I4_0);
-                               ec.ig.Emit (OpCodes.Conv_U);
+                               ec.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Conv_U);
                                vi.EmitAssign (ec);
                        }
                }
@@ -4301,44 +4191,45 @@ namespace Mono.CSharp {
                                pinned_string.Pinned = true;
                        }
 
+                       public StringEmitter Resolve (ResolveContext rc)
+                       {
+                               pinned_string.Resolve (rc);
+
+                               if (TypeManager.int_get_offset_to_string_data == null) {
+                                       TypeManager.int_get_offset_to_string_data = TypeManager.GetPredefinedProperty (
+                                               TypeManager.runtime_helpers_type, "OffsetToStringData", pinned_string.Location, TypeManager.int32_type);
+                               }
+
+                               return this;
+                       }
+
                        public override void Emit (EmitContext ec)
                        {
-                               pinned_string.Resolve (ec);
                                pinned_string.ResolveVariable (ec);
 
                                converted.Emit (ec);
                                pinned_string.EmitAssign (ec);
 
-                               PropertyInfo p = TypeManager.int_get_offset_to_string_data;
-                               if (p == null) {
-                                       // TODO: Move to resolve
-                                       p = TypeManager.int_get_offset_to_string_data = TypeManager.GetPredefinedProperty (
-                                               TypeManager.runtime_helpers_type, "OffsetToStringData", pinned_string.Location, TypeManager.int32_type);
-
-                                       if (p == null)
-                                               return;
-                               }
-
                                // TODO: Should use Binary::Add
                                pinned_string.Emit (ec);
-                               ec.ig.Emit (OpCodes.Conv_I);
+                               ec.Emit (OpCodes.Conv_I);
 
-                               PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, p, pinned_string.Location);
+                               PropertyExpr pe = new PropertyExpr (TypeManager.int_get_offset_to_string_data, pinned_string.Location);
                                //pe.InstanceExpression = pinned_string;
-                               pe.Resolve (ec).Emit (ec);
+                               pe.Resolve (new ResolveContext (ec.MemberContext)).Emit (ec);
 
-                               ec.ig.Emit (OpCodes.Add);
+                               ec.Emit (OpCodes.Add);
                                vi.EmitAssign (ec);
                        }
 
                        public override void EmitExit (EmitContext ec)
                        {
-                               ec.ig.Emit (OpCodes.Ldnull);
+                               ec.Emit (OpCodes.Ldnull);
                                pinned_string.EmitAssign (ec);
                        }
                }
 
-               public Fixed (Expression type, ArrayList decls, Statement stmt, Location l)
+               public Fixed (Expression type, List<KeyValuePair<LocalInfo, Expression>> decls, Statement stmt, Location l)
                {
                        this.type = type;
                        declarators = decls;
@@ -4350,17 +4241,17 @@ namespace Mono.CSharp {
                        get { return statement; }
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       if (!ec.InUnsafe){
-                               Expression.UnsafeError (loc);
+                       if (!ec.IsUnsafe){
+                               Expression.UnsafeError (ec, loc);
                                return false;
                        }
                        
                        TypeExpr texpr = type.ResolveAsContextualType (ec, false);
                        if (texpr == null) {
                                if (type is VarExpr)
-                                       Report.Error (821, type.Location, "A fixed statement cannot use an implicitly typed local variable");
+                                       ec.Report.Error (821, type.Location, "A fixed statement cannot use an implicitly typed local variable");
 
                                return false;
                        }
@@ -4370,14 +4261,14 @@ namespace Mono.CSharp {
                        data = new Emitter [declarators.Count];
 
                        if (!expr_type.IsPointer){
-                               Report.Error (209, loc, "The type of locals declared in a fixed statement must be a pointer type");
+                               ec.Report.Error (209, loc, "The type of locals declared in a fixed statement must be a pointer type");
                                return false;
                        }
                        
                        int i = 0;
-                       foreach (Pair p in declarators){
-                               LocalInfo vi = (LocalInfo) p.First;
-                               Expression e = (Expression) p.Second;
+                       foreach (var p in declarators){
+                               LocalInfo vi = p.Key;
+                               Expression e = p.Value;
                                
                                vi.VariableInfo.SetAssigned (ec);
                                vi.SetReadOnlyContext (LocalInfo.ReadOnlyContext.Fixed);
@@ -4394,13 +4285,14 @@ namespace Mono.CSharp {
                                //
 
                                if (e is Cast){
-                                       Report.Error (254, loc, "The right hand side of a fixed statement assignment may not be a cast expression");
+                                       ec.Report.Error (254, loc, "The right hand side of a fixed statement assignment may not be a cast expression");
                                        return false;
                                }
 
-                               ec.InFixedInitializer = true;
-                               e = e.Resolve (ec);
-                               ec.InFixedInitializer = false;
+                               using (ec.Set (ResolveContext.Options.FixedInitializerScope)) {
+                                       e = e.Resolve (ec);
+                               }
+
                                if (e == null)
                                        return false;
 
@@ -4408,12 +4300,12 @@ namespace Mono.CSharp {
                                // Case 2: Array
                                //
                                if (e.Type.IsArray){
-                                       Type array_type = TypeManager.GetElementType (e.Type);
+                                       TypeSpec array_type = TypeManager.GetElementType (e.Type);
                                        
                                        //
                                        // Provided that array_type is unmanaged,
                                        //
-                                       if (!TypeManager.VerifyUnManaged (array_type, loc))
+                                       if (!TypeManager.VerifyUnmanaged (ec.Compiler, array_type, loc))
                                                return false;
 
                                        //
@@ -4430,9 +4322,9 @@ namespace Mono.CSharp {
                                        //
                                        // fixed (T* e_ptr = (e == null || e.Length == 0) ? null : converted [0])
                                        //
-                                       converted = new Conditional (new Binary (Binary.Operator.LogicalOr,
-                                               new Binary (Binary.Operator.Equality, e, new NullLiteral (loc)),
-                                               new Binary (Binary.Operator.Equality, new MemberAccess (e, "Length"), new IntConstant (0, loc))),
+                                       converted = new Conditional (new BooleanExpression (new Binary (Binary.Operator.LogicalOr,
+                                               new Binary (Binary.Operator.Equality, e, new NullLiteral (loc), loc),
+                                               new Binary (Binary.Operator.Equality, new MemberAccess (e, "Length"), new IntConstant (0, loc), loc), loc)),
                                                        new NullPointer (loc),
                                                        converted);
 
@@ -4448,7 +4340,7 @@ namespace Mono.CSharp {
                                // Case 3: string
                                //
                                if (e.Type == TypeManager.string_type){
-                                       data [i] = new StringEmitter (e, vi, loc);
+                                       data [i] = new StringEmitter (e, vi, loc).Resolve (ec);
                                        i++;
                                        continue;
                                }
@@ -4471,7 +4363,7 @@ namespace Mono.CSharp {
                                }
 
                                if (data [i++] == null)
-                                       Report.Error (213, vi.Location, "You cannot use the fixed statement to take the address of an already fixed expression");
+                                       ec.Report.Error (213, vi.Location, "You cannot use the fixed statement to take the address of an already fixed expression");
 
                                e = Convert.ImplicitConversionRequired (ec, e, expr_type, loc);
                        }
@@ -4503,24 +4395,15 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       // Fixed statement cannot be used inside anonymous methods or lambdas
-                       throw new NotSupportedException ();
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Fixed target = (Fixed) t;
 
                        target.type = type.Clone (clonectx);
-                       target.declarators = new ArrayList (declarators.Count);
-                       foreach (Pair p in declarators) {
-                               LocalInfo vi = (LocalInfo) p.First;
-                               Expression e = (Expression) p.Second;
-
-                               target.declarators.Add (
-                                       new Pair (clonectx.LookupVariable (vi), e.Clone (clonectx)));                           
+                       target.declarators = new List<KeyValuePair<LocalInfo, Expression>> (declarators.Count);
+                       foreach (var p in declarators) {
+                               target.declarators.Add (new KeyValuePair<LocalInfo, Expression> (
+                                       clonectx.LookupVariable (p.Key), p.Value.Clone (clonectx)));
                        }
                        
                        target.statement = statement.Clone (clonectx);
@@ -4533,7 +4416,7 @@ namespace Mono.CSharp {
                public Block  VarBlock;
 
                Expression type_expr;
-               Type type;
+               TypeSpec type;
                
                public Catch (Expression type, string name, Block block, Block var_block, Location l)
                {
@@ -4544,7 +4427,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public Type CatchType {
+               public TypeSpec CatchType {
                        get {
                                return type;
                        }
@@ -4558,12 +4441,10 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        if (CatchType != null)
-                               ig.BeginCatchBlock (CatchType);
+                               ec.BeginCatchBlock (CatchType);
                        else
-                               ig.BeginCatchBlock (TypeManager.object_type);
+                               ec.BeginCatchBlock (TypeManager.object_type);
 
                        if (VarBlock != null)
                                VarBlock.Emit (ec);
@@ -4571,13 +4452,11 @@ namespace Mono.CSharp {
                        if (Name != null) {
                                // TODO: Move to resolve
                                LocalVariableReference lvr = new LocalVariableReference (Block, Name, loc);
-                               lvr.Resolve (ec);
+                               lvr.Resolve (new ResolveContext (ec.MemberContext));
                                
-#if GMCS_SOURCE
                                // Only to make verifier happy
                                if (TypeManager.IsGenericParameter (lvr.Type))
-                                       ig.Emit (OpCodes.Unbox_Any, lvr.Type);
-#endif
+                                       ec.Emit (OpCodes.Unbox_Any, lvr.Type);
 
                                Expression source;
                                if (lvr.IsHoisted) {
@@ -4591,14 +4470,14 @@ namespace Mono.CSharp {
 
                                lvr.EmitAssign (ec, source, false, false);
                        } else
-                               ig.Emit (OpCodes.Pop);
+                               ec.Emit (OpCodes.Pop);
 
                        Block.Emit (ec);
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Flags.InCatch, true)) {
+                       using (ec.With (ResolveContext.Options.CatchScope, true)) {
                                if (type_expr != null) {
                                        TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false);
                                        if (te == null)
@@ -4607,7 +4486,7 @@ namespace Mono.CSharp {
                                        type = te.Type;
 
                                        if (type != TypeManager.exception_type && !TypeManager.IsSubclassOf (type, TypeManager.exception_type)){
-                                               Error (155, "The type caught or thrown must be derived from System.Exception");
+                                               ec.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception");
                                                return false;
                                        }
                                } else
@@ -4625,15 +4504,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (type != null)
-                               type = storey.MutateType (type);
-                       if (VarBlock != null)
-                               VarBlock.MutateHoistedGenericType (storey);
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Catch target = (Catch) t;
@@ -4657,7 +4527,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
@@ -4668,14 +4538,14 @@ namespace Mono.CSharp {
 
                        if (ok)
                                ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally);
-                       using (ec.With (EmitContext.Flags.InFinally, true)) {
+                       using (ec.With (ResolveContext.Options.FinallyScope, true)) {
                                if (!fini.Resolve (ec))
                                        ok = false;
                        }
 
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
+                       ok &= base.Resolve (ec);
 
                        return ok;
                }
@@ -4694,12 +4564,6 @@ namespace Mono.CSharp {
                        fini.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       stmt.MutateHoistedGenericType (storey);
-                       fini.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        TryFinally target = (TryFinally) t;
@@ -4712,32 +4576,26 @@ namespace Mono.CSharp {
 
        public class TryCatch : Statement {
                public Block Block;
-               public ArrayList Specific;
+               public List<Catch> Specific;
                public Catch General;
                bool inside_try_finally, code_follows;
 
-               public TryCatch (Block block, ArrayList catch_clauses, Location l, bool inside_try_finally)
+               public TryCatch (Block block, List<Catch> catch_clauses, Location l, bool inside_try_finally)
                {
                        this.Block = block;
                        this.Specific = catch_clauses;
-                       this.General = null;
                        this.inside_try_finally = inside_try_finally;
 
-                       for (int i = 0; i < catch_clauses.Count; ++i) {
-                               Catch c = (Catch) catch_clauses [i];
-                               if (c.IsGeneral) {
-                                       if (i != catch_clauses.Count - 1)
-                                               Report.Error (1017, c.loc, "Try statement already has an empty catch block");
-                                       this.General = c;
-                                       catch_clauses.RemoveAt (i);
-                                       i--;
-                               }
+                       Catch c = catch_clauses [0];
+                       if (c.IsGeneral) {
+                               this.General = c;                       
+                               catch_clauses.RemoveAt (0);
                        }
 
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
@@ -4746,7 +4604,7 @@ namespace Mono.CSharp {
                        if (!Block.Resolve (ec))
                                ok = false;
 
-                       Type[] prev_catches = new Type [Specific.Count];
+                       TypeSpec[] prev_catches = new TypeSpec [Specific.Count];
                        int last_index = 0;
                        foreach (Catch c in Specific){
                                ec.CurrentBranching.CreateSibling (c.Block, FlowBranching.SiblingType.Catch);
@@ -4764,10 +4622,10 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               Type resolved_type = c.CatchType;
+                               TypeSpec resolved_type = c.CatchType;
                                for (int ii = 0; ii < last_index; ++ii) {
                                        if (resolved_type == prev_catches [ii] || TypeManager.IsSubclassOf (resolved_type, prev_catches [ii])) {
-                                               Report.Error (160, c.loc,
+                                               ec.Report.Error (160, c.loc,
                                                        "A previous catch clause already catches all exceptions of this or a super type `{0}'",
                                                        TypeManager.CSharpName (prev_catches [ii]));
                                                ok = false;
@@ -4781,7 +4639,7 @@ namespace Mono.CSharp {
                                if (CodeGen.Assembly.WrapNonExceptionThrows) {
                                        foreach (Catch c in Specific){
                                                if (c.CatchType == TypeManager.exception_type && PredefinedAttributes.Get.RuntimeCompatibility.IsDefined) {
-                                                       Report.Warning (1058, 1, c.loc, "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'");
+                                                       ec.Report.Warning (1058, 1, c.loc, "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'");
                                                }
                                        }
                                }
@@ -4809,10 +4667,8 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        if (!inside_try_finally)
-                               ig.BeginExceptionBlock ();
+                               ec.BeginExceptionBlock ();
 
                        Block.Emit (ec);
 
@@ -4823,19 +4679,7 @@ namespace Mono.CSharp {
                                General.Emit (ec);
 
                        if (!inside_try_finally)
-                               ig.EndExceptionBlock ();
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-
-                       if (General != null)
-                               General.MutateHoistedGenericType (storey);
-                       if (Specific != null) {
-                               foreach (Catch c in Specific)
-                                       c.MutateHoistedGenericType (storey);
-                       }
+                               ec.EndExceptionBlock ();
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -4846,19 +4690,20 @@ namespace Mono.CSharp {
                        if (General != null)
                                target.General = (Catch) General.Clone (clonectx);
                        if (Specific != null){
-                               target.Specific = new ArrayList ();
+                               target.Specific = new List<Catch> ();
                                foreach (Catch c in Specific)
-                                       target.Specific.Add (c.Clone (clonectx));
+                                       target.Specific.Add ((Catch) c.Clone (clonectx));
                        }
                }
        }
 
        // FIXME: Why is it almost exact copy of Using ??
-       public class UsingTemporary : ExceptionStatement {
+       public class UsingTemporary : ExceptionStatement
+       {
                TemporaryVariable local_copy;
                public Statement Statement;
                Expression expr;
-               Type expr_type;
+               Statement dispose_call;
 
                public UsingTemporary (Expression expr, Statement stmt, Location l)
                {
@@ -4867,36 +4712,54 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
                                return false;
 
-                       expr_type = expr.Type;
+                       var expr_type = expr.Type;
 
-                       if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)) {
-                               if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
-                                       Using.Error_IsNotConvertibleToIDisposable (expr);
+                       if (!expr_type.ImplementsInterface (TypeManager.idisposable_type) &&
+                               Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
+                               if (expr_type != InternalType.Dynamic) {
+                                       Using.Error_IsNotConvertibleToIDisposable (ec, expr);
                                        return false;
                                }
+
+                               expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.idisposable_type, loc);
+                               expr_type = expr.Type;
                        }
 
                        local_copy = new TemporaryVariable (expr_type, loc);
                        local_copy.Resolve (ec);
 
+                       if (TypeManager.void_dispose_void == null) {
+                               TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
+                                       TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
+                       }
+
+                       var dispose_mg = new MethodGroupExpr (TypeManager.void_dispose_void, TypeManager.idisposable_type, loc) {
+                               InstanceExpression = TypeManager.IsNullableType (expr_type) ?
+                               new Cast (new TypeExpression (TypeManager.idisposable_type, loc), local_copy).Resolve (ec) :
+                               local_copy
+                       };
+
+                       dispose_call = new StatementExpression (new Invocation (dispose_mg, null));
+
+                       // Add conditional call when disposing possible null variable
+                       if (!expr_type.IsStruct || TypeManager.IsNullableType (expr_type))
+                               dispose_call = new If (new Binary (Binary.Operator.Inequality, local_copy, new NullLiteral (loc), loc), dispose_call, loc);
+
+                       dispose_call.Resolve (ec);
+
                        ec.StartFlowBranching (this);
 
                        bool ok = Statement.Resolve (ec);
 
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
-
-                       if (TypeManager.void_dispose_void == null) {
-                               TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
-                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
-                       }
+                       ok &= base.Resolve (ec);
 
                        return ok;
                }
@@ -4913,51 +4776,7 @@ namespace Mono.CSharp {
 
                protected override void EmitFinallyBody (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       if (!TypeManager.IsStruct (expr_type)) {
-                               Label skip = ig.DefineLabel ();
-                               local_copy.Emit (ec);
-                               ig.Emit (OpCodes.Brfalse, skip);
-                               local_copy.Emit (ec);
-                               ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
-                               ig.MarkLabel (skip);
-                               return;
-                       }
-
-                       Expression ml = Expression.MemberLookup (
-                               ec.ContainerType, TypeManager.idisposable_type, expr_type,
-                               "Dispose", Location.Null);
-
-                       if (!(ml is MethodGroupExpr)) {
-                               local_copy.Emit (ec);
-                               ig.Emit (OpCodes.Box, expr_type);
-                               ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
-                               return;
-                       }
-
-                       MethodInfo mi = null;
-
-                       foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
-                               if (TypeManager.GetParameterData (mk).Count == 0) {
-                                       mi = mk;
-                                       break;
-                               }
-                       }
-
-                       if (mi == null) {
-                               Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
-                               return;
-                       }
-
-                       local_copy.AddressOf (ec, AddressOp.Load);
-                       ig.Emit (OpCodes.Call, mi);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr_type = storey.MutateType (expr_type);
-                       local_copy.MutateHoistedGenericType (storey);
-                       Statement.MutateHoistedGenericType (storey);
+                       dispose_call.Emit (ec);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -4988,11 +4807,11 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               static public void Error_IsNotConvertibleToIDisposable (Expression expr)
+               static public void Error_IsNotConvertibleToIDisposable (BlockContext ec, Expression expr)
                {
-                       Report.SymbolRelatedToPreviousError (expr.Type);
-                       Report.Error (1674, expr.Location, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
-                               expr.GetSignatureForError ());
+                       ec.Report.SymbolRelatedToPreviousError (expr.Type);
+                       ec.Report.Error (1674, expr.Location, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
+                               TypeManager.CSharpName (expr.Type));
                }
 
                protected override void EmitPreTryBody (EmitContext ec)
@@ -5007,29 +4826,21 @@ namespace Mono.CSharp {
 
                protected override void EmitFinallyBody (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label skip = ig.DefineLabel ();
+                       Label skip = ec.DefineLabel ();
 
                        bool emit_null_check = !TypeManager.IsValueType (var.Type);
                        if (emit_null_check) {
                                var.Emit (ec);
-                               ig.Emit (OpCodes.Brfalse, skip);
+                               ec.Emit (OpCodes.Brfalse, skip);
                        }
 
                        Invocation.EmitCall (ec, false, var, TypeManager.void_dispose_void, null, loc);
 
                        if (emit_null_check)
-                               ig.MarkLabel (skip);
+                               ec.MarkLabel (skip);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       assign.MutateHoistedGenericType (storey);
-                       var.MutateHoistedGenericType (storey);
-                       stmt.MutateHoistedGenericType (storey);
-               }
-
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        if (!ResolveVariable (ec))
                                return false;
@@ -5040,31 +4851,37 @@ namespace Mono.CSharp {
 
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
+                       ok &= base.Resolve (ec);
 
                        if (TypeManager.void_dispose_void == null) {
                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
-                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                                       TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
                        }
 
                        return ok;
                }
 
-               bool ResolveVariable (EmitContext ec)
+               bool ResolveVariable (BlockContext ec)
                {
                        assign = new SimpleAssign (var, init, loc);
                        assign = assign.ResolveStatement (ec);
                        if (assign == null)
                                return false;
 
-                       if (assign.Type == TypeManager.idisposable_type ||
-                               TypeManager.ImplementsInterface (assign.Type, TypeManager.idisposable_type)) {
+                       if (assign.Type == TypeManager.idisposable_type || assign.Type.ImplementsInterface (TypeManager.idisposable_type)) {
                                return true;
                        }
 
                        Expression e = Convert.ImplicitConversionStandard (ec, assign, TypeManager.idisposable_type, var.Location);
                        if (e == null) {
-                               Error_IsNotConvertibleToIDisposable (var);
+                               if (assign.Type == InternalType.Dynamic) {
+                                       e = Convert.ImplicitConversionRequired (ec, assign, TypeManager.idisposable_type, loc);
+                                       var = new TemporaryVariable (e.Type, loc);
+                                       assign = new SimpleAssign (var, e, loc).ResolveStatement (ec);
+                                       return true;
+                               }
+
+                               Error_IsNotConvertibleToIDisposable (ec, var);
                                return false;
                        }
 
@@ -5097,9 +4914,9 @@ namespace Mono.CSharp {
                                {
                                }
 
-                               public void ResolveIncrement (EmitContext ec)
+                               public void ResolveIncrement (BlockContext ec)
                                {
-                                       increment = new StatementExpression (new UnaryMutator (UnaryMutator.Mode.PostIncrement, this));
+                                       increment = new StatementExpression (new UnaryMutator (UnaryMutator.Mode.PostIncrement, this, loc));
                                        increment.Resolve (ec);
                                }
 
@@ -5142,7 +4959,7 @@ namespace Mono.CSharp {
                                throw new NotImplementedException ();
                        }
 
-                       public override bool Resolve (EmitContext ec)
+                       public override bool Resolve (BlockContext ec)
                        {
                                copy = new TemporaryVariable (for_each.expr.Type, loc);
                                copy.Resolve (ec);
@@ -5210,8 +5027,6 @@ namespace Mono.CSharp {
 
                        protected override void DoEmit (EmitContext ec)
                        {
-                               ILGenerator ig = ec.ig;
-
                                copy.EmitAssign (ec, for_each.expr);
 
                                int rank = length_exprs.Length;
@@ -5219,8 +5034,8 @@ namespace Mono.CSharp {
                                Label[] loop = new Label [rank];
 
                                for (int i = 0; i < rank; i++) {
-                                       test [i] = ig.DefineLabel ();
-                                       loop [i] = ig.DefineLabel ();
+                                       test [i] = ec.DefineLabel ();
+                                       loop [i] = ec.DefineLabel ();
 
                                        if (lengths != null)
                                                lengths [i].EmitAssign (ec, length_exprs [i]);
@@ -5230,20 +5045,20 @@ namespace Mono.CSharp {
                                for (int i = 0; i < rank; i++) {
                                        counter [i].EmitAssign (ec, zero);
 
-                                       ig.Emit (OpCodes.Br, test [i]);
-                                       ig.MarkLabel (loop [i]);
+                                       ec.Emit (OpCodes.Br, test [i]);
+                                       ec.MarkLabel (loop [i]);
                                }
 
                                ((IAssignMethod) for_each.variable).EmitAssign (ec, conv, false, false);
 
                                statement.Emit (ec);
 
-                               ig.MarkLabel (ec.LoopBegin);
+                               ec.MarkLabel (ec.LoopBegin);
 
                                for (int i = rank - 1; i >= 0; i--){
                                        counter [i].EmitIncrement (ec);
 
-                                       ig.MarkLabel (test [i]);
+                                       ec.MarkLabel (test [i]);
                                        counter [i].Emit (ec);
 
                                        if (lengths != null)
@@ -5251,25 +5066,10 @@ namespace Mono.CSharp {
                                        else
                                                length_exprs [i].Emit (ec);
 
-                                       ig.Emit (OpCodes.Blt, loop [i]);
+                                       ec.Emit (OpCodes.Blt, loop [i]);
                                }
 
-                               ig.MarkLabel (ec.LoopEnd);
-                       }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               for_each.expr.MutateHoistedGenericType (storey);
-
-                               copy.MutateHoistedGenericType (storey);
-                               conv.MutateHoistedGenericType (storey);
-                               statement.MutateHoistedGenericType (storey);
-
-                               for (int i = 0; i < counter.Length; i++) {
-                                       counter [i].MutateHoistedGenericType (storey);
-                                       if (lengths != null)
-                                               lengths [i].MutateHoistedGenericType (storey);
-                               }
+                               ec.MarkLabel (ec.LoopEnd);
                        }
                }
 
@@ -5277,12 +5077,12 @@ namespace Mono.CSharp {
                {
                        class CollectionForeachStatement : Statement
                        {
-                               Type type;
+                               TypeSpec type;
                                Expression variable, current, conv;
                                Statement statement;
                                Assign assign;
 
-                               public CollectionForeachStatement (Type type, Expression variable,
+                               public CollectionForeachStatement (TypeSpec type, Expression variable,
                                                                   Expression current, Statement statement,
                                                                   Location loc)
                                {
@@ -5298,7 +5098,7 @@ namespace Mono.CSharp {
                                        throw new NotImplementedException ();
                                }
 
-                               public override bool Resolve (EmitContext ec)
+                               public override bool Resolve (BlockContext ec)
                                {
                                        current = current.Resolve (ec);
                                        if (current == null)
@@ -5323,12 +5123,6 @@ namespace Mono.CSharp {
                                        assign.EmitStatement (ec);
                                        statement.Emit (ec);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       assign.MutateHoistedGenericType (storey);
-                                       statement.MutateHoistedGenericType (storey);
-                               }
                        }
 
                        Expression variable, expr;
@@ -5341,9 +5135,9 @@ namespace Mono.CSharp {
 
                        MethodGroupExpr get_enumerator;
                        PropertyExpr get_current;
-                       MethodInfo move_next;
+                       MethodSpec move_next;
                        Expression var_type;
-                       Type enumerator_type;
+                       TypeSpec enumerator_type;
                        bool enumerator_found;
 
                        public CollectionForeach (Expression var_type, Expression var,
@@ -5361,9 +5155,9 @@ namespace Mono.CSharp {
                                throw new NotImplementedException ();
                        }
 
-                       bool GetEnumeratorFilter (EmitContext ec, MethodInfo mi)
+                       bool GetEnumeratorFilter (ResolveContext ec, MethodSpec mi)
                        {
-                               Type return_type = mi.ReturnType;
+                               TypeSpec return_type = mi.ReturnType;
 
                                //
                                // Ok, we can access it, now make sure that we can do something
@@ -5371,7 +5165,7 @@ namespace Mono.CSharp {
                                //
 
                                if (return_type == TypeManager.ienumerator_type ||
-                                       TypeManager.ImplementsInterface (return_type, TypeManager.ienumerator_type)) {
+                                       return_type.ImplementsInterface (TypeManager.ienumerator_type)) {
                                        //
                                        // If it is not an interface, lets try to find the methods ourselves.
                                        // For example, if we have:
@@ -5388,7 +5182,7 @@ namespace Mono.CSharp {
 
                                        if (TypeManager.bool_movenext_void == null) {
                                                TypeManager.bool_movenext_void = TypeManager.GetPredefinedMethod (
-                                                       TypeManager.ienumerator_type, "MoveNext", loc, Type.EmptyTypes);
+                                                       TypeManager.ienumerator_type, "MoveNext", loc, TypeSpec.EmptyTypes);
                                        }
 
                                        if (TypeManager.ienumerator_getcurrent == null) {
@@ -5402,8 +5196,7 @@ namespace Mono.CSharp {
                                        if (return_type.IsInterface && TypeManager.IsGenericType (return_type)) {
                                                enumerator_type = return_type;
                                                if (!FetchGetCurrent (ec, return_type))
-                                                       get_current = new PropertyExpr (
-                                                               ec.ContainerType, TypeManager.ienumerator_getcurrent, loc);
+                                                       get_current = new PropertyExpr (TypeManager.ienumerator_getcurrent, loc);
                                                if (!FetchMoveNext (return_type))
                                                        move_next = TypeManager.bool_movenext_void;
                                                return true;
@@ -5414,8 +5207,7 @@ namespace Mono.CSharp {
                                            !FetchGetCurrent (ec, return_type)) {
                                                enumerator_type = return_type;
                                                move_next = TypeManager.bool_movenext_void;
-                                               get_current = new PropertyExpr (
-                                                       ec.ContainerType, TypeManager.ienumerator_getcurrent, loc);
+                                               get_current = new PropertyExpr (TypeManager.ienumerator_getcurrent, loc);
                                                return true;
                                        }
                                } else {
@@ -5425,7 +5217,7 @@ namespace Mono.CSharp {
                                        //
 
                                        if (TypeManager.HasElementType (return_type) || !FetchMoveNext (return_type) || !FetchGetCurrent (ec, return_type)) {
-                                               Report.Error (202, loc, "foreach statement requires that the return type `{0}' of `{1}' must have a suitable public MoveNext method and public Current property",
+                                               ec.Report.Error (202, loc, "foreach statement requires that the return type `{0}' of `{1}' must have a suitable public MoveNext method and public Current property",
                                                        TypeManager.CSharpName (return_type), TypeManager.CSharpSignature (mi));
                                                return false;
                                        }
@@ -5439,34 +5231,23 @@ namespace Mono.CSharp {
                        //
                        // Retrieves a `public bool MoveNext ()' method from the Type `t'
                        //
-                       bool FetchMoveNext (Type t)
+                       bool FetchMoveNext (TypeSpec t)
                        {
-                               MemberInfo[] move_next_list = TypeManager.MemberLookup (null, null, t,
-                                       MemberTypes.Method,
-                                       BindingFlags.Public | BindingFlags.Instance,
-                                       "MoveNext", null);
+                               move_next = MemberCache.FindMember (t,
+                                       MemberFilter.Method ("MoveNext", 0, ParametersCompiled.EmptyReadOnlyParameters, TypeManager.bool_type),
+                                       BindingRestriction.InstanceOnly) as MethodSpec;
 
-                               foreach (MemberInfo m in move_next_list){
-                                       MethodInfo mi = (MethodInfo) m;
-                               
-                                       if ((TypeManager.GetParameterData (mi).Count == 0) &&
-                                           TypeManager.TypeToCoreType (mi.ReturnType) == TypeManager.bool_type) {
-                                               move_next = mi;
-                                               return true;
-                                       }
-                               }
-
-                               return false;
+                               return move_next != null && (move_next.Modifiers & Modifiers.PUBLIC) != 0;
                        }
                
                        //
                        // Retrieves a `public T get_Current ()' method from the Type `t'
                        //
-                       bool FetchGetCurrent (EmitContext ec, Type t)
+                       bool FetchGetCurrent (ResolveContext ec, TypeSpec t)
                        {
-                               PropertyExpr pe = Expression.MemberLookup (
-                                       ec.ContainerType, t, "Current", MemberTypes.Property,
-                                       Expression.AllBindingFlags, loc) as PropertyExpr;
+                               PropertyExpr pe = Expression.MemberLookup (ec.Compiler,
+                                       ec.CurrentType, t, "Current", 0, MemberKind.Property,
+                                       BindingRestriction.AccessibleOnly, loc) as PropertyExpr;
                                if (pe == null)
                                        return false;
 
@@ -5474,51 +5255,35 @@ namespace Mono.CSharp {
                                return true;
                        }
 
-                       void Error_Enumerator ()
+                       void Error_Enumerator (BlockContext ec)
                        {
                                if (enumerator_found) {
                                        return;
                                }
 
-                           Report.Error (1579, loc,
+                           ec.Report.Error (1579, loc,
                                        "foreach statement cannot operate on variables of type `{0}' because it does not contain a definition for `GetEnumerator' or is not accessible",
                                        TypeManager.CSharpName (expr.Type));
                        }
 
-                       bool IsOverride (MethodInfo m)
+                       bool TryType (ResolveContext ec, TypeSpec t)
                        {
-                               m = (MethodInfo) TypeManager.DropGenericMethodArguments (m);
+                               var mg = Expression.MemberLookup (ec.Compiler, ec.CurrentType, null, t, "GetEnumerator", 0,
+                                       MemberKind.Method, BindingRestriction.NoOverrides | BindingRestriction.InstanceOnly, loc) as MethodGroupExpr;
 
-                               if (!m.IsVirtual || ((m.Attributes & MethodAttributes.NewSlot) != 0))
-                                       return false;
-                               if (m is MethodBuilder)
-                                       return true;
-
-                               MethodInfo base_method = m.GetBaseDefinition ();
-                               return base_method != m;
-                       }
-
-                       bool TryType (EmitContext ec, Type t)
-                       {
-                               MethodGroupExpr mg = Expression.MemberLookup (
-                                       ec.ContainerType, t, "GetEnumerator", MemberTypes.Method,
-                                       Expression.AllBindingFlags, loc) as MethodGroupExpr;
                                if (mg == null)
                                        return false;
 
-                               MethodInfo result = null;
-                               MethodInfo tmp_move_next = null;
+                               MethodSpec result = null;
+                               MethodSpec tmp_move_next = null;
                                PropertyExpr tmp_get_cur = null;
-                               Type tmp_enumerator_type = enumerator_type;
-                               foreach (MethodInfo mi in mg.Methods) {
-                                       if (TypeManager.GetParameterData (mi).Count != 0)
+                               TypeSpec tmp_enumerator_type = enumerator_type;
+                               foreach (MethodSpec mi in mg.Methods) {
+                                       if (!mi.Parameters.IsEmpty)
                                                continue;
                        
                                        // Check whether GetEnumerator is public
-                                       if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
-                                               continue;
-
-                                       if (IsOverride (mi))
+                                       if ((mi.Modifiers & Modifiers.AccessibilityMask) != Modifiers.PUBLIC)
                                                continue;
 
                                        enumerator_found = true;
@@ -5531,24 +5296,23 @@ namespace Mono.CSharp {
                                                        if (!TypeManager.IsGenericType (mi.ReturnType))
                                                                continue;
 
-                                                       MethodBase mb = TypeManager.DropGenericMethodArguments (mi);
-                                                       Report.SymbolRelatedToPreviousError (t);
-                                                       Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
-                                                                    "because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
-                                                                    TypeManager.CSharpName (t), TypeManager.CSharpSignature (mb));
+                                                       ec.Report.SymbolRelatedToPreviousError (t);
+                                                       ec.Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
+                                                                        "because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
+                                                                        TypeManager.CSharpName (t), TypeManager.generic_ienumerable_type.GetSignatureForError ());
                                                        return false;
                                                }
 
                                                // Always prefer generics enumerators
                                                if (!TypeManager.IsGenericType (mi.ReturnType)) {
-                                                       if (TypeManager.ImplementsInterface (mi.DeclaringType, result.DeclaringType) ||
-                                                           TypeManager.ImplementsInterface (result.DeclaringType, mi.DeclaringType))
+                                                       if (mi.DeclaringType.ImplementsInterface (result.DeclaringType) ||
+                                                               result.DeclaringType.ImplementsInterface (mi.DeclaringType))
                                                                continue;
 
-                                                       Report.SymbolRelatedToPreviousError (result);
-                                                       Report.SymbolRelatedToPreviousError (mi);
-                                                       Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'",
-                                                                       TypeManager.CSharpName (t), "enumerable", TypeManager.CSharpSignature (result), TypeManager.CSharpSignature (mi));
+                                                       ec.Report.SymbolRelatedToPreviousError (result);
+                                                       ec.Report.SymbolRelatedToPreviousError (mi);
+                                                       ec.Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'",
+                                                                       TypeManager.CSharpName (t), "enumerable", result.GetSignatureForError (), mi.GetSignatureForError ());
                                                        return false;
                                                }
                                        }
@@ -5564,8 +5328,7 @@ namespace Mono.CSharp {
                                        move_next = tmp_move_next;
                                        get_current = tmp_get_cur;
                                        enumerator_type = tmp_enumerator_type;
-                                       MethodInfo[] mi = new MethodInfo[] { (MethodInfo) result };
-                                       get_enumerator = new MethodGroupExpr (mi, enumerator_type, loc);
+                                       get_enumerator = new MethodGroupExpr (result, enumerator_type, loc);
 
                                        if (t != expr.Type) {
                                                expr = Convert.ExplicitConversion (
@@ -5581,45 +5344,55 @@ namespace Mono.CSharp {
                                }
 
                                return false;
-                       }               
+                       }
 
-                       bool ProbeCollectionType (EmitContext ec, Type t)
+                       bool ProbeCollectionType (ResolveContext ec, TypeSpec t)
                        {
-                               int errors = Report.Errors;
-                               for (Type tt = t; tt != null && tt != TypeManager.object_type;){
+                               int errors = ec.Report.Errors;
+                               for (TypeSpec tt = t; tt != null && tt != TypeManager.object_type;){
                                        if (TryType (ec, tt))
                                                return true;
                                        tt = tt.BaseType;
                                }
 
-                               if (Report.Errors > errors)
+                               if (ec.Report.Errors > errors)
                                        return false;
 
                                //
                                // Now try to find the method in the interfaces
                                //
-                               Type [] ifaces = TypeManager.GetInterfaces (t);
-                               foreach (Type i in ifaces){
-                                       if (TryType (ec, i))
-                                               return true;
+                               for (TypeSpec tt = t; tt != null && tt != TypeManager.object_type; ) {
+                                       if (tt.Interfaces != null) {
+                                               foreach (TypeSpec i in tt.Interfaces) {
+                                                       if (TryType (ec, i))
+                                                               return true;
+                                               }
+                                       }
+                                       tt = tt.BaseType;
                                }
 
                                return false;
                        }
 
-                       public override bool Resolve (EmitContext ec)
+                       public override bool Resolve (BlockContext ec)
                        {
                                enumerator_type = TypeManager.ienumerator_type;
 
+                               bool is_dynamic = expr.Type == InternalType.Dynamic;
+                               if (is_dynamic)
+                                       expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc);
+                               
                                if (!ProbeCollectionType (ec, expr.Type)) {
-                                       Error_Enumerator ();
+                                       Error_Enumerator (ec);
                                        return false;
                                }
 
                                VarExpr ve = var_type as VarExpr;
                                if (ve != null) {
                                        // Infer implicitly typed local variable from foreach enumerable type
-                                       var_type = new TypeExpression (get_current.PropertyInfo.PropertyType, var_type.Location);
+                                       var_type = new TypeExpression (
+                                               is_dynamic ? InternalType.Dynamic : get_current.Type,
+                                               var_type.Location);
                                }
 
                                var_type = var_type.ResolveAsTypeTerminal (ec, false);
@@ -5636,7 +5409,7 @@ namespace Mono.CSharp {
 
                                Expression move_next_expr;
                                {
-                                       MemberInfo[] mi = new MemberInfo[] { move_next };
+                                       var mi = new List<MemberSpec> (1) { move_next };
                                        MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc);
                                        mg.InstanceExpression = enumerator;
 
@@ -5648,10 +5421,10 @@ namespace Mono.CSharp {
                                Statement block = new CollectionForeachStatement (
                                        var_type.Type, variable, get_current, statement, loc);
 
-                               loop = new While (move_next_expr, block, loc);
+                               loop = new While (new BooleanExpression (move_next_expr), block, loc);
 
 
-                               bool implements_idisposable = TypeManager.ImplementsInterface (enumerator_type, TypeManager.idisposable_type);
+                               bool implements_idisposable = enumerator_type.ImplementsInterface (TypeManager.idisposable_type);
                                if (implements_idisposable || !enumerator_type.IsSealed) {
                                        wrapper = new DisposableWrapper (this, implements_idisposable);
                                } else {
@@ -5679,7 +5452,7 @@ namespace Mono.CSharp {
                                        throw new NotSupportedException ();
                                }
 
-                               public override bool Resolve (EmitContext ec)
+                               public override bool Resolve (BlockContext ec)
                                {
                                        return parent.ResolveLoop (ec);
                                }
@@ -5689,11 +5462,6 @@ namespace Mono.CSharp {
                                        parent.EmitLoopInit (ec);
                                        parent.EmitLoopBody (ec);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       throw new NotSupportedException ();
-                               }
                        }
 
                        sealed class DisposableWrapper : ExceptionStatement
@@ -5712,7 +5480,7 @@ namespace Mono.CSharp {
                                        throw new NotSupportedException ();
                                }
 
-                               public override bool Resolve (EmitContext ec)
+                               public override bool Resolve (BlockContext ec)
                                {
                                        bool ok = true;
 
@@ -5723,11 +5491,11 @@ namespace Mono.CSharp {
 
                                        ec.EndFlowBranching ();
 
-                                       ResolveReachability (ec);
+                                       ok &= base.Resolve (ec);
 
                                        if (TypeManager.void_dispose_void == null) {
                                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
-                                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                                                       TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
                                        }
                                        return ok;
                                }
@@ -5746,37 +5514,31 @@ namespace Mono.CSharp {
                                {
                                        Expression instance = parent.enumerator;
                                        if (!TypeManager.IsValueType (parent.enumerator_type)) {
-                                               ILGenerator ig = ec.ig;
 
                                                parent.enumerator.Emit (ec);
 
-                                               Label call_dispose = ig.DefineLabel ();
+                                               Label call_dispose = ec.DefineLabel ();
 
                                                if (!implements_idisposable) {
-                                                       ec.ig.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
+                                                       ec.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
                                                        LocalTemporary temp = new LocalTemporary (TypeManager.idisposable_type);
                                                        temp.Store (ec);
                                                        temp.Emit (ec);
                                                        instance = temp;
                                                }
                                                
-                                               ig.Emit (OpCodes.Brtrue_S, call_dispose);
+                                               ec.Emit (OpCodes.Brtrue_S, call_dispose);
 
                                                // using 'endfinally' to empty the evaluation stack
-                                               ig.Emit (OpCodes.Endfinally);
-                                               ig.MarkLabel (call_dispose);
+                                               ec.Emit (OpCodes.Endfinally);
+                                               ec.MarkLabel (call_dispose);
                                        }
 
                                        Invocation.EmitCall (ec, false, instance, TypeManager.void_dispose_void, null, loc);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       throw new NotSupportedException ();
-                               }
                        }
 
-                       bool ResolveLoop (EmitContext ec)
+                       bool ResolveLoop (BlockContext ec)
                        {
                                return loop.Resolve (ec);
                        }
@@ -5790,13 +5552,6 @@ namespace Mono.CSharp {
                        {
                                loop.Emit (ec);
                        }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               enumerator_type = storey.MutateType (enumerator_type);
-                               init.MutateHoistedGenericType (storey);
-                               loop.MutateHoistedGenericType (storey);
-                       }
                }
 
                Expression type;
@@ -5818,24 +5573,24 @@ namespace Mono.CSharp {
                        get { return statement; }
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
                                return false;
 
                        if (expr.IsNull) {
-                               Report.Error (186, loc, "Use of null is not valid in this context");
+                               ec.Report.Error (186, loc, "Use of null is not valid in this context");
                                return false;
                        }
 
                        if (expr.Type == TypeManager.string_type) {
                                statement = new ArrayForeach (this, 1);
-                       } else if (expr.Type.IsArray) {
-                               statement = new ArrayForeach (this, expr.Type.GetArrayRank ());
+                       } else if (expr.Type is ArrayContainer) {
+                               statement = new ArrayForeach (this, ((ArrayContainer) expr.Type).Rank);
                        } else {
                                if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethodExpression) {
-                                       Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
+                                       ec.Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
                                                expr.ExprClassName);
                                        return false;
                                }
@@ -5848,11 +5603,9 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        Label old_begin = ec.LoopBegin, old_end = ec.LoopEnd;
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
 
                        statement.Emit (ec);
 
@@ -5869,10 +5622,5 @@ namespace Mono.CSharp {
                        target.expr = expr.Clone (clonectx);
                        target.statement = statement.Clone (clonectx);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       statement.MutateHoistedGenericType (storey);
-               }
        }
 }