CS1526 error recovery
[mono.git] / mcs / mcs / statement.cs
index ef0fb06875e5cf274b9c59bca2ac46bdcfa29736..bb4a8007f7a1b358bf618457d993b7dae3669d38 100644 (file)
@@ -27,7 +27,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 +36,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 +48,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 +62,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 +81,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;
                }
 
@@ -113,82 +97,18 @@ namespace Mono.CSharp {
                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)
-               {
-                       if (variable_map == null)
-                               variable_map = new Hashtable ();
-                       
-                       if (variable_map.Contains (from))
-                               return;
-                       variable_map [from] = to;
-               }
-               
-               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;
                }
@@ -213,20 +133,18 @@ 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;
@@ -240,50 +158,44 @@ namespace Mono.CSharp {
                                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);
@@ -361,15 +273,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 +295,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){
@@ -450,21 +362,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
@@ -575,7 +487,7 @@ namespace Mono.CSharp {
                bool infinite, empty;
                
                public For (Statement init_statement,
-                           Expression test,
+                           BooleanExpression test,
                            Statement increment,
                            Statement statement,
                            Location l)
@@ -587,7 +499,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
@@ -597,7 +509,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){
@@ -734,7 +646,7 @@ namespace Mono.CSharp {
                        loc = expr.Location;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        if (expr != null && expr.eclass == ExprClass.Invalid)
                                expr = expr.ResolveStatement (ec);
@@ -768,14 +680,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,35 +711,34 @@ 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 (EmitContext.Options.InferReturnType)) {
+                       if (ec.HasSet (ResolveContext.Options.InferReturnType)) {
                                ec.ReturnTypeInference.AddCommonTypeBound (Expr.Type);
                                return true;
                        }
@@ -837,7 +748,7 @@ namespace Mono.CSharp {
 
                                if (Expr == null) {
                                        if (am != null) {
-                                               Report.Error (1662, loc,
+                                               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 ());
                                        }
@@ -882,13 +793,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)
@@ -979,7 +889,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);
@@ -1020,23 +930,25 @@ namespace Mono.CSharp {
                        // nothing to clone
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        ec.CurrentBranching.CurrentUsageVector.Goto ();
+
+                       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", ec.Report);
+                               return false;
+                       }
+
                        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.GotDefault){
-                               FlowBranchingBlock.Error_UnknownLabel (loc, "default");
-                               return;
-                       }
                        ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
                }
 
@@ -1058,10 +970,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;
                        }
 
@@ -1073,7 +985,7 @@ 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;
                        }
 
@@ -1085,7 +997,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));
 
@@ -1097,7 +1009,7 @@ namespace Mono.CSharp {
 
                        if (sl == null){
                                FlowBranchingBlock.Error_UnknownLabel (loc, "case " + 
-                                       (c.GetValue () == null ? "null" : val.ToString ()));
+                                       (c.GetValue () == null ? "null" : val.ToString ()), ec.Report);
                                return false;
                        }
 
@@ -1131,7 +1043,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 ();
@@ -1147,7 +1059,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;
                }
@@ -1187,12 +1099,11 @@ 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)
@@ -1219,12 +1130,11 @@ 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)
@@ -1342,7 +1252,7 @@ namespace Mono.CSharp {
                                ec.DefineLocalVariable (Name, builder);
                }
 
-               public bool IsThisAssigned (EmitContext ec, Block block)
+               public bool IsThisAssigned (BlockContext ec, Block block)
                {
                        if (VariableInfo == null)
                                throw new Exception ();
@@ -1350,10 +1260,10 @@ namespace Mono.CSharp {
                        if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))
                                return true;
 
-                       return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, block.StartLocation);
+                       return VariableInfo.TypeInfo.IsFullyInitialized (ec, VariableInfo, block.StartLocation);
                }
 
-               public bool IsAssigned (EmitContext ec)
+               public bool IsAssigned (BlockContext ec)
                {
                        if (VariableInfo == null)
                                throw new Exception ();
@@ -1361,7 +1271,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;
@@ -1376,12 +1286,12 @@ namespace Mono.CSharp {
                                return true;
 
                        if (VariableType.IsAbstract && VariableType.IsSealed) {
-                               FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType);
+                               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;
                }
@@ -1650,9 +1560,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);
                }
 
@@ -1676,8 +1586,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;
                                }
 
@@ -1699,7 +1609,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;
                                        }
@@ -1771,8 +1681,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;
                                }
 
@@ -1796,8 +1706,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;
                        }
 
@@ -1805,7 +1715,7 @@ 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;
                }
@@ -1814,7 +1724,7 @@ namespace Mono.CSharp {
                {
                        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 {
@@ -1847,8 +1757,8 @@ namespace Mono.CSharp {
                        if (Toplevel.GenericMethod != null) {
                                foreach (TypeParameter tp in Toplevel.GenericMethod.CurrentTypeParameters) {
                                        if (tp.Name == name) {
-                                               Report.SymbolRelatedToPreviousError (tp);
-                                               Error_AlreadyDeclaredTypeParameter (loc, name, "local variable");
+                                               Toplevel.Report.SymbolRelatedToPreviousError (tp);
+                                               Error_AlreadyDeclaredTypeParameter (Toplevel.Report, loc, name, "local variable");
                                                return null;
                                        }
                                }
@@ -1856,7 +1766,7 @@ namespace Mono.CSharp {
 
                        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;
                        }
@@ -1883,7 +1793,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);
@@ -1891,13 +1801,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)
+               public virtual void Error_AlreadyDeclaredTypeParameter (Report r, Location loc, string name, string conflict)
                {
-                       Report.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
+                       r.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
                                name, conflict);
                }
 
@@ -2018,7 +1928,7 @@ namespace Mono.CSharp {
                        anonymous_children.Add (b);
                }
 
-               void DoResolveConstants (EmitContext ec)
+               void DoResolveConstants (BlockContext ec)
                {
                        if (constants == null)
                                return;
@@ -2033,7 +1943,7 @@ namespace Mono.CSharp {
 
                                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;
                                }
@@ -2048,13 +1958,13 @@ namespace Mono.CSharp {
                                constants.Remove (name);
 
                                if (!Const.IsConstantTypeValid (variable_type)) {
-                                       Const.Error_InvalidConstantType (variable_type, loc);
+                                       Const.Error_InvalidConstantType (variable_type, loc, ec.Report);
                                        continue;
                                }
 
                                ec.CurrentBlock = this;
                                Expression e;
-                               using (ec.With (EmitContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
+                               using (ec.With (ResolveContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
                                        e = cv.Resolve (ec);
                                }
                                if (e == null)
@@ -2062,14 +1972,14 @@ namespace Mono.CSharp {
 
                                Constant ce = e as Constant;
                                if (ce == null) {
-                                       Const.Error_ExpressionMustBeConstant (vi.Location, name);
+                                       Const.Error_ExpressionMustBeConstant (vi.Location, name, ec.Report);
                                        continue;
                                }
 
                                e = ce.ConvertImplicitly (variable_type);
                                if (e == null) {
                                        if (TypeManager.IsReferenceType (variable_type))
-                                               Const.Error_ConstantCanBeInitializedWithNullOnly (variable_type, vi.Location, vi.Name);
+                                               Const.Error_ConstantCanBeInitializedWithNullOnly (variable_type, vi.Location, vi.Name, ec.Report);
                                        else
                                                ce.Error_ValueCannotBeConverted (ec, vi.Location, variable_type, false);
                                        continue;
@@ -2080,13 +1990,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.Options.UnsafeScope, ec.InUnsafe | Unsafe)) {
+                       using (ec.With (ResolveContext.Options.UnsafeScope, ec.IsUnsafe | Unsafe)) {
                                flags |= Flags.VariablesInitialized;
 
                                if (variables != null) {
@@ -2129,9 +2039,9 @@ 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) {
@@ -2142,14 +2052,14 @@ namespace Mono.CSharp {
 
                                        // 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;
 
@@ -2178,15 +2088,15 @@ 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);
@@ -2211,10 +2121,9 @@ namespace Mono.CSharp {
                        for (int ix = 0; ix < statement_count; ix++){
                                Statement s = (Statement) 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.
@@ -2224,7 +2133,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;
                                        }
 
@@ -2276,25 +2185,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);
@@ -2313,9 +2222,6 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       Block prev_block = ec.CurrentBlock;
-                       ec.CurrentBlock = this;
-
                        if (scope_initializers != null)
                                EmitScopeInitializers (ec);
 
@@ -2324,15 +2230,13 @@ namespace Mono.CSharp {
 
                        if (SymbolWriter.HasSymbolWriter)
                                EmitSymbolInfo (ec);
-
-                       ec.CurrentBlock = prev_block;
                }
 
                protected void EmitScopeInitializers (EmitContext ec)
                {
                        SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
 
-                       using (ec.Set (EmitContext.Options.OmitDebuggingInfo)) {
+                       using (ec.With (EmitContext.Options.OmitDebugInfo, true)) {
                                foreach (Statement s in scope_initializers)
                                        s.Emit (ec);
                        }
@@ -2457,7 +2361,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
@@ -2473,7 +2377,7 @@ 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;
 
                                //
@@ -2628,12 +2532,12 @@ 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)
+                       public override Expression DoResolve (ResolveContext ec)
                        {
                                if (child == null)
                                        return null;
@@ -2668,9 +2572,16 @@ namespace Mono.CSharp {
                LocalInfo this_variable;
                bool resolved;
                bool unreachable;
+               CompilerContext compiler;
 
                public HoistedVariable HoistedThisVariable;
 
+               public bool Resolved {
+                       get {
+                               return resolved;
+                       }
+               }
+
                //
                // The parameters for the block.
                //
@@ -2678,6 +2589,10 @@ namespace Mono.CSharp {
                        get { return parameters; }
                }
 
+               public Report Report {
+                       get { return compiler.Report; }
+               }
+
                public GenericMethod GenericMethod {
                        get { return generic; }
                }
@@ -2686,32 +2601,33 @@ namespace Mono.CSharp {
                        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)
+               public ToplevelBlock (CompilerContext ctx, Block parent, ParametersCompiled parameters, GenericMethod generic, Location start) :
+                       this (ctx, 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;
@@ -2723,8 +2639,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)
                {
                }
 
@@ -2790,7 +2706,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);
@@ -2877,12 +2793,12 @@ namespace Mono.CSharp {
                        set { flags = value ? flags | Flags.IsIterator : flags & ~Flags.IsIterator; }
                }
 
-               public bool IsThisAssigned (EmitContext ec)
+               public bool IsThisAssigned (BlockContext ec)
                {
                        return this_variable == null || this_variable.IsThisAssigned (ec, this);
                }
 
-               public bool Resolve (FlowBranching parent, EmitContext rc, ParametersCompiled ip, IMethodData md)
+               public bool Resolve (FlowBranching parent, BlockContext rc, ParametersCompiled ip, IMethodData md)
                {
                        if (resolved)
                                return true;
@@ -2893,7 +2809,7 @@ namespace Mono.CSharp {
                                if (!ResolveMeta (rc, ip))
                                        return false;
 
-                               using (rc.With (EmitContext.Options.DoFlowAnalysis, true)) {
+                               using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) {
                                        FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);
 
                                        if (!Resolve (rc))
@@ -2904,9 +2820,9 @@ namespace Mono.CSharp {
                        } catch (Exception) {
 #if PRODUCTION
                                if (rc.CurrentBlock != null) {
-                                       Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve");
+                                       ec.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve");
                                } else {
-                                       Report.Error (587, "Internal compiler error: Phase Resolve");
+                                       ec.Report.Error (587, "Internal compiler error: Phase Resolve");
                                }
 #endif
                                throw;
@@ -2914,10 +2830,10 @@ namespace Mono.CSharp {
 
                        if (rc.ReturnType != TypeManager.void_type && !unreachable) {
                                if (rc.CurrentAnonymousMethod == null) {
-                                       Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
+                                       rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
                                        return false;
                                } else if (!rc.CurrentAnonymousMethod.IsIterator) {
-                                       Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
+                                       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;
                                }
@@ -2926,9 +2842,9 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               bool ResolveMeta (EmitContext ec, ParametersCompiled ip)
+               bool ResolveMeta (BlockContext ec, ParametersCompiled ip)
                {
-                       int errors = Report.Errors;
+                       int errors = ec.Report.Errors;
                        int orig_count = parameters.Count;
 
                        if (ip != null)
@@ -2953,7 +2869,7 @@ namespace Mono.CSharp {
 
                        ResolveMeta (ec, offset);
 
-                       return Report.Errors == errors;
+                       return ec.Report.Errors == errors;
                }
 
                // <summary>
@@ -3115,7 +3031,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, Type required_type, bool allow_nullable)
                {       
                        Expression e = label.Resolve (ec);
 
@@ -3124,7 +3040,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;
                        }
 
@@ -3146,7 +3062,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public void Error_AlreadyOccurs (Type switch_type, SwitchLabel collision_with)
+               public void Error_AlreadyOccurs (ResolveContext ec, Type switch_type, SwitchLabel collision_with)
                {
                        string label;
                        if (converted == null)
@@ -3156,8 +3072,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)
@@ -3257,7 +3173,7 @@ 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;
 
@@ -3312,7 +3228,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;
                                }
 
@@ -3328,7 +3244,7 @@ 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 ? 
@@ -3339,7 +3255,7 @@ namespace Mono.CSharp {
                                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;
@@ -3358,7 +3274,7 @@ namespace Mono.CSharp {
                                        try {
                                                Elements.Add (key, sl);
                                        } catch (ArgumentException) {
-                                               sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)Elements [key]);
+                                               sl.Error_AlreadyOccurs (ec, SwitchType, (SwitchLabel)Elements [key]);
                                                error = true;
                                        }
                                }
@@ -3679,7 +3595,7 @@ namespace Mono.CSharp {
                        allowed_types = null;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        Expr = Expr.Resolve (ec);
                        if (Expr == null)
@@ -3696,7 +3612,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;
@@ -3706,7 +3622,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;
                        }
 
@@ -3776,7 +3692,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               void ResolveStringSwitchMap (EmitContext ec)
+               void ResolveStringSwitchMap (ResolveContext ec)
                {
                        FullNamedExpression string_dictionary_type;
                        if (TypeManager.generic_ienumerable_type != null) {
@@ -3856,11 +3772,13 @@ namespace Mono.CSharp {
 
                        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;
 
@@ -3872,7 +3790,7 @@ 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;
 
@@ -3881,7 +3799,7 @@ namespace Mono.CSharp {
                                ec.ig.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);
@@ -3986,6 +3904,7 @@ namespace Mono.CSharp {
        public abstract class ExceptionStatement : ResumableStatement
        {
                bool code_follows;
+               Iterator iter;
 
                protected abstract void EmitPreTryBody (EmitContext ec);
                protected abstract void EmitTryBody (EmitContext ec);
@@ -3999,7 +3918,7 @@ namespace Mono.CSharp {
 
                        if (resume_points != null) {
                                IntConstant.EmitInt (ig, (int) Iterator.State.Running);
-                               ig.Emit (OpCodes.Stloc, ec.CurrentIterator.CurrentPC);
+                               ig.Emit (OpCodes.Stloc, iter.CurrentPC);
                        }
 
                        ig.BeginExceptionBlock ();
@@ -4009,7 +3928,7 @@ namespace Mono.CSharp {
 
                                // 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);
+                               ig.Emit (OpCodes.Ldloc, iter.CurrentPC);
                                IntConstant.EmitInt (ig, first_resume_pc);
                                ig.Emit (OpCodes.Sub);
 
@@ -4025,7 +3944,7 @@ namespace Mono.CSharp {
 
                        Label start_finally = ec.ig.DefineLabel ();
                        if (resume_points != null) {
-                               ig.Emit (OpCodes.Ldloc, ec.CurrentIterator.SkipFinally);
+                               ig.Emit (OpCodes.Ldloc, iter.SkipFinally);
                                ig.Emit (OpCodes.Brfalse_S, start_finally);
                                ig.Emit (OpCodes.Endfinally);
                        }
@@ -4041,13 +3960,15 @@ 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;
@@ -4151,14 +4072,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;
@@ -4168,7 +4089,7 @@ 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:
@@ -4180,7 +4101,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);
+                               Type monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", Kind.Class, true);
                                TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
                                        monitor_type, "Enter", loc, TypeManager.object_type);
                                TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
@@ -4235,9 +4156,9 @@ namespace Mono.CSharp {
                        b.Unchecked = true;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
+                       using (ec.With (ResolveContext.Options.AllCheckStateFlags, false))
                                return Block.Resolve (ec);
                }
                
@@ -4269,10 +4190,10 @@ namespace Mono.CSharp {
                        b.Unchecked = false;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
-                               return Block.Resolve (ec);
+                       using (ec.With (ResolveContext.Options.AllCheckStateFlags, true))
+                               return Block.Resolve (ec);
                }
 
                protected override void DoEmit (EmitContext ec)
@@ -4304,19 +4225,18 @@ namespace Mono.CSharp {
                        loc = b.StartLocation;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        if (ec.CurrentIterator != null)
-                               Report.Error (1629, loc, "Unsafe code may not appear in iterators");
+                               ec.Report.Error (1629, loc, "Unsafe code may not appear in iterators");
 
-                       using (ec.With (EmitContext.Options.UnsafeScope, true))
+                       using (ec.Set (ResolveContext.Options.UnsafeScope))
                                return Block.Resolve (ec);
                }
                
                protected override void DoEmit (EmitContext ec)
                {
-                       using (ec.With (EmitContext.Options.UnsafeScope, true))
-                               Block.Emit (ec);
+                       Block.Emit (ec);
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -4391,7 +4311,7 @@ namespace Mono.CSharp {
                                pinned_string.Pinned = true;
                        }
 
-                       public StringEmitter Resolve (EmitContext rc)
+                       public StringEmitter Resolve (ResolveContext rc)
                        {
                                pinned_string.Resolve (rc);
 
@@ -4416,7 +4336,7 @@ namespace Mono.CSharp {
 
                                PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, 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);
                                vi.EmitAssign (ec);
@@ -4441,17 +4361,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;
                        }
@@ -4461,7 +4381,7 @@ 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;
                        }
                        
@@ -4485,11 +4405,11 @@ 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;
                                }
 
-                               using (ec.Set (EmitContext.Options.FixedInitializerScope)) {
+                               using (ec.Set (ResolveContext.Options.FixedInitializerScope)) {
                                        e = e.Resolve (ec);
                                }
 
@@ -4522,9 +4442,9 @@ namespace Mono.CSharp {
                                        //
                                        // fixed (T* e_ptr = (e == null || e.Length == 0) ? null : converted [0])
                                        //
-                                       converted = new Conditional (new Binary (Binary.Operator.LogicalOr,
+                                       converted = new Conditional (new BooleanExpression (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))),
+                                               new Binary (Binary.Operator.Equality, new MemberAccess (e, "Length"), new IntConstant (0, loc)))),
                                                        new NullPointer (loc),
                                                        converted);
 
@@ -4563,7 +4483,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);
                        }
@@ -4663,13 +4583,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
 
                                Expression source;
                                if (lvr.IsHoisted) {
@@ -4688,9 +4606,9 @@ namespace Mono.CSharp {
                        Block.Emit (ec);
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (EmitContext.Options.CatchScope, true)) {
+                       using (ec.With (ResolveContext.Options.CatchScope, true)) {
                                if (type_expr != null) {
                                        TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false);
                                        if (te == null)
@@ -4699,7 +4617,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
@@ -4749,7 +4667,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
 
@@ -4760,14 +4678,14 @@ namespace Mono.CSharp {
 
                        if (ok)
                                ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally);
-                       using (ec.With (EmitContext.Options.FinallyScope, true)) {
+                       using (ec.With (ResolveContext.Options.FinallyScope, true)) {
                                if (!fini.Resolve (ec))
                                        ok = false;
                        }
 
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
+                       ok &= base.Resolve (ec);
 
                        return ok;
                }
@@ -4812,24 +4730,18 @@ namespace Mono.CSharp {
                {
                        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) 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;
 
@@ -4859,7 +4771,7 @@ namespace Mono.CSharp {
                                Type 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;
@@ -4873,7 +4785,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'");
                                                }
                                        }
                                }
@@ -4959,7 +4871,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
@@ -4969,7 +4881,7 @@ namespace Mono.CSharp {
 
                        if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)) {
                                if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
-                                       Using.Error_IsNotConvertibleToIDisposable (expr);
+                                       Using.Error_IsNotConvertibleToIDisposable (ec, expr);
                                        return false;
                                }
                        }
@@ -4983,7 +4895,7 @@ namespace Mono.CSharp {
 
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
+                       ok &= base.Resolve (ec);
 
                        if (TypeManager.void_dispose_void == null) {
                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
@@ -5016,7 +4928,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       Expression ml = Expression.MemberLookup (
+                       Expression ml = Expression.MemberLookup (RootContext.ToplevelTypes.Compiler,
                                ec.CurrentType, TypeManager.idisposable_type, expr_type,
                                "Dispose", Location.Null);
 
@@ -5037,7 +4949,7 @@ namespace Mono.CSharp {
                        }
 
                        if (mi == null) {
-                               Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+                               RootContext.ToplevelTypes.Compiler.Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
                                return;
                        }
 
@@ -5080,11 +4992,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)
@@ -5121,7 +5033,7 @@ namespace Mono.CSharp {
                        stmt.MutateHoistedGenericType (storey);
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Resolve (BlockContext ec)
                {
                        if (!ResolveVariable (ec))
                                return false;
@@ -5132,7 +5044,7 @@ namespace Mono.CSharp {
 
                        ec.EndFlowBranching ();
 
-                       ResolveReachability (ec);
+                       ok &= base.Resolve (ec);
 
                        if (TypeManager.void_dispose_void == null) {
                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
@@ -5142,7 +5054,7 @@ namespace Mono.CSharp {
                        return ok;
                }
 
-               bool ResolveVariable (EmitContext ec)
+               bool ResolveVariable (BlockContext ec)
                {
                        assign = new SimpleAssign (var, init, loc);
                        assign = assign.ResolveStatement (ec);
@@ -5156,7 +5068,7 @@ namespace Mono.CSharp {
 
                        Expression e = Convert.ImplicitConversionStandard (ec, assign, TypeManager.idisposable_type, var.Location);
                        if (e == null) {
-                               Error_IsNotConvertibleToIDisposable (var);
+                               Error_IsNotConvertibleToIDisposable (ec, var);
                                return false;
                        }
 
@@ -5189,7 +5101,7 @@ namespace Mono.CSharp {
                                {
                                }
 
-                               public void ResolveIncrement (EmitContext ec)
+                               public void ResolveIncrement (BlockContext ec)
                                {
                                        increment = new StatementExpression (new UnaryMutator (UnaryMutator.Mode.PostIncrement, this));
                                        increment.Resolve (ec);
@@ -5234,7 +5146,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);
@@ -5390,7 +5302,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)
@@ -5453,7 +5365,7 @@ namespace Mono.CSharp {
                                throw new NotImplementedException ();
                        }
 
-                       bool GetEnumeratorFilter (EmitContext ec, MethodInfo mi)
+                       bool GetEnumeratorFilter (ResolveContext ec, MethodInfo mi)
                        {
                                Type return_type = mi.ReturnType;
 
@@ -5517,7 +5429,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;
                                        }
@@ -5538,6 +5450,9 @@ namespace Mono.CSharp {
                                        BindingFlags.Public | BindingFlags.Instance,
                                        "MoveNext", null);
 
+                               if (move_next_list == null)
+                                       return false;
+
                                foreach (MemberInfo m in move_next_list){
                                        MethodInfo mi = (MethodInfo) m;
                                
@@ -5554,9 +5469,9 @@ namespace Mono.CSharp {
                        //
                        // Retrieves a `public T get_Current ()' method from the Type `t'
                        //
-                       bool FetchGetCurrent (EmitContext ec, Type t)
+                       bool FetchGetCurrent (ResolveContext ec, Type t)
                        {
-                               PropertyExpr pe = Expression.MemberLookup (
+                               PropertyExpr pe = Expression.MemberLookup (ec.Compiler,
                                        ec.CurrentType, t, "Current", MemberTypes.Property,
                                        Expression.AllBindingFlags, loc) as PropertyExpr;
                                if (pe == null)
@@ -5566,13 +5481,13 @@ 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));
                        }
@@ -5590,9 +5505,9 @@ namespace Mono.CSharp {
                                return base_method != m;
                        }
 
-                       bool TryType (EmitContext ec, Type t)
+                       bool TryType (ResolveContext ec, Type t)
                        {
-                               MethodGroupExpr mg = Expression.MemberLookup (
+                               MethodGroupExpr mg = Expression.MemberLookup (ec.Compiler,
                                        ec.CurrentType, t, "GetEnumerator", MemberTypes.Method,
                                        Expression.AllBindingFlags, loc) as MethodGroupExpr;
                                if (mg == null)
@@ -5624,8 +5539,8 @@ namespace Mono.CSharp {
                                                                continue;
 
                                                        MethodBase mb = TypeManager.DropGenericMethodArguments (mi);
-                                                       Report.SymbolRelatedToPreviousError (t);
-                                                       Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
+                                                       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.CSharpSignature (mb));
                                                        return false;
@@ -5637,9 +5552,9 @@ namespace Mono.CSharp {
                                                            TypeManager.ImplementsInterface (result.DeclaringType, 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}'",
+                                                       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", TypeManager.CSharpSignature (result), TypeManager.CSharpSignature (mi));
                                                        return false;
                                                }
@@ -5673,18 +5588,18 @@ namespace Mono.CSharp {
                                }
 
                                return false;
-                       }               
+                       }
 
-                       bool ProbeCollectionType (EmitContext ec, Type t)
+                       bool ProbeCollectionType (ResolveContext ec, Type t)
                        {
-                               int errors = Report.Errors;
+                               int errors = ec.Report.Errors;
                                for (Type 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;
 
                                //
@@ -5699,12 +5614,12 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       public override bool Resolve (EmitContext ec)
+                       public override bool Resolve (BlockContext ec)
                        {
                                enumerator_type = TypeManager.ienumerator_type;
 
                                if (!ProbeCollectionType (ec, expr.Type)) {
-                                       Error_Enumerator ();
+                                       Error_Enumerator (ec);
                                        return false;
                                }
 
@@ -5740,7 +5655,7 @@ 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);
@@ -5771,7 +5686,7 @@ namespace Mono.CSharp {
                                        throw new NotSupportedException ();
                                }
 
-                               public override bool Resolve (EmitContext ec)
+                               public override bool Resolve (BlockContext ec)
                                {
                                        return parent.ResolveLoop (ec);
                                }
@@ -5804,7 +5719,7 @@ namespace Mono.CSharp {
                                        throw new NotSupportedException ();
                                }
 
-                               public override bool Resolve (EmitContext ec)
+                               public override bool Resolve (BlockContext ec)
                                {
                                        bool ok = true;
 
@@ -5815,7 +5730,7 @@ namespace Mono.CSharp {
 
                                        ec.EndFlowBranching ();
 
-                                       ResolveReachability (ec);
+                                       ok &= base.Resolve (ec);
 
                                        if (TypeManager.void_dispose_void == null) {
                                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
@@ -5868,7 +5783,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       bool ResolveLoop (EmitContext ec)
+                       bool ResolveLoop (BlockContext ec)
                        {
                                return loop.Resolve (ec);
                        }
@@ -5910,14 +5825,14 @@ 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;
                        }
 
@@ -5927,7 +5842,7 @@ namespace Mono.CSharp {
                                statement = new ArrayForeach (this, expr.Type.GetArrayRank ());
                        } 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;
                                }