Index: report.cs
===================================================================
--- report.cs	(revision 63019)
+++ report.cs	(working copy)
@@ -634,6 +634,10 @@
 			: base (message)
 		{
 		}
+
+		public InternalErrorException (string message, params object[] args)
+			: base (String.Format (message, args))
+		{ }
 	}
 
 	/// <summary>
Index: generic.cs
===================================================================
--- generic.cs	(revision 63019)
+++ generic.cs	(working copy)
@@ -151,11 +151,14 @@
 		}
 
 		public override string TypeParameter {
-			get {
-				return name;
-			}
+			get { return name; }
 		}
 
+		public Constraints Clone ()
+		{
+			return new Constraints (name, constraints, loc);
+		}
+
 		GenericParameterAttributes attrs;
 		TypeExpr class_constraint;
 		ArrayList iface_constraints;
@@ -739,7 +742,7 @@
 						TypeManager.CSharpName (mparam), TypeManager.CSharpSignature (mb));
 					return false;
 				}
-			} else if (DeclSpace is Iterator) {
+			} else if (DeclSpace is CompilerGeneratedClass) {
 				TypeParameter[] tparams = DeclSpace.TypeParameters;
 				Type[] types = new Type [tparams.Length];
 				for (int i = 0; i < tparams.Length; i++)
@@ -2622,7 +2625,7 @@
 
 				Argument a = (Argument) arguments [i];
 				if ((a.Expr is NullLiteral) || (a.Expr is MethodGroupExpr) ||
-				    (a.Expr is AnonymousMethod))
+				    (a.Expr is AnonymousMethodExpression))
 					continue;
 
 				arg_types [i] = a.Type;
Index: typemanager.cs
===================================================================
--- typemanager.cs	(revision 63019)
+++ typemanager.cs	(working copy)
@@ -71,6 +71,7 @@
 	static public Type asynccallback_type;
 	static public Type intptr_type;
 	static public Type monitor_type;
+	static public Type interlocked_type;
 	static public Type runtime_field_handle_type;
 	static public Type runtime_argument_handle_type;
 	static public Type attribute_type;
@@ -974,6 +975,7 @@
 		icloneable_type      = CoreLookupType ("System", "ICloneable");
 		iconvertible_type    = CoreLookupType ("System", "IConvertible");
 		monitor_type         = CoreLookupType ("System.Threading", "Monitor");
+		interlocked_type     = CoreLookupType ("System.Threading", "Interlocked");
 		intptr_type          = CoreLookupType ("System", "IntPtr");
 
 		attribute_type       = CoreLookupType ("System", "Attribute");
Index: parameter.cs
===================================================================
--- parameter.cs	(revision 63019)
+++ parameter.cs	(working copy)
@@ -212,6 +212,11 @@
 		protected Type parameter_type;
 		public readonly Location Location;
 
+		Variable var;
+		public Variable Variable {
+			get { return var; }
+		}
+
 		IResolveContext resolve_context;
 		
 		public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
@@ -335,6 +340,15 @@
 			return true;
 		}
 
+		public void ResolveVariable (EmitContext ec, int idx)
+		{
+			Report.Debug (64, "PARAMETER RESOLVE VARIABLE", ParameterType, Name, Location);
+			var = ec.GetCapturedParameter (this);
+			Report.Debug (64, "PARAMETER RESOLVE VARIABLE #1", var, ec.IsStatic, idx);
+			if (var == null)
+				var = new ParameterVariable (this, idx);
+		}
+
 		public Type ExternalType ()
 		{
 			if ((ModFlags & Parameter.Modifier.ISBYREF) != 0)
@@ -452,6 +466,78 @@
 				return attribute_targets;
 			}
 		}
+
+		protected class ParameterVariable : Variable
+		{
+			public readonly Parameter Parameter;
+			public readonly int Idx;
+			public readonly bool IsRef;
+
+			public ParameterVariable (Parameter par, int idx)
+			{
+				this.Parameter = par;
+				this.Idx = idx;
+				this.IsRef = (par.ModFlags & Parameter.Modifier.ISBYREF) != 0;
+			}
+
+			public override Type Type {
+				get { return Parameter.ParameterType; }
+			}
+
+			public override bool HasInstance {
+				get { return false; }
+			}
+
+			public override bool NeedsTemporary {
+				get { return false; }
+			}
+
+			public override void EmitInstance (EmitContext ec)
+			{
+			}
+
+			public override void Emit (EmitContext ec)
+			{
+				int arg_idx = Idx;
+				if (!ec.MethodIsStatic)
+					arg_idx++;
+
+				ParameterReference.EmitLdArg (ec.ig, arg_idx);
+			}
+
+			public override void EmitAssign (EmitContext ec)
+			{
+				int arg_idx = Idx;
+				if (!ec.MethodIsStatic)
+					arg_idx++;
+
+				if (arg_idx <= 255)
+					ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+				else
+					ec.ig.Emit (OpCodes.Starg, arg_idx);
+			}
+
+			public override void EmitAddressOf (EmitContext ec)
+			{
+				int arg_idx = Idx;
+
+				if (!ec.MethodIsStatic)
+					arg_idx++;
+
+				if (IsRef) {
+					if (arg_idx <= 255)
+						ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
+					else
+						ec.ig.Emit (OpCodes.Ldarg, arg_idx);
+				} else {
+					if (arg_idx <= 255)
+						ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+					else
+						ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+				}
+			}
+		}
+
 	}
 
 	/// <summary>
@@ -607,6 +693,14 @@
 			return ok;
 		}
 
+		public void ResolveVariable (EmitContext ec)
+		{
+			for (int i = 0; i < FixedParameters.Length; ++i) {
+				Parameter p = FixedParameters [i];
+				p.ResolveVariable (ec, i);
+			}
+		}
+
 		public CallingConventions CallingConvention
 		{
 			get {
@@ -665,7 +759,7 @@
 			}
 		}
 
-		Parameter this [int pos]
+		public Parameter this [int pos]
 		{
 			get {
 				if (pos >= count && (HasArglist || HasParams)) {
Index: rootcontext.cs
===================================================================
--- rootcontext.cs	(revision 63019)
+++ rootcontext.cs	(working copy)
@@ -377,6 +377,7 @@
 				"System.Runtime.CompilerServices.RuntimeHelpers",
 				"System.Reflection.DefaultMemberAttribute",
 				"System.Threading.Monitor",
+				"System.Threading.Interlocked",
 				
 				"System.AttributeUsageAttribute",
 				"System.Runtime.InteropServices.DllImportAttribute",
Index: ecore.cs
===================================================================
--- ecore.cs	(revision 63019)
+++ ecore.cs	(working copy)
@@ -4007,10 +4007,10 @@
 		}
 	}
 
-	
 	public class TemporaryVariable : Expression, IMemoryLocation
 	{
 		LocalInfo li;
+		Variable var;
 		
 		public TemporaryVariable (Type type, Location loc)
 		{
@@ -4028,64 +4028,46 @@
 			li = ec.CurrentBlock.AddTemporaryVariable (te, loc);
 			if (!li.Resolve (ec))
 				return null;
+
+			if (ec.MustCaptureVariable (li)) {
+				var = ec.CaptureVariable (li);
+				type = var.Type;
+			}
 			
-			AnonymousContainer am = ec.CurrentAnonymousMethod;
-			if ((am != null) && am.IsIterator)
-				ec.CaptureVariable (li);
-			
 			return this;
 		}
+
+		public Variable Variable {
+			get { return var != null ? var : li.Variable; }
+		}
 		
 		public override void Emit (EmitContext ec)
 		{
-			ILGenerator ig = ec.ig;
-			
-			if (li.FieldBuilder != null) {
-				ig.Emit (OpCodes.Ldarg_0);
-				ig.Emit (OpCodes.Ldfld, li.FieldBuilder);
-			} else {
-				ig.Emit (OpCodes.Ldloc, li.LocalBuilder);
-			}
+			Variable.EmitInstance (ec);
+			Variable.Emit (ec);
 		}
 		
 		public void EmitLoadAddress (EmitContext ec)
 		{
-			ILGenerator ig = ec.ig;
-			
-			if (li.FieldBuilder != null) {
-				ig.Emit (OpCodes.Ldarg_0);
-				ig.Emit (OpCodes.Ldflda, li.FieldBuilder);
-			} else {
-				ig.Emit (OpCodes.Ldloca, li.LocalBuilder);
-			}
+			Variable.EmitInstance (ec);
+			Variable.EmitAddressOf (ec);
 		}
 		
 		public void Store (EmitContext ec, Expression right_side)
 		{
-			if (li.FieldBuilder != null)
-				ec.ig.Emit (OpCodes.Ldarg_0);
-			
+			Variable.EmitInstance (ec);
 			right_side.Emit (ec);
-			if (li.FieldBuilder != null) {
-				ec.ig.Emit (OpCodes.Stfld, li.FieldBuilder);
-			} else {
-				ec.ig.Emit (OpCodes.Stloc, li.LocalBuilder);
-			}
+			Variable.EmitAssign (ec);
 		}
 		
 		public void EmitThis (EmitContext ec)
 		{
-			if (li.FieldBuilder != null) {
-				ec.ig.Emit (OpCodes.Ldarg_0);
-			}
+			Variable.EmitInstance (ec);
 		}
 		
-		public void EmitStore (ILGenerator ig)
+		public void EmitStore (EmitContext ec)
 		{
-			if (li.FieldBuilder != null)
-				ig.Emit (OpCodes.Stfld, li.FieldBuilder);
-			else
-				ig.Emit (OpCodes.Stloc, li.LocalBuilder);
+			Variable.EmitAssign (ec);
 		}
 		
 		public void AddressOf (EmitContext ec, AddressOp mode)
@@ -4093,5 +4075,5 @@
 			EmitLoadAddress (ec);
 		}
 	}
-	
+
 }	
Index: class.cs
===================================================================
--- class.cs	(revision 63019)
+++ class.cs	(working copy)
@@ -429,8 +429,8 @@
 		// Holds the operators
 		MemberCoreArrayList operators;
 
-		// Holds the iterators
-		ArrayList iterators;
+		// Holds the compiler generated classes
+		ArrayList compiler_generated;
 
 		//
 		// Pointers to the default constructor and the default static constructor
@@ -772,12 +772,14 @@
 			operators.Add (op);
 		}
 
-		public void AddIterator (Iterator i)
+		public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
 		{
-			if (iterators == null)
-				iterators = new ArrayList ();
+			Report.Debug (64, "ADD COMPILER GENERATED CLASS", this, c);
 
-			iterators.Add (i);
+			if (compiler_generated == null)
+				compiler_generated = new ArrayList ();
+
+			compiler_generated.Add (c);
 		}
 
 		public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
@@ -822,9 +824,9 @@
 			}
 		}
 
-		public ArrayList Iterators {
+		public ArrayList CompilerGenerated {
 			get {
-				return iterators;
+				return compiler_generated;
 			}
 		}
 
@@ -1202,7 +1204,7 @@
 			// Let's do it as soon as possible, since code below can call DefineType() on classes
 			// that depend on us to be populated before they are.
 			//
-			if (!(this is Iterator))
+			if (!(this is Iterator) && !(this is CompilerGeneratedClass))
 				RootContext.RegisterOrder (this); 
 
 			if (base_type != null) {
@@ -1329,6 +1331,20 @@
 
 		public bool ResolveType ()
 		{
+			if (!DoResolveType ())
+				return false;
+
+			if (compiler_generated != null) {
+				foreach (CompilerGeneratedClass c in compiler_generated)
+					if (!c.ResolveType ())
+						return false;
+			}
+
+			return true;
+		}
+
+		protected virtual bool DoResolveType ()
+		{
 			if ((base_type != null) &&
 			    (base_type.ResolveAsTypeTerminal (this, false) == null)) {
 				error = true;
@@ -1413,6 +1429,13 @@
 						return false;
 			}
 
+			if (compiler_generated != null) {
+				foreach (CompilerGeneratedClass c in compiler_generated) {
+					if (c.DefineType () == null)
+						return false;
+				}
+			}
+
 			return true;
 		}
 
@@ -1541,18 +1564,7 @@
 					part.member_cache = member_cache;
 			}
 #endif
-			if (iterators != null) {
-				foreach (Iterator iterator in iterators) {
-					if (iterator.DefineType () == null)
-						return false;
-				}
 
-				foreach (Iterator iterator in iterators) {
-					if (!iterator.DefineMembers ())
-						return false;
-				}
-			}
-
 			return true;
 		}
 
@@ -1564,9 +1576,9 @@
 
 		public override bool Define ()
 		{
-			if (iterators != null) {
-				foreach (Iterator iterator in iterators) {
-					if (!iterator.Define ())
+			if (compiler_generated != null) {
+				foreach (CompilerGeneratedClass c in compiler_generated) {
+					if (!c.Define ())
 						return false;
 				}
 			}
@@ -2239,7 +2251,7 @@
 
 			if (default_static_constructor != null)
 				default_static_constructor.Emit ();
-			
+
 			if (methods != null){
 				foreach (Method m in methods)
 					m.Emit ();
@@ -2282,9 +2294,14 @@
 				if (pending.VerifyPendingMethods ())
 					return;
 
-			if (iterators != null)
-				foreach (Iterator iterator in iterators)
-					iterator.EmitType ();
+			if (compiler_generated != null) {
+				foreach (CompilerGeneratedClass c in compiler_generated) {
+					if (!c.DefineMembers ())
+						throw new InternalErrorException ();
+				}
+				foreach (CompilerGeneratedClass c in compiler_generated)
+					c.EmitType ();
+			}
 		}
 		
 		public override void CloseType ()
@@ -2324,9 +2341,9 @@
 				foreach (Delegate d in Delegates)
 					d.CloseType ();
 
-			if (Iterators != null)
-				foreach (Iterator i in Iterators)
-					i.CloseType ();
+			if (CompilerGenerated != null)
+				foreach (CompilerGeneratedClass c in CompilerGenerated)
+					c.CloseType ();
 			
 			types = null;
 			properties = null;
@@ -2341,7 +2358,7 @@
 			events = null;
 			indexers = null;
 			operators = null;
-			iterators = null;
+			compiler_generated = null;
 			default_constructor = null;
 			default_static_constructor = null;
 			type_bases = null;
@@ -3702,16 +3719,10 @@
 			}
 		}
 
-		public EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
+		public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
 		{
-			EmitContext ec = new EmitContext (this,
-				tc, this.ds, Location, ig, MemberType, ModFlags, false);
-
-			Iterator iterator = tc as Iterator;
-			if (iterator != null)
-				ec.CurrentAnonymousMethod = iterator.Host;
-
-			return ec;
+			return new EmitContext (
+				this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
 		}
 
 		public override bool Define ()
@@ -3821,6 +3832,10 @@
 			}
 		}
 
+		public abstract Iterator Iterator {
+			get;
+		}
+
 		public new Location Location {
 			get {
 				return base.Location;
@@ -3981,6 +3996,12 @@
 			Modifiers.METHOD_YIELDS | 
 			Modifiers.EXTERN;
 
+		Iterator iterator;
+
+		public override Iterator Iterator {
+			get { return iterator; }
+		}
+
 		const int AllowedInterfaceModifiers =
 			Modifiers.NEW | Modifiers.UNSAFE;
 
@@ -4118,6 +4139,8 @@
 		//
 		public override bool Define ()
 		{
+			Report.Debug (64, "METHOD DEFINE", this, Name);
+
 			if (!base.Define ())
 				return false;
 
@@ -4135,11 +4158,11 @@
 			// Setup iterator if we are one
 			//
 			if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
-				Iterator iterator = new Iterator (
-					this, Parent, GenericMethod, ModFlags);
+				iterator = Iterator.CreateIterator (
+					this, (TypeContainer) Parent, GenericMethod, ModFlags);
 
-				if (!iterator.DefineIterator ())
-					return false;
+				if (iterator == null)
+					throw new InternalErrorException ();
 			}
 
 			//
@@ -4179,6 +4202,7 @@
 		// 
 		public override void Emit ()
 		{
+			Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
 			MethodData.Emit (Parent);
 			base.Emit ();
 
@@ -4360,6 +4384,10 @@
 
 		static string[] attribute_targets = new string [] { "method" };
 
+		public Iterator Iterator {
+			get { return null; }
+		}
+
 		bool has_compliant_args = false;
 		//
 		// The spec claims that static is not permitted, but
@@ -4710,6 +4738,8 @@
 		GenericMethod GenericMethod { get; }
 		Parameters ParameterInfo { get; }
 
+		Iterator Iterator { get; }
+
 		Attributes OptAttributes { get; }
 		ToplevelBlock Block { get; set; }
 
@@ -5032,6 +5062,20 @@
 			
 			SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
 
+			Report.Debug (64, "METHOD DATA EMIT", this, MethodBuilder,
+				      method, method.Iterator, block);
+
+#if FIXME
+			if (method.Iterator != null) {
+				if (!method.Iterator.Resolve (ec))
+					throw new InternalErrorException ();
+				// method.Iterator.EmitMethod (ec);
+			}
+#endif
+
+			Report.Debug (64, "METHOD DATA EMIT #1", this, MethodBuilder,
+				      method, method.Iterator, block);
+
 			//
 			// Handle destructors specially
 			//
@@ -5934,6 +5978,10 @@
 
 		#region IMethodData Members
 
+		public Iterator Iterator {
+			get { return null; }
+		}
+
 		public ToplevelBlock Block {
 			get {
 				return block;
@@ -6285,9 +6333,10 @@
 				// Setup iterator if we are one
 				//
 				if (yields) {
-					Iterator iterator = new Iterator (this, Parent as TypeContainer, null, ModFlags);
-					
-					if (!iterator.DefineIterator ())
+					Iterator iterator = Iterator.CreateIterator (
+						this, (TypeContainer) Parent, null, ModFlags);
+
+					if (iterator == null)
 						return null;
 				}
 
@@ -7323,10 +7372,10 @@
 				// Setup iterator if we are one
 				//
 				if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
-					Iterator iterator = new Iterator (
-						Get, Parent, null, ModFlags);
+					Iterator iterator = Iterator.CreateIterator (
+						Get, (TypeContainer) Parent, null, ModFlags);
 
-					if (!iterator.DefineIterator ())
+					if (iterator == null)
 						return false;
 				}
 			}
@@ -7444,6 +7493,10 @@
 			Block = block;
 		}
 
+		public override Iterator Iterator {
+			get { return null; }
+		}
+
 		public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
 		{
 			if (a.Type == TypeManager.conditional_attribute_type) {
Index: decl.cs
===================================================================
--- decl.cs	(revision 63019)
+++ decl.cs	(working copy)
@@ -525,6 +525,7 @@
 				caching_flags |= Flags.ClsCompliantAttributeTrue;
 				return true;
 			}
+
 			return false;
 		}
 
Index: delegate.cs
===================================================================
--- delegate.cs	(revision 63019)
+++ delegate.cs	(working copy)
@@ -816,8 +816,8 @@
 			
 			Expression e = a.Expr;
 
-			if (e is AnonymousMethod && RootContext.Version != LanguageVersion.ISO_1)
-				return ((AnonymousMethod) e).Compatible (ec, type);
+			if (e is AnonymousMethodExpression && RootContext.Version != LanguageVersion.ISO_1)
+				return ((AnonymousMethodExpression) e).Compatible (ec, type);
 
 			MethodGroupExpr mg = e as MethodGroupExpr;
 			if (mg != null)
Index: iterators.cs
===================================================================
--- iterators.cs	(revision 63019)
+++ iterators.cs	(working copy)
@@ -71,16 +71,19 @@
 		
 		public override bool Resolve (EmitContext ec)
 		{
+			Report.Debug (64, "RESOLVE YIELD", this, ec, expr, expr.GetType ());
 			expr = expr.Resolve (ec);
 			if (expr == null)
 				return false;
 
+			Report.Debug (64, "RESOLVE YIELD #1", this, ec, expr, expr.GetType (),
+				      ec.CurrentAnonymousMethod, ec.CurrentIterator);
+
 			if (!CheckContext (ec, loc, false))
 				return false;
 
 			Iterator iterator = ec.CurrentIterator;
-
-			if (expr.Type != iterator.IteratorType){
+			if (expr.Type != iterator.IteratorType) {
 				expr = Convert.ImplicitConversionRequired (
 					ec, expr, iterator.IteratorType, loc);
 				if (expr == null)
@@ -119,13 +122,512 @@
 		}
 	}
 
-	public class Iterator : Class {
-		protected ToplevelBlock original_block;
+	public class IteratorHost : AnonymousMethodHost
+	{
+		public readonly Iterator Iterator;
+
+		TypeExpr iterator_type_expr;
+		Field pc_field;
+		Field current_field;
+		Method dispose;
+		MethodInfo dispose_method;
+
+		TypeExpr enumerator_type;
+		TypeExpr enumerable_type;
+		TypeExpr generic_enumerator_type;
+		TypeExpr generic_enumerable_type;
+		TypeArguments generic_args;
+
+		public IteratorHost (Iterator iterator)
+			: base (iterator.Block.CaptureContext, iterator.Block,
+				iterator.Host, iterator.GenericMethod)
+		{
+			this.Iterator = iterator;
+		}
+
+		public MethodInfo Dispose {
+			get { return dispose_method; }
+		}
+
+		public Field PC {
+			get { return pc_field; }
+		}
+
+		public Field CurrentField {
+			get { return current_field; }
+		}
+
+		public Type IteratorType {
+			get { return iterator_type_expr.Type; }
+		}
+
+		public override TypeExpr [] GetClassBases (out TypeExpr base_class)
+		{
+			iterator_type_expr = InflateType (Iterator.OriginalIteratorType);
+
+			generic_args = new TypeArguments (Location);
+			generic_args.Add (iterator_type_expr);
+
+			ArrayList list = new ArrayList ();
+			if (Iterator.IsEnumerable) {
+				enumerable_type = new TypeExpression (
+					TypeManager.ienumerable_type, Location);
+				list.Add (enumerable_type);
+
+				generic_enumerable_type = new ConstructedType (
+					TypeManager.generic_ienumerable_type,
+					generic_args, Location);
+				list.Add (generic_enumerable_type);
+			}
+
+			enumerator_type = new TypeExpression (
+				TypeManager.ienumerator_type, Location);
+			list.Add (enumerator_type);
+
+			list.Add (new TypeExpression (TypeManager.idisposable_type, Location));
+
+			generic_enumerator_type = new ConstructedType (
+				TypeManager.generic_ienumerator_type,
+				generic_args, Location);
+			list.Add (generic_enumerator_type);
+
+			Bases = list;
+
+			return base.GetClassBases (out base_class);
+		}
+
+		protected override bool DoDefineMembers ()
+		{
+			pc_field = CaptureVariable ("$PC", TypeManager.int32_type);
+			current_field = CaptureVariable ("$current", Iterator.OriginalIteratorType);
+
+			Define_Current (true);
+			Define_Current (false);
+			Define_Dispose ();
+			Define_Reset ();
+
+			if (Iterator.IsEnumerable) {
+				Define_GetEnumerator (false);
+				Define_GetEnumerator (true);
+			}
+
+			if (!base.DoDefineMembers ())
+				return false;
+
+			FetchMethodDispose ();
+			return true;
+		}
+
+		protected override void EmitScopeConstructor (EmitContext ec)
+		{
+			ec.ig.Emit (OpCodes.Ldarg_0);
+			ec.ig.Emit (OpCodes.Ldarg_1);
+			ec.ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+			base.EmitScopeConstructor (ec);
+		}
+
+		void FetchMethodDispose ()
+		{
+			MemberList dispose_list;
+
+			dispose_list = FindMembers (
+				CurrentType != null ? CurrentType : TypeBuilder,
+				MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance,
+				Type.FilterName, "Dispose");
+
+			if (dispose_list.Count != 1)
+				throw new InternalErrorException ("Cannot find Dipose() method.");
+
+			dispose_method = (MethodInfo) dispose_list [0];
+		}
+
+		void Define_Current (bool is_generic)
+		{
+			MemberName left;
+			Expression type;
+
+			if (is_generic) {
+				left = new MemberName (
+					"System.Collections.Generic.IEnumerator",
+					generic_args, Location);
+				type = iterator_type_expr;
+			} else {
+				left = new MemberName ("System.Collections.IEnumerator", Location);
+				type = TypeManager.system_object_expr;
+			}
+
+			MemberName name = new MemberName (left, "Current", null, Location);
+
+			ToplevelBlock get_block = new ToplevelBlock (Location);
+			get_block.AddStatement (new CurrentBlock (this, is_generic));
+
+			Accessor getter = new Accessor (get_block, 0, null, Location);
+
+			Property current = new Property (
+				this, type, 0, false, name, null, getter, null);
+			AddProperty (current);
+		}
+
+		void Define_GetEnumerator (bool is_generic)
+		{
+			MemberName left;
+			Expression type;
+			if (is_generic) {
+				left = new MemberName (
+					"System.Collections.Generic.IEnumerable",
+					generic_args, Location);
+				type = generic_enumerator_type;
+			} else {
+				left = new MemberName ("System.Collections.IEnumerable", Location);
+				type = enumerator_type;
+			}
+
+			MemberName name = new MemberName (left, "GetEnumerator", Location);
+
+			Method get_enumerator = new Method (
+				this, null, type, 0, false, name,
+				Parameters.EmptyReadOnlyParameters, null);
+
+			AddMethod (get_enumerator);
+			get_enumerator.Block = new ToplevelBlock (Location);
+			get_enumerator.Block.AddStatement (new GetEnumeratorBlock (this, type, is_generic));
+
+
+#if FIXME
+			Expression ce = new MemberAccess (
+				new SimpleName ("System.Threading.Interlocked", Location),
+				"CompareExchange");
+
+			Expression pc = new FieldExpression (this, pc_field);
+			Expression before = new IntLiteral ((int) State.Running, Location);
+			Expression uninitialized = new IntLiteral ((int) State.Uninitialized, Location);
+
+			ArrayList args = new ArrayList ();
+			args.Add (new Argument (pc, Argument.AType.Ref));
+			args.Add (new Argument (before, Argument.AType.Expression));
+			args.Add (new Argument (uninitialized, Argument.AType.Expression));
+
+			get_enumerator.Block.AddStatement (new If (
+				new Binary (
+					Binary.Operator.Equality,
+					new Invocation (ce, args),
+					uninitialized),
+				new Return (new ThisParameterReference (type.Type, Location),
+					    Location),
+				Location));
+
+			args = new ArrayList ();
+			if (!IsStatic) {
+				args.Add (new Argument (new CapturedThisReference (this, Location)));
+			}
+
+			args.Add (new Argument (new BoolLiteral (true, Location)));
+
+			for (int i = 0; i < parameters.Count; i++) {
+				Expression cp = new CapturedParameterReference (
+					this, parameters.ParameterType (i),
+					parameters.ParameterName (i), Location);
+				args.Add (new Argument (cp));
+			}
+
+			Expression new_expr = new New (current_type, args, Location);
+			get_enumerator.Block.AddStatement (new Return (new_expr, Location));
+#endif
+		}
+
+		void Define_Dispose ()
+		{
+#if FIXME
+			dispose = new Method (
+				this, null, TypeManager.system_void_expr, Modifiers.PUBLIC,
+				false, new MemberName ("Dispose", Location),
+				Parameters.EmptyReadOnlyParameters, null);
+			AddMethod (dispose);
+#else
+			dispose = new DisposeMethod (this);
+#endif
+
+#if FIXME
+			dispose.Block = new ToplevelBlock (null, Location);
+			dispose.Block.SetHaveAnonymousMethods (Location, Iterator);
+			dispose.Block.AddStatement (new DisposeMethod (Iterator, Location));
+#endif
+		}
+
+		void Define_Reset ()
+		{
+			Method reset = new Method (
+				this, null, TypeManager.system_void_expr, Modifiers.PUBLIC,
+				false, new MemberName ("Reset", Location),
+				Parameters.EmptyReadOnlyParameters, null);
+			AddMethod (reset);
+
+			reset.Block = new ToplevelBlock (Location);
+			reset.Block.AddStatement (Create_ThrowNotSupported ());
+		}
+
+		Statement Create_ThrowNotSupported ()
+		{
+			TypeExpr ex_type = new TypeExpression (
+				TypeManager.not_supported_exception_type, Location);
+
+			return new Throw (new New (ex_type, null, Location), Location);
+		}
+
+		ConstructorInfo GetInvalidOperationException ()
+		{
+			MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookup (
+				TypeBuilder, TypeManager.invalid_operation_exception_type,
+				".ctor", Location);
+			if (mg == null)
+				throw new InternalErrorException ();
+			return (ConstructorInfo) mg.Methods [0];
+		}
+
+		MethodInfo GetCompareExchange ()
+		{
+			MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookup (
+				TypeBuilder, TypeManager.interlocked_type,
+				"CompareExchange", Location);
+			if (mg == null)
+				throw new InternalErrorException ();
+			return (MethodInfo) mg.Methods [0];
+		}
+
+		protected override ScopeInitializerBase CreateScopeInitializer ()
+		{
+			return new IteratorHostInitializer (this);
+		}
+
+		protected class IteratorHostInitializer : AnonymousMethodHostInitializer
+		{
+			new public readonly IteratorHost Host;
+			protected Iterator.State state;
+
+			public IteratorHostInitializer (IteratorHost host)
+				: base (host)
+			{
+				this.Host = host;
+			}
+
+			protected override bool DoResolveInternal (EmitContext ec)
+			{
+				if (this is EnumeratorScopeInitializer)
+					state = Iterator.State.Running;
+				else if (Host.Iterator.IsEnumerable)
+					state = Iterator.State.Uninitialized;
+				else
+					state = Iterator.State.Running;
+
+				return base.DoResolveInternal (ec);
+			}
+
+			protected override void EmitScopeConstructor (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldc_I4, (int) state);
+				base.EmitScopeConstructor (ec);
+			}
+		}
+
+		protected class DisposeMethod : Method
+		{
+			public IteratorHost Host;
+
+			public DisposeMethod (IteratorHost host)
+				: base (host, null, TypeManager.system_void_expr, Modifiers.PUBLIC,
+					false, new MemberName ("Dispose", host.Location),
+					Parameters.EmptyReadOnlyParameters, null)
+			{
+				this.Host = host;
+
+				host.AddMethod (this);
+
+				Block = new ToplevelBlock (host.Iterator.Container, null, Location);
+				// Block.SetHaveAnonymousMethods (Location, Host.Iterator);
+
+				// Block = Host.Iterator.DisposeBlock;
+
+				// Block = new ToplevelBlock (Location);
+				// Block.SetHaveAnonymousMethods (Location, Host.Iterator);
+
+				Block.AddStatement (new DisposeMethodStatement (Host.Iterator));
+
+				Report.Debug (64, "DISPOSE METHOD", host, Block);
+			}
+
+			public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
+			{
+				EmitContext ec = new EmitContext (
+					this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
+
+				ec.capture_context = Host.Iterator.Block.CaptureContext;
+				ec.CurrentAnonymousMethod = Host.Iterator;
+				return ec;
+			}
+
+			protected class DisposeMethodStatement : Statement
+			{
+				Iterator iterator;
+
+				public DisposeMethodStatement (Iterator iterator)
+				{
+					this.iterator = iterator;
+					this.loc = iterator.Location;
+				}
+
+				public override bool Resolve (EmitContext ec)
+				{
+					return true;
+				}
+
+				protected override void DoEmit (EmitContext ec)
+				{
+					iterator.EmitDispose (ec);
+				}
+			}
+		}
+
+		protected ScopeInitializer GetEnumeratorInitializer (EmitContext ec)
+		{
+			ScopeInitializer init = new EnumeratorScopeInitializer (this);
+			if (init.Resolve (ec) == null)
+				throw new InternalErrorException ();
+			return init;
+		}
+
+		protected class EnumeratorScopeInitializer : IteratorHostInitializer
+		{
+			IteratorHost host;
+			ExpressionStatement initializer;
+
+			public EnumeratorScopeInitializer (IteratorHost host)
+				: base (host)
+			{
+				this.host = host;
+			}
+
+			protected override bool DoResolveInternal (EmitContext ec)
+			{
+				initializer = host.GetScopeInitializer (ec);
+				type = host.IsGeneric ? host.CurrentType : host.TypeBuilder;
+				return base.DoResolveInternal (ec);
+			}
+
+			protected override void EmitParameterReference (EmitContext ec,
+									CapturedParameter cp)
+			{
+				Report.Debug (64, "EMIT THE PARAM", this, cp, host,
+					      initializer, host.CaptureContext.captured_parameters);
+				ec.ig.Emit (OpCodes.Ldarg_0);
+				ec.ig.Emit (OpCodes.Ldfld, cp.Field.FieldBuilder);
+			}
+		}
+
+		protected class CurrentBlock : Statement {
+			IteratorHost host;
+			bool is_generic;
+
+			public CurrentBlock (IteratorHost host, bool is_generic)
+			{
+				this.host = host;
+				this.is_generic = is_generic;
+				loc = host.Location;
+			}
+
+			public override bool Resolve (EmitContext ec)
+			{
+				ec.CurrentBranching.CurrentUsageVector.Return ();
+				return true;
+			}
+
+			protected override void DoEmit (EmitContext ec)
+			{
+				ILGenerator ig = ec.ig;
+				Label label_ok = ig.DefineLabel ();
+
+				ig.Emit (OpCodes.Ldarg_0);
+				ig.Emit (OpCodes.Ldfld, host.PC.FieldBuilder);
+				ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Running);
+				ig.Emit (OpCodes.Bgt, label_ok);
+
+				ig.Emit (OpCodes.Newobj, host.GetInvalidOperationException ());
+				ig.Emit (OpCodes.Throw);
+
+				ig.MarkLabel (label_ok);
+				ig.Emit (OpCodes.Ldarg_0);
+				ig.Emit (OpCodes.Ldfld, host.CurrentField.FieldBuilder);
+				if (!is_generic)
+					ig.Emit (OpCodes.Box, host.CurrentField.MemberType);
+				ig.Emit (OpCodes.Ret);
+			}
+		}
+
+		protected class GetEnumeratorBlock : Statement {
+			IteratorHost host;
+			Expression type;
+			bool is_generic;
+
+			Expression initializer, cast;
+			MethodInfo ce;
+
+			public GetEnumeratorBlock (IteratorHost host, Expression type,
+						   bool is_generic)
+			{
+				this.host = host;
+				this.type = type;
+				this.is_generic = is_generic;
+				loc = host.Location;
+			}
+
+			public override bool Resolve (EmitContext ec)
+			{
+				type = type.ResolveAsTypeTerminal (ec, false);
+				if ((type == null) || (type.Type == null))
+					return false;
+
+				initializer = host.GetEnumeratorInitializer (ec);
+				if (initializer == null)
+					return false;
+
+				cast = new ClassCast (initializer, type.Type);
+
+				ce = host.GetCompareExchange ();
+
+				ec.CurrentBranching.CurrentUsageVector.Return ();
+				return true;
+			}
+
+			protected override void DoEmit (EmitContext ec)
+			{
+				ILGenerator ig = ec.ig;
+				Label label_init = ig.DefineLabel ();
+
+				ig.Emit (OpCodes.Ldarg_0);
+				ig.Emit (OpCodes.Ldflda, host.PC.FieldBuilder);
+				ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Running);
+				ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Uninitialized);
+				ig.Emit (OpCodes.Call, ce);
+
+				ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Uninitialized);
+				ig.Emit (OpCodes.Bne_Un, label_init);
+
+				ig.Emit (OpCodes.Ldarg_0);
+				ig.Emit (OpCodes.Ret);
+
+				ig.MarkLabel (label_init);
+
+				cast.Emit (ec);
+				ig.Emit (OpCodes.Ret);
+			}
+		}
+	}
+
+	public class Iterator : AnonymousContainer {
+		protected readonly ToplevelBlock OriginalBlock;
+		protected readonly IMethodData OriginalMethod;
 		protected ToplevelBlock block;
 
-		Type original_iterator_type;
-		TypeExpr iterator_type_expr;
-		bool is_enumerable;
+		public readonly bool IsEnumerable;
 		public readonly bool IsStatic;
 
 		//
@@ -139,7 +641,6 @@
 		// Context from the original method
 		//
 		GenericMethod generic_method;
-		TypeContainer container;
 		TypeExpr current_type;
 		Type this_type;
 		Parameters parameters;
@@ -147,7 +648,7 @@
 		IMethodData orig_method;
 
 		MethodInfo dispose_method;
-		MoveNextMethod move_next_method;
+		Method move_next_method;
 		Constructor ctor;
 		CaptureContext cc;
 
@@ -156,25 +657,25 @@
 		Expression generic_enumerator_type;
 		Expression generic_enumerable_type;
 		TypeArguments generic_args;
-		EmitContext ec;
 
-		protected enum State {
+		public readonly Type OriginalIteratorType;
+		public readonly IteratorHost IteratorHost;
+
+		public enum State {
 			Uninitialized	= -2,
 			After,
 			Running
 		}
 
-		static int proxy_count;
-
 		public void EmitYieldBreak (ILGenerator ig)
 		{
 			ig.Emit (OpCodes.Ldarg_0);
 			IntConstant.EmitInt (ig, (int) State.After);
-			ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+			ig.Emit (OpCodes.Stfld, IteratorHost.PC.FieldBuilder);
 			ig.Emit (OpCodes.Br, move_next_error);
 		}
 
-		public void EmitMoveNext (EmitContext ec)
+		internal void EmitMoveNext (EmitContext ec, Block original_block)
 		{
 			ILGenerator ig = ec.ig;
 
@@ -192,7 +693,7 @@
 			resume_points.Add (entry_point);
 			entry_point.Define (ig);
 
-			ec.EmitTopBlock (orig_method, original_block);
+			original_block.Emit (ec);
 
 			EmitYieldBreak (ig);
 
@@ -203,7 +704,7 @@
 				labels [i] = ((ResumePoint) resume_points [i]).Label;
 
 			ig.Emit (OpCodes.Ldarg_0);
-			ig.Emit (OpCodes.Ldfld, pc_field.FieldBuilder);
+			ig.Emit (OpCodes.Ldfld, IteratorHost.PC.FieldBuilder);
 			ig.Emit (OpCodes.Switch, labels);
 
 			Label end = ig.DefineLabel ();
@@ -221,7 +722,7 @@
 			ig.BeginFaultBlock ();
 
 			ig.Emit (OpCodes.Ldarg_0);
-			ig.Emit (OpCodes.Callvirt, dispose_method);
+			ig.Emit (OpCodes.Callvirt, IteratorHost.Dispose);
 
 			ig.EndExceptionBlock ();
 
@@ -264,12 +765,12 @@
 
 			ig.MarkLabel (dispatcher);
 			ig.Emit (OpCodes.Ldarg_0);
-			ig.Emit (OpCodes.Ldfld, pc_field.FieldBuilder);
+			ig.Emit (OpCodes.Ldfld, IteratorHost.PC.FieldBuilder);
 			ig.Emit (OpCodes.Switch, labels);
 
 			ig.Emit (OpCodes.Ldarg_0);
 			IntConstant.EmitInt (ig, (int) State.After);
-			ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+			ig.Emit (OpCodes.Stfld, IteratorHost.PC.FieldBuilder);
 
 			ig.MarkLabel (end);
 		}
@@ -305,13 +806,13 @@
 			// Store the new current
 			ig.Emit (OpCodes.Ldarg_0);
 			expr.Emit (ec);
-			ig.Emit (OpCodes.Stfld, current_field.FieldBuilder);
+			ig.Emit (OpCodes.Stfld, IteratorHost.CurrentField.FieldBuilder);
 
 			// increment pc
 			pc++;
 			ig.Emit (OpCodes.Ldarg_0);
 			IntConstant.EmitInt (ig, pc);
-			ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+			ig.Emit (OpCodes.Stfld, IteratorHost.PC.FieldBuilder);
 
 			// Return ok
 			ig.Emit (OpCodes.Br, move_next_ok);
@@ -329,75 +830,103 @@
 			pc++;
 			ig.Emit (OpCodes.Ldarg_0);
 			IntConstant.EmitInt (ig, pc);
-			ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+			ig.Emit (OpCodes.Stfld, IteratorHost.PC.FieldBuilder);
 
 			ResumePoint point = new ResumePoint (finally_blocks);
 			resume_points.Add (point);
 			point.Define (ig);
 		}
 
-		private static MemberName MakeProxyName (string name, GenericMethod generic, Location loc)
-		{
-			int pos = name.LastIndexOf ('.');
-			if (pos > 0)
-				name = name.Substring (pos + 1);
+		public override bool IsIterator {
+			get { return true; }
+		}
 
-			string proxy_name = "<" + name + ">__" + (proxy_count++);
-
-			if (generic != null) {
-				TypeArguments args = new TypeArguments (loc);
-				foreach (TypeParameter tparam in generic.CurrentTypeParameters)
-					args.Add (new SimpleName (tparam.Name, loc));
-				return new MemberName (proxy_name, args, loc);
-			} else
-				return new MemberName (proxy_name, loc);
+		public override AnonymousMethodHost RootScope {
+			get { return IteratorHost; }
 		}
 
+		ToplevelBlock TheBlock;
+		// public ToplevelBlock DisposeBlock;
+
 		//
 		// Our constructor
 		//
-		public Iterator (IMethodData m_container, DeclSpace parent, GenericMethod generic,
-				 int modifiers)
-			: base (parent.NamespaceEntry, parent,
-				MakeProxyName (m_container.MethodName.Name, generic, m_container.Location),
-				(modifiers & Modifiers.UNSAFE) | Modifiers.PRIVATE, null)
+		public Iterator (IMethodData m_container, TypeContainer host, GenericMethod generic,
+				 ToplevelBlock container, ToplevelBlock block, int modifiers,
+				 Type iterator_type, bool is_enumerable)
+			: base (null, host, generic, m_container.ParameterInfo,
+				block, m_container.Block, TypeManager.bool_type, modifiers,
+				m_container.Location)
 		{
-			this.orig_method = m_container;
+			this.OriginalBlock = m_container.Block;
+			this.OriginalMethod = m_container;
+			this.OriginalIteratorType = iterator_type;
+			this.IsEnumerable = is_enumerable;
+			this.TheBlock = block;
 
-			this.generic_method = generic;
-			this.container = ((TypeContainer) parent).PartialContainer;
-			this.original_parameters = m_container.ParameterInfo;
-			this.original_block = orig_method.Block;
-			this.block = new ToplevelBlock (orig_method.Block, parameters, orig_method.Location);
+			// Block.ReParent (Container);
 
-			if (generic != null) {
-				ArrayList constraints = new ArrayList ();
-				foreach (TypeParameter tparam in generic.TypeParameters)
-					constraints.Add (tparam.Constraints);
+			// Container.SetHaveAnonymousMethods (Location, this);
+			Block.SetHaveAnonymousMethods (Location, this);
 
-				SetParameterInfo (constraints);
+			// DisposeBlock = new ToplevelBlock (Block, null, Location);
+			// DisposeBlock.SetHaveAnonymousMethods (Location, this);
+
+			// OriginalBlock.ReParent (Block);
+			// OriginalBlock.SetHaveAnonymousMethods (Location, this);
+
+			Report.Debug (64, "NEW ITERATOR", host, generic, OriginalBlock,
+				      Container, Block, block);
+
+			IteratorHost = new IteratorHost (this);
+			Block.CreateIteratorHost (IteratorHost);
+
+			OriginalBlock.ReParent (Container);
+
+			m_container.Block = TheBlock;
+			// block.AddStatement (new TestStatement ());
+
+			OriginalBlock.MakeIterator (this);
+
+			// MoveNextStatement inline = new MoveNextStatement (this, Location);
+			// Container.AddStatement (inline);
+		}
+
+		protected class TestStatement : Statement
+		{
+			public override bool Resolve (EmitContext ec)
+			{
+				return true;
 			}
 
-			IsStatic = (modifiers & Modifiers.STATIC) != 0;
+			protected override void DoEmit (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Nop);
+				ec.ig.Emit (OpCodes.Neg);
+				ec.ig.Emit (OpCodes.Pop);
+				ec.ig.Emit (OpCodes.Ret);
+			}
 		}
 
-		public AnonymousContainer Host {
-			get { return move_next_method; }
+		protected override CaptureContext ContainerCaptureContext {
+			get { return OriginalBlock.CaptureContext; }
 		}
 
-		public bool DefineIterator ()
+		protected override CaptureContext CaptureContext {
+			get { return OriginalBlock.CaptureContext; }
+		}
+
+#if FIXME
+		public override ConstructorInfo Constructor {
+			get { return ctor.ConstructorBuilder; }
+		}
+
+		protected bool DefineIterator ()
 		{
 			ec = new EmitContext (this, this, Location, null, null, ModFlags);
-			ec.CurrentAnonymousMethod = move_next_method;
+			ec.CurrentAnonymousMethod = this;
 			ec.InIterator = true;
 
-			if (!CheckType ()) {
-				Report.Error (1624, Location,
-					"The body of `{0}' cannot be an iterator block because `{1}' is not an iterator interface type",
-					orig_method.GetSignatureForError (), TypeManager.CSharpName (orig_method.ReturnType));
-				return false;
-			}
-
 			for (int i = 0; i < original_parameters.Count; i++){
 				Parameter.Modifier mod = original_parameters.ParameterModifier (i);
 				if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0){
@@ -423,12 +952,50 @@
 			else
 				this_type = container.TypeBuilder;
 
-			container.AddIterator (this);
+			orig_method.Block = block;
 
-			orig_method.Block = block;
+			return Resolve (ec);
+		}
+#endif
+
+		public override bool Resolve (EmitContext ec)
+		{
+			Report.Debug (64, "RESOLVE ITERATOR", this, Container, Block, TheBlock);
+
+			if (!base.Resolve (ec))
+				return false;
+
+			Report.Debug (64, "RESOLVE ITERATOR #1", this, method, method.Parent, RootScope);
+
+			if (!RootScope.DefineMembers ())
+				return false;
+
+			Expression scope_init = RootScope.GetScopeInitializer (ec);
+			Expression cast = new ClassCast (scope_init, OriginalMethod.ReturnType);
+			Container.AddStatement (new NoCheckReturn (cast));
+
 			return true;
 		}
 
+		protected override Method DoCreateMethodHost (EmitContext ec)
+		{
+			return new AnonymousMethodMethod (
+				this, null, TypeManager.system_boolean_expr,
+				Modifiers.PUBLIC, new MemberName ("MoveNext", Location),
+				Parameters.EmptyReadOnlyParameters);
+		}
+
+#if FIXME
+
+		public override CompilerGeneratedClass CreateScopeType (ScopeInfo scope)
+		{
+			return this;
+		}
+
+		public override bool IsIterator {
+			get { return true; }
+		}
+
 		MethodInfo FetchMethodDispose ()
 		{
 			MemberList dispose_list;
@@ -447,7 +1014,7 @@
 		protected override bool DoDefineMembers ()
 		{
 			ec.InIterator = true;
-			ec.CurrentAnonymousMethod = move_next_method;
+			ec.CurrentAnonymousMethod = this;
 			ec.capture_context = cc;
 
 			if (!base.DoDefineMembers ())
@@ -457,6 +1024,8 @@
 			if (dispose_method == null)
 				return false;
 
+			Report.Debug (64, "ITERATOR DEFINE MEMBERS", this);
+
 			return true;
 		}
 
@@ -466,7 +1035,7 @@
 				return false;
 
 			ec.InIterator = true;
-			ec.CurrentAnonymousMethod = move_next_method;
+			ec.CurrentAnonymousMethod = this;
 			ec.capture_context = cc;
 
 			ec.TypeContainer = ec.TypeContainer.Parent;
@@ -476,7 +1045,7 @@
 			else
 				ec.ContainerType = ec.TypeContainer.TypeBuilder;
 
-			ec.ig = move_next_method.method.MethodBuilder.GetILGenerator ();
+			// ec.ig = move_next_method.method.MethodBuilder.GetILGenerator ();
 
 			if (!ctor.Define ())
 				return false;
@@ -489,38 +1058,13 @@
 			if (!ec.ResolveTopBlock (null, block, parameters, orig_method, out unreachable))
 				return false;
 
-			original_block.CompleteContexts ();
+			original_block.CompleteContexts (ec);
 
 			cc.EmitAnonymousHelperClasses (ec);
 
-			return true;
-		}
+			ComputeMethodHost ();
 
-		TypeExpr InflateType (Type it)
-		{
-			if (generic_method == null)
-				return new TypeExpression (it, Location);
-
-			if (it.IsGenericParameter && (it.DeclaringMethod != null)) {
-				int pos = it.GenericParameterPosition;
-				it = CurrentTypeParameters [pos].Type;
-			} else if (it.IsGenericType) {
-				Type[] args = it.GetGenericArguments ();
-
-				TypeArguments inflated = new TypeArguments (Location);
-				foreach (Type t in args)
-					inflated.Add (InflateType (t));
-
-				return new ConstructedType (it, inflated, Location);
-			} else if (it.IsArray) {
-				TypeExpr et_expr = InflateType (it.GetElementType ());
-				int rank = it.GetArrayRank ();
-
-				Type et = et_expr.ResolveAsTypeTerminal (ec, false).Type;
-				it = et.MakeArrayType (rank);
-			}
-
-			return new TypeExpression (it, Location);
+			return DefineMembers ();
 		}
 
 		Parameter InflateParameter (Parameter param)
@@ -587,11 +1131,6 @@
 			else
 				current_type = new TypeExpression (TypeBuilder, Location);
 
-			if (IsGeneric) {
-				foreach (TypeParameter tparam in TypeParameters)
-					tparam.InflateConstraints (current_type.Type);
-			}
-
 			parameters = InflateParameters (original_parameters, ec);
 			if (!parameters.Resolve (ec)) {
 				// TODO:
@@ -600,7 +1139,6 @@
 			Define_Fields ();
 			Define_Current (false);
 			Define_Current (true);
-			Define_MoveNext ();
 			Define_Reset ();
 			Define_Dispose ();
 
@@ -616,14 +1154,12 @@
 			return base.DefineNestedTypes ();
 		}
 
-		Field pc_field;
-		Field current_field;
 		Method dispose;
 
 		void Create_Block ()
 		{
-			original_block.SetHaveAnonymousMethods (Location, move_next_method);
-			block.SetHaveAnonymousMethods (Location, move_next_method);
+			original_block.SetHaveAnonymousMethods (Location, this);
+			block.SetHaveAnonymousMethods (Location, this);
 
 			cc = original_block.CaptureContext;
 
@@ -634,7 +1170,7 @@
 				Type t = this_type;
 				args.Add (new Argument (
 					new ThisParameterReference (t, Location)));
-				cc.CaptureThis (move_next_method);
+				cc.CaptureThis (this);
 			}
 
 			args.Add (new Argument (new BoolLiteral (false, Location)));
@@ -647,7 +1183,11 @@
 				args.Add (new Argument (
 					new SimpleParameterReference (t, first + i, Location)));
 
-				cc.AddParameterToContext (move_next_method, name, inflated, first + i);
+				Report.Debug (64, "ITERATOR ADD PARAMETER", this, i, t, name,
+					      inflated);
+
+				cc.AddParameterToContext (
+					this, parameters [i], first + i, Location);
 			}
 
 			TypeExpr proxy_type;
@@ -665,7 +1205,7 @@
 				proxy_type = current_type;
 
 			Expression new_expr = new New (proxy_type, args, Location);
-			block.AddStatement (new NoCheckReturn (new_expr, Location));
+			block.AddStatement (new NoCheckReturn (new_expr));
 		}
 
 		void Define_Fields ()
@@ -723,7 +1263,8 @@
 				new SetState (this, State.Running, Location),
 				Location));
 
-			ctor.Block.AddStatement (new InitScope (this, Location));
+			ExpressionStatement init_scope = GetScopeInitializer (Location);
+			ctor.Block.AddStatement (new StatementExpression (init_scope));
 		}
 
 		Statement Create_ThrowInvalidOperation ()
@@ -778,17 +1319,6 @@
 			AddProperty (current);
 		}
 
-		void Define_MoveNext ()
-		{
-			move_next_method = new MoveNextMethod (this, Location);
-
-			original_block.ReParent (block, move_next_method);
-
-			move_next_method.CreateMethod (ec);
-
-			AddMethod (move_next_method.method);
-		}
-
 		void Define_GetEnumerator (bool is_generic)
 		{
 			MemberName left;
@@ -820,7 +1350,7 @@
 			get_enumerator.Block = new ToplevelBlock (
 				block, parameters, Location);
 
-			get_enumerator.Block.SetHaveAnonymousMethods (Location, move_next_method);
+			get_enumerator.Block.SetHaveAnonymousMethods (Location, this);
 
 			Expression ce = new MemberAccess (
 				new SimpleName ("System.Threading.Interlocked", Location),
@@ -934,7 +1464,7 @@
 
 			public override void Emit (EmitContext ec)
 			{
-				ec.CurrentAnonymousMethod = iterator.move_next_method;
+				ec.CurrentAnonymousMethod = iterator;
 
 				LocalTemporary dummy = null;
 				
@@ -995,62 +1525,8 @@
 				throw new InvalidOperationException ();
 			}
 		}
+#endif
 
-		protected class MoveNextMethod : AnonymousContainer
-		{
-			Iterator iterator;
-
-			public MoveNextMethod (Iterator iterator, Location loc)
-				: base (iterator.parameters, iterator.original_block, loc)
-			{
-				this.iterator = iterator;
-			}
-
-			protected override bool CreateMethodHost (EmitContext ec)
-			{
-				method = new Method (
-					iterator, null, TypeManager.system_boolean_expr,
-					Modifiers.PUBLIC, false, new MemberName ("MoveNext", loc),
-					Parameters.EmptyReadOnlyParameters, null);
-
-				method.Block = Block;
-
-				MoveNextStatement inline = new MoveNextStatement (iterator, loc);
-				Block.AddStatement (inline);
-
-				return true;
-			}
-
-			public bool CreateMethod (EmitContext ec)
-			{
-				return CreateMethodHost (ec);
-			}
-
-			public override Iterator Iterator {
-				get { return iterator; }
-			}
-
-			public void ComputeHost ()
-			{
-				ComputeMethodHost ();
-			}
-			
-			public override bool IsIterator {
-				get { return true; }
-			}
-
-			public override void CreateScopeType (EmitContext ec, ScopeInfo scope)
-			{
-				scope.ScopeTypeBuilder = iterator.TypeBuilder;
-				scope.ScopeConstructor = iterator.ctor.ConstructorBuilder;
-			}
-
-			public override void Emit (EmitContext ec)
-			{
-				throw new InternalErrorException ();
-			}
-		}
-
 		protected class MoveNextStatement : Statement {
 			Iterator iterator;
 
@@ -1062,19 +1538,16 @@
 
 			public override bool Resolve (EmitContext ec)
 			{
-				return true;
+				return iterator.OriginalBlock.Resolve (ec);
 			}
 
 			protected override void DoEmit (EmitContext ec)
 			{
-				iterator.move_next_method.ComputeHost ();
-				ec.CurrentAnonymousMethod = iterator.move_next_method;
-				ec.InIterator = true;
-
-				iterator.EmitMoveNext (ec);
+				iterator.EmitMoveNext (ec, iterator.Block);
 			}
 		}
 
+#if FIXME
 		protected class DisposeMethod : Statement {
 			Iterator iterator;
 
@@ -1151,27 +1624,6 @@
 			}
 		}
 
-		protected class InitScope : Statement
-		{
-			Iterator iterator;
-
-			public InitScope (Iterator iterator, Location loc)
-			{
-				this.iterator = iterator;
-				this.loc = loc;
-			}
-
-			public override bool Resolve (EmitContext ec)
-			{
-				return true;
-			}
-
-			protected override void DoEmit (EmitContext ec)
-			{
-				iterator.cc.EmitInitScope (ec);
-			}
-		}
-
 		void Define_Reset ()
 		{
 			Method reset = new Method (
@@ -1182,7 +1634,7 @@
 
 			reset.Block = new ToplevelBlock (Location);
 			reset.Block = new ToplevelBlock (block, parameters, Location);
-			reset.Block.SetHaveAnonymousMethods (Location, move_next_method);
+			reset.Block.SetHaveAnonymousMethods (Location, this);
 
 			reset.Block.AddStatement (Create_ThrowNotSupported ());
 		}
@@ -1196,13 +1648,14 @@
 			AddMethod (dispose);
 
 			dispose.Block = new ToplevelBlock (block, parameters, Location);
-			dispose.Block.SetHaveAnonymousMethods (Location, move_next_method);
+			dispose.Block.SetHaveAnonymousMethods (Location, this);
 
 			dispose.Block.AddStatement (new DisposeMethod (this, Location));
 		}
+#endif
 
 		public Type IteratorType {
-			get { return iterator_type_expr.Type; }
+			get { return IteratorHost.IteratorType; }
 		}
 
 		//
@@ -1212,10 +1665,10 @@
 		class NoCheckReturn : Statement {
 			public Expression Expr;
 		
-			public NoCheckReturn (Expression expr, Location l)
+			public NoCheckReturn (Expression expr)
 			{
 				Expr = expr;
-				loc = l;
+				loc = expr.Location;
 			}
 
 			public override bool Resolve (EmitContext ec)
@@ -1236,10 +1689,53 @@
 			}
 		}
 
-		bool CheckType ()
+		public static Iterator CreateIterator (IMethodData method, TypeContainer parent,
+						       GenericMethod generic, int modifiers)
 		{
-			Type ret = orig_method.ReturnType;
+			bool is_enumerable;
+			Type iterator_type;
 
+			if (!CheckType (method.ReturnType, out iterator_type, out is_enumerable)) {
+				Report.Error (1624, method.Location,
+					      "The body of `{0}' cannot be an iterator block " +
+					      "because `{1}' is not an iterator interface type",
+					      method.GetSignatureForError (),
+					      TypeManager.CSharpName (method.ReturnType));
+				return null;
+			}
+
+			Report.Debug (64, "CREATE ITERATOR", parent, method, method.Block);
+
+#if FIXME
+			ToplevelBlock container = new ToplevelBlock (
+				method.Block, method.ParameterInfo, method.Location);
+#endif
+
+			ToplevelBlock block = new ToplevelBlock (method.ParameterInfo, method.Location);
+			// method.Block.ReParent (block);
+
+			Iterator iterator = new Iterator (
+				method, parent, generic, null, block, modifiers,
+				iterator_type, is_enumerable);
+
+			if (!iterator.RootScope.Define ())
+				return null;
+			if (iterator.RootScope.DefineType () == null)
+				return null;
+			if (!iterator.RootScope.ResolveType ())
+				return null;
+
+			Report.Debug (64, "CREATE ITERATOR #1", iterator, iterator.RootScope,
+				      iterator.RootScope.IsGeneric, iterator.RootScope.TypeBuilder);
+
+			return iterator;
+		}
+
+		static bool CheckType (Type ret, out Type original_iterator_type, out bool is_enumerable)
+		{
+			original_iterator_type = null;
+			is_enumerable = false;
+
 			if (ret == TypeManager.ienumerable_type) {
 				original_iterator_type = TypeManager.object_type;
 				is_enumerable = true;
Index: cs-parser.jay
===================================================================
--- cs-parser.jay	(revision 63019)
+++ cs-parser.jay	(working copy)
@@ -45,6 +45,9 @@
 
 		Delegate   current_delegate;
 
+		GenericMethod current_generic_method;
+		AnonymousMethodExpression current_anonymous_method;
+
 		/// <summary>
 		///   This is used by the unary_expression code to resolve
 		///   a name against a parameter.  
@@ -1074,6 +1077,7 @@
 		method.Block = (ToplevelBlock) $3;
 		current_container.AddMethod (method);
 
+		current_generic_method = null;
 		current_local_parameters = null;
 		iterator_container = null;
 
@@ -1133,6 +1137,7 @@
 				     name, (Parameters) $6, (Attributes) $1);
 
 		current_local_parameters = (Parameters) $6;
+		current_generic_method = generic;
 
 		if (RootContext.Documentation != null)
 			method.DocComment = Lexer.consume_doc_comment ();
@@ -1169,6 +1174,7 @@
 				     (int) $2, false, name, (Parameters) $6, (Attributes) $1);
 
 		current_local_parameters = (Parameters) $6;
+		current_generic_method = generic;
 
 		if (RootContext.Documentation != null)
 			method.DocComment = Lexer.consume_doc_comment ();
@@ -3396,6 +3402,7 @@
 		if (oob_stack == null)
 			oob_stack = new Stack (6);
 
+		oob_stack.Push (current_anonymous_method);
 		oob_stack.Push (current_local_parameters);
 		current_local_parameters = (Parameters)$2;
 
@@ -3403,7 +3410,12 @@
 		oob_stack.Push (current_block);
 		oob_stack.Push (top_current_block);
 		current_block = null;
-	  } 
+
+		Location loc = (Location) $1;
+		current_anonymous_method = new AnonymousMethodExpression (
+			current_anonymous_method, current_generic_method, current_container,
+			(Parameters) $2, (ToplevelBlock) top_current_block, loc);
+	  }
 	  block
 	  {
 		Location loc = (Location) $1;
@@ -3416,11 +3428,16 @@
 			ToplevelBlock anon_block = (ToplevelBlock) $4;
 
 			anon_block.Parent = current_block;
-			$$ = new AnonymousMethod (current_container, (Parameters) $2, (ToplevelBlock) top_current_block, 
-				anon_block, loc);
+
+			current_anonymous_method.Block = anon_block;
+			anon_block.SetHaveAnonymousMethods (loc, current_anonymous_method);
+
+			$$ = current_anonymous_method;
 		}
-			current_local_parameters = (Parameters) oob_stack.Pop ();
-		}
+
+		current_local_parameters = (Parameters) oob_stack.Pop ();
+		current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
+	}
 	;
 
 opt_anonymous_method_signature
@@ -4000,7 +4017,8 @@
 	: OPEN_BRACE 
 	  {
 		if (current_block == null){
-			current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, (Location) $1);
+			current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters,
+							   current_generic_method, (Location) $1);
 			top_current_block = current_block;
 		} else {
 			current_block = new Block (current_block, (Location) $1, Location.Null);
Index: convert.cs
===================================================================
--- convert.cs	(revision 63019)
+++ convert.cs	(working copy)
@@ -838,8 +838,8 @@
 				if (!TypeManager.IsDelegateType (target_type))
 					return false;
 
-				AnonymousMethod am = (AnonymousMethod) expr;
-				return am.ImplicitStandardConversionExists (target_type);
+				AnonymousMethodExpression ame = (AnonymousMethodExpression) expr;
+				return ame.ImplicitStandardConversionExists (target_type);
 			}
 
 			return false;
@@ -1325,10 +1325,11 @@
 					return null;
 				}
 
-				AnonymousMethod am = (AnonymousMethod) expr;
+				AnonymousMethodExpression ame = (AnonymousMethodExpression) expr;
+
 				int errors = Report.Errors;
 
-				Expression conv = am.Compatible (ec, target_type);
+				Expression conv = ame.Compatible (ec, target_type);
 				if (conv != null)
 					return conv;
 				
Index: anonymous.cs
===================================================================
--- anonymous.cs	(revision 63019)
+++ anonymous.cs	(working copy)
@@ -20,297 +20,721 @@
 
 namespace Mono.CSharp {
 
-	public abstract class AnonymousContainer : Expression
+	public abstract class CompilerGeneratedClass : Class
 	{
-		// Used to generate unique method names.
-		protected static int anonymous_method_count;
-		    
-		// An array list of AnonymousMethodParameter or null
-		public Parameters Parameters;
-		
-		//
-		// The block that makes up the body for the anonymous mehtod
-		//
-		public ToplevelBlock Block;
+		GenericMethod generic_method;
+		static int next_index = 0;
 
-		//
-		// The container block for this anonymous method.
-		//
-		public Block ContainingBlock;
+		private static MemberName MakeProxyName (GenericMethod generic, Location loc)
+		{
+			string name = String.Format ("<>c__CompilerGenerated{0}", ++next_index);
+			if (generic != null) {
+				TypeArguments args = new TypeArguments (loc);
+				foreach (TypeParameter tparam in generic.CurrentTypeParameters)
+					args.Add (new SimpleName (tparam.Name, loc));
+				return new MemberName (name, args, loc);
+			} else
+				return new MemberName (name, loc);
+		}
 
-		//
-		// The implicit method we create
-		//
-		public Method method;
+		protected string MakeName (string prefix)
+		{
+			return String.Format ("<>c__{0}{1}", prefix, ++next_index);
+		}
 
-		protected MethodInfo invoke_mb;
-		
-		// The emit context for the anonymous method
-		public EmitContext aec;
-		public string[] TypeParameters;
-		public Type[] TypeArguments;
-		protected bool unreachable;
+		protected CompilerGeneratedClass (TypeContainer parent, GenericMethod generic,
+						  int mod, Location loc)
+			: base (parent.NamespaceEntry, parent,
+				MakeProxyName (generic, loc), mod, null)
+		{
+			this.generic_method = generic;
 
-		// The method scope
-		ScopeInfo method_scope;
-		bool computed_method_scope = false;
-		
-		//
-		// The modifiers applied to the method, we aggregate them
-		//
-		protected int method_modifiers = Modifiers.PRIVATE;
-		
-		//
-		// Track the scopes that this method has used.  At the
-		// end this is used to determine the ScopeInfo that will
-		// host the method
-		//
-		ArrayList scopes_used = new ArrayList ();
-		
-		//
-		// Points to our container anonymous method if its present
-		//
-		public AnonymousContainer ContainerAnonymousMethod;	
+			if (generic != null) {
+				ArrayList list = new ArrayList ();
+				foreach (TypeParameter tparam in generic.TypeParameters) {
+					if (tparam.Constraints != null)
+						list.Add (tparam.Constraints.Clone ());
+				}
+				SetParameterInfo (list);
+			}
 
-		protected AnonymousContainer (Parameters parameters, ToplevelBlock container,
-					      ToplevelBlock block, Location l)
+			parent.AddCompilerGeneratedClass (this);
+		}
+
+		protected override bool DefineNestedTypes ()
 		{
-			Parameters = parameters;
-			Block = block;
-			loc = l;
+			RootContext.RegisterCompilerGeneratedType (TypeBuilder);
+			return base.DefineNestedTypes ();
+		}
 
-			//
-			// The order is important: this setups the CaptureContext tree hierarchy.
-			//
-			if (container == null) {
-				return;
+		protected override bool DoDefineMembers ()
+		{
+			if (!PopulateType ())
+				throw new InternalErrorException ();
+
+			members_defined = true;
+
+			if (!base.DoDefineMembers ())
+				return false;
+
+			if (CompilerGenerated != null) {
+				foreach (CompilerGeneratedClass c in CompilerGenerated) {
+					if (!c.DefineMembers ())
+						throw new InternalErrorException ();
+				}
 			}
-			container.SetHaveAnonymousMethods (l, this);
-			block.SetHaveAnonymousMethods (l, this);
+
+			return true;
 		}
 
-		protected AnonymousContainer (Parameters parameters, ToplevelBlock container,
-					      Location l):
-			this (parameters, container, new ToplevelBlock (container, parameters, l), l)
+		protected virtual bool PopulateType ()
 		{
+			if (type_populated)
+				return true;
+
+			type_populated = true;
+
+			if (!DoPopulateType ())
+				return false;
+
+			if (CompilerGenerated != null) {
+				foreach (CompilerGeneratedClass c in CompilerGenerated) {
+					if (!c.PopulateType ())
+						return false;
+				}
+			}
+
+			return true;
 		}
 
-		public override Expression DoResolve (EmitContext ec)
+		protected virtual bool DoPopulateType ()
 		{
-			//
-			// Set class type, set type
-			//
+			return true;
+		}
 
-			eclass = ExprClass.Value;
+		public GenericMethod GenericMethod {
+			get { return generic_method; }
+		}
 
-			//
-			// This hack means `The type is not accessible
-			// anywhere', we depend on special conversion
-			// rules.
-			// 
-			type = TypeManager.anonymous_method_type;
+		protected TypeExpr InflateType (Type it)
+		{
+			if (generic_method == null)
+				return new TypeExpression (it, Location);
 
-			return this;
+			if (it.IsGenericParameter && (it.DeclaringMethod != null)) {
+				int pos = it.GenericParameterPosition;
+				it = CurrentTypeParameters [pos].Type;
+			} else if (it.IsGenericType) {
+				Type[] args = it.GetGenericArguments ();
+
+				TypeArguments inflated = new TypeArguments (Location);
+				foreach (Type t in args)
+					inflated.Add (InflateType (t));
+
+				return new ConstructedType (it, inflated, Location);
+			} else if (it.IsArray) {
+				TypeExpr et_expr = InflateType (it.GetElementType ());
+				int rank = it.GetArrayRank ();
+
+				Type et = et_expr.ResolveAsTypeTerminal (this, false).Type;
+				it = et.MakeArrayType (rank);
+			}
+
+			return new TypeExpression (it, Location);
 		}
 
-		public void RegisterScope (ScopeInfo scope)
+		public Field CaptureVariable (string name, Type type)
 		{
-			if (scopes_used.Contains (scope))
-				return;
-			scopes_used.Add (scope);
+			if (members_defined)
+				throw new InternalErrorException ("Helper class already defined!");
+			if (type == null)
+				throw new ArgumentNullException ();
+
+			return new CapturedVariable (this, name, InflateType (type));
 		}
 
-		// Returns the deepest of two scopes
-		ScopeInfo Deepest (ScopeInfo a, ScopeInfo b)
+		bool type_populated;
+		bool members_defined;
+
+		internal void CheckMembersDefined ()
 		{
-			ScopeInfo p;
+			if (members_defined)
+				throw new InternalErrorException ("Helper class already defined!");
+		}
 
-			if (a == null)
-				return b;
-			if (b == null)
-				return a;
-			if (a == b)
-				return a;
+		public override void EmitType ()
+		{
+			Report.Debug (64, "COMPILER GENERATED EMIT TYPE", this, CompilerGenerated);
+			base.EmitType ();
+		}
 
-			//
-			// If they Scopes are on the same CaptureContext, we do the double
-			// checks just so if there is an invariant change in the future,
-			// we get the exception at the end
-			//
-			for (p = a; p != null; p = p.ParentScope)
-				if (p == b)
-					return a;
-			
-			for (p = b; p != null; p = p.ParentScope)
-				if (p == a)
-					return b;
+		protected class CapturedVariable : Field
+		{
+			public CapturedVariable (CompilerGeneratedClass helper, string name,
+						 TypeExpr type)
+				: base (helper, type, Modifiers.INTERNAL, name, null, helper.Location)
+			{
+				helper.AddField (this);
+			}
+		}
+	}
 
-			CaptureContext ca = a.CaptureContext;
-			CaptureContext cb = b.CaptureContext;
+	public abstract class ScopeInfoBase : CompilerGeneratedClass
+	{
+		public CaptureContext CaptureContext;
 
-			for (CaptureContext c = ca; c != null; c = c.ParentCaptureContext)
-				if (c == cb)
-					return a;
+		protected ScopeInfoBase (TypeContainer parent, GenericMethod generic,
+					 int mod, Location loc)
+			: base (parent, generic, mod, loc)
+		{ }
 
-			for (CaptureContext c = cb; c != null; c = c.ParentCaptureContext)
-				if (c == ca)
-					return b;
-			throw new Exception ("Should never be reached");
+		TypeExpr scope_type;
+		Field scope_instance;
+		ScopeInitializerBase scope_initializer;
+
+		public abstract AnonymousMethodHost Host {
+			get;
 		}
 
-		//
-		// Determines the proper host for a method considering the
-		// scopes it references
-		//
-		public void ComputeMethodHost ()
+		public Field ScopeInstance {
+			get { return scope_instance; }
+		}
+
+		public Type ScopeType {
+			get { return scope_type.Type; }
+		}
+
+		public void EmitScopeInstance (EmitContext ec)
 		{
-			if (computed_method_scope)
-				return;
-			
-			method_scope = null;
-			int top = scopes_used.Count;
-			computed_method_scope = true;
+			if (scope_initializer == null) {
+				//
+				// This is needed if someone overwrites the Emit method
+				// of Statement and manually calls Block.Emit without
+				// this snippet first:
+				// 
+				//   ec.EmitScopeInitFromBlock (The_Block);
+				//   The_Block.Emit (ec);
+				// 
+				throw new InternalErrorException ();
+			}
 
-			if (top == 0)
-				return;
-			
-			method_scope = (ScopeInfo) scopes_used [0];
-			if (top == 1)
-				return;
-			
-			for (int i = 1; i < top; i++)
-				method_scope = Deepest (method_scope, (ScopeInfo) scopes_used [i]);
+			Report.Debug (64, "EMIT SCOPE INSTANCE", this, GetType (), scope_initializer);
+			if (this is IteratorHost)
+				ec.ig.Emit (OpCodes.Ldarg_0);
+			else
+				scope_initializer.Emit (ec);
 		}
 
-		public ScopeInfo Scope {
-			get {
-				if (computed_method_scope)
-					return method_scope;
+		public ExpressionStatement GetScopeInitializer (EmitContext ec)
+		{
+			Report.Debug (64, "GET SCOPE INITIALIZER", this, GetType (), scope_initializer);
+			if (scope_initializer == null) {
+				scope_initializer = CreateScopeInitializer ();
+				if (scope_initializer.Resolve (ec) == null)
+					throw new InternalErrorException ();
+			}
 
-				//
-				// This means that ComputeMethodHost is not being called, most
-				// likely by someone who overwrote the CreateMethodHost method
-				//
-				throw new Exception ("Internal error, AnonymousContainer.Scope is being used before its container is computed");
+			return scope_initializer;
+		}
+
+		protected abstract ScopeInitializerBase CreateScopeInitializer ();
+
+		protected override bool DoPopulateType ()
+		{
+			Report.Debug (64, "SCOPE INFO RESOLVE TYPE", this, GetType (), IsGeneric,
+				      Parent.IsGeneric, GenericMethod);
+
+			if (IsGeneric) {
+				TypeArguments targs = new TypeArguments (Location);
+				if (Parent.IsGeneric)
+					foreach (TypeParameter t in Parent.TypeParameters)
+						targs.Add (new TypeParameterExpr (t, Location));
+				if (GenericMethod != null)
+					foreach (TypeParameter t in GenericMethod.TypeParameters)
+						targs.Add (new TypeParameterExpr (t, Location));
+
+				scope_type = new ConstructedType (TypeBuilder, targs, Location);
+				scope_type = scope_type.ResolveAsTypeTerminal (this, false);
+				if ((scope_type == null) || (scope_type.Type == null))
+					return false;
+			} else {
+				scope_type = new TypeExpression (TypeBuilder, Location);
 			}
+
+			if (Host != this)
+				scope_instance = Host.CaptureVariable (MakeName ("scope"), ScopeType);
+
+			return base.DoPopulateType ();
 		}
-		
-		
-		protected abstract bool CreateMethodHost (EmitContext ec);
 
-		public abstract void CreateScopeType (EmitContext ec, ScopeInfo scope);
+		protected abstract class ScopeInitializerBase : ExpressionStatement
+		{
+			ScopeInfoBase scope;
+			protected Variable scope_instance;
+			ConstructorInfo scope_ctor;
 
-		public abstract Iterator Iterator {
-			get;
+			bool initialized;
+
+			protected ScopeInitializerBase (ScopeInfoBase scope)
+			{
+				this.scope = scope;
+				this.loc = scope.Location;
+				eclass = ExprClass.Value;
+			}
+
+			public ScopeInfoBase Scope {
+				get { return scope; }
+			}
+
+			public override Expression DoResolve (EmitContext ec)
+			{
+				if (scope_ctor != null)
+					return this;
+
+				Report.Debug (64, "RESOLVE SCOPE INITIALIZER BASE", this, Scope);
+
+				type = Scope.ScopeType;
+
+				if (!DoResolveInternal (ec))
+					throw new InternalErrorException ();
+
+				return this;
+			}
+
+			protected virtual bool DoResolveInternal (EmitContext ec)
+			{
+				MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookupFinal (
+					ec, ec.ContainerType, type, ".ctor", MemberTypes.Constructor,
+					AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+				if (mg == null)
+					throw new InternalErrorException ();
+
+				scope_ctor = (ConstructorInfo) mg.Methods [0];
+
+				if (Scope.ScopeInstance != null)
+					scope_instance = new CapturedField (Scope.ScopeInstance);
+				else {
+					LocalBuilder local = ec.ig.DeclareLocal (type);
+					scope_instance = new CapturedTemporary (Scope, local);
+				}
+				return true;
+			}
+
+			static int next_id;
+			int id = ++next_id;
+
+			protected void DoEmit (EmitContext ec)
+			{
+				if (initialized)
+					return;
+				initialized = true;
+
+				Report.Debug (64, "EMIT SCOPE INIT", this, id,
+					      Scope, scope_instance, ec);
+
+				ec.ig.Emit (OpCodes.Nop);
+				ec.ig.Emit (OpCodes.Ldc_I4, id);
+				ec.ig.Emit (OpCodes.Pop);
+				ec.ig.Emit (OpCodes.Nop);
+
+				DoEmitInternal (ec);
+			}
+
+			protected virtual void EmitScopeConstructor (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Newobj, scope_ctor);
+			}
+
+			protected virtual void DoEmitInternal (EmitContext ec)
+			{
+				scope_instance.EmitInstance (ec);
+				EmitScopeConstructor (ec);
+				scope_instance.EmitAssign (ec);
+			}
+
+			public override void Emit (EmitContext ec)
+			{
+				DoEmit (ec);
+				scope_instance.EmitInstance (ec);
+				scope_instance.Emit (ec);
+			}
+
+			public override void EmitStatement (EmitContext ec)
+			{
+				DoEmit (ec);
+			}
 		}
 
-		public abstract bool IsIterator {
-			get;
+		protected class CapturedTemporary : Variable {
+			public readonly ScopeInfoBase Scope;
+			public readonly LocalBuilder Local;
+
+			public CapturedTemporary (ScopeInfoBase scope, LocalBuilder local)
+			{
+				this.Scope = scope;
+				this.Local = local;
+			}
+
+			public override Type Type {
+				get { return Local.LocalType; }
+			}
+
+			public override bool HasInstance {
+				get { return false; }
+			}
+
+			public override bool NeedsTemporary {
+				get { return false; }
+			}
+
+			public override void EmitInstance (EmitContext ec)
+			{ }
+
+			public override void Emit (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldloc, Local);
+			}
+
+			public override void EmitAssign (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Stloc, Local);
+			}
+
+			public override void EmitAddressOf (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldloca, Local);
+			}
 		}
+
+		protected class CapturedField : Variable {
+			public readonly Field Field;
+
+			public CapturedField (Field field)
+			{
+				this.Field = field;
+			}
+
+			public override Type Type {
+				get { return Field.MemberType; }
+			}
+
+			public override bool HasInstance {
+				get { return true; }
+			}
+
+			public override bool NeedsTemporary {
+				get { return true; }
+			}
+
+			public override void EmitInstance (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldarg_0);
+			}
+
+			public override void Emit (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldfld, Field.FieldBuilder);
+			}
+
+			public override void EmitAssign (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Stfld, Field.FieldBuilder);
+			}
+
+			public override void EmitAddressOf (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldflda, Field.FieldBuilder);
+			}
+		}
 	}
 
-	public class AnonymousMethod : AnonymousContainer
+	public class AnonymousMethodHost : ScopeInfo
 	{
-		TypeContainer host;
+		public AnonymousMethodHost (CaptureContext cc, ToplevelBlock toplevel,
+					    TypeContainer parent, GenericMethod generic)
+			: base (cc, toplevel, parent, generic)
+		{ }
 
-		//
-		// The value return by the Compatible call, this ensure that
-		// the code works even if invoked more than once (Resolve called
-		// more than once, due to the way Convert.ImplicitConversion works
-		//
-		Expression anonymous_delegate;
+		public bool HostsParameters = false;
 
-		public AnonymousMethod (TypeContainer host, Parameters parameters, ToplevelBlock container,
-					ToplevelBlock block, Location l)
-			: base (parameters, container, block, l)
+		TypeExpr parent_type;
+		CapturedVariable parent_link;
+		CapturedVariable this_field;
+
+		public override AnonymousMethodHost Host {
+			get { return this; }
+		}
+
+		public AnonymousMethodHost ParentHost {
+			get { return Parent as AnonymousMethodHost; }
+		}
+
+		public Type ParentType {
+			get { return parent_type.Type; }
+		}
+
+		public Field ParentLink {
+			get { return parent_link; }
+		}
+
+		public Field THIS {
+			get { return this_field; }
+		}
+
+		public Field CaptureThis ()
 		{
-			this.host = host;
+			CheckMembersDefined ();
+			if (Parent is CompilerGeneratedClass)
+				throw new InternalErrorException ("CaptureThis called in inner class!");
+
+			if (this_field == null)
+				this_field = new CapturedVariable (this, "<>THIS", parent_type);
+			return this_field;
 		}
 
-		public override Iterator Iterator {
-			get { return null; }
+		protected override ScopeInitializerBase CreateScopeInitializer ()
+		{
+			return new AnonymousMethodHostInitializer (this);
 		}
 
-		public override bool IsIterator {
-			get { return false; }
+		protected override bool DefineNestedTypes ()
+		{
+			Report.Debug (64, "ANONYMOUS METHOD HOST NESTED",
+				      this, Name, Parent, Parent.Name, Parent.IsGeneric);
+
+			if (Parent.IsGeneric) {
+				parent_type = new ConstructedType (
+					Parent.TypeBuilder, Parent.TypeParameters, Location);
+				parent_type = parent_type.ResolveAsTypeTerminal (this, false);
+				if ((parent_type == null) || (parent_type.Type == null))
+					return false;
+			} else {
+				parent_type = new TypeExpression (Parent.TypeBuilder, Location);
+			}
+
+			CompilerGeneratedClass parent = Parent as CompilerGeneratedClass;
+			if (parent != null)
+				parent_link = new CapturedVariable (this, "<>parent", parent_type);
+
+			return base.DefineNestedTypes ();
 		}
 
-		public override void Emit (EmitContext ec)
+		protected override bool DoDefineMembers ()
 		{
-			// nothing, as we only exist to not do anything.
+			Report.Debug (64, "ANONYMOUS METHOD HOST DEFINE MEMBERS",
+				      this, Name, Parent, CompilerGenerated);
+
+			ArrayList args = new ArrayList ();
+			if (this is IteratorHost)
+				args.Add (new Parameter (
+					TypeManager.int32_type, "$PC", Parameter.Modifier.NONE,
+					null, Location));
+
+			Field pfield = Parent is CompilerGeneratedClass ? parent_link : this_field;
+			if (pfield != null)
+				args.Add (new Parameter (
+					pfield.MemberType, "parent", Parameter.Modifier.NONE,
+					null, Location));
+
+			if (HostsParameters) {
+				Hashtable hash = CaptureContext.captured_parameters;
+				foreach (CapturedParameter cp in hash.Values) {
+					args.Add (new Parameter (
+							  cp.Field.MemberType, cp.Field.Name,
+							  Parameter.Modifier.NONE, null, Location));
+				}
+			}
+
+			Parameter[] ctor_params = new Parameter [args.Count];
+			args.CopyTo (ctor_params, 0);
+			Constructor ctor = new Constructor (
+				this, MemberName.Name, Modifiers.PUBLIC,
+				new Parameters (ctor_params),
+				new GeneratedBaseInitializer (Location),
+				Location);
+			AddConstructor (ctor);
+
+			ctor.Block = new ToplevelBlock (null, Location);
+			ctor.Block.AddStatement (new TheCtor (this));
+
+			return base.DoDefineMembers ();
 		}
 
-		//
-		// Creates the host for the anonymous method
-		//
-		protected override bool CreateMethodHost (EmitContext ec)
+		protected virtual void EmitScopeConstructor (EmitContext ec)
 		{
-			ComputeMethodHost ();
+			int pos = (this is IteratorHost) ? 2 : 1;
+			Field pfield = Parent is CompilerGeneratedClass ? parent_link : this_field;
+			if (pfield != null) {
+				ec.ig.Emit (OpCodes.Ldarg_0);
+				ec.ig.Emit (OpCodes.Ldarg_1);
+				ec.ig.Emit (OpCodes.Stfld, pfield.FieldBuilder);
+				pos++;
+			}
 
-			//
-			// Crude hack follows: we replace the TypeBuilder during the
-			// definition to get the method hosted in the right class
-			//
-			TypeBuilder current_type = ec.TypeContainer.TypeBuilder;
-			TypeBuilder type_host = (Scope == null ) ? current_type : Scope.ScopeTypeBuilder;
+			if (HostsParameters) {
+				Hashtable hash = CaptureContext.captured_parameters;
+				foreach (CapturedParameter cp in hash.Values) {
+					ec.ig.Emit (OpCodes.Ldarg_0);
+					ParameterReference.EmitLdArg (ec.ig, pos++);
+					ec.ig.Emit (OpCodes.Stfld, cp.Field.FieldBuilder);
+				}
+			}
+		}
 
-			if (current_type == null)
-				throw new Exception ("The current_type is null");
-			
-			if (type_host == null)
-				throw new Exception (String.Format ("Type host is null, method_host is {0}", Scope == null ? "null" : "Not null"));
+		protected class TheCtor : Statement
+		{
+			AnonymousMethodHost host;
 
-			if (current_type != type_host)
-				method_modifiers = Modifiers.INTERNAL;
+			public TheCtor (AnonymousMethodHost host)
+			{
+				this.host = host;
+			}
 
-			if (current_type == type_host && ec.IsStatic){
-				method_modifiers |= Modifiers.STATIC;
-				current_type = null;
-			} 
+			public override bool Resolve (EmitContext ec)
+			{
+				return true;
+			}
 
-			string name = "<#AnonymousMethod>" + anonymous_method_count++;
-			MemberName member_name;
+			protected override void DoEmit (EmitContext ec)
+			{
+				host.EmitScopeConstructor (ec);
+			}
+		}
 
-			GenericMethod generic_method = null;
-			if (TypeParameters != null) {
-				TypeArguments args = new TypeArguments (loc);
-				foreach (string t in TypeParameters)
-					args.Add (new SimpleName (t, loc));
+		protected class AnonymousMethodHostInitializer : ScopeInitializer
+		{
+			AnonymousMethodHost host;
+			ExpressionStatement parent_init;
 
-				member_name = new MemberName (name, args, loc);
+			public AnonymousMethodHostInitializer (AnonymousMethodHost host)
+				: base (host)
+			{
+				this.host = host;
+			}
 
-				generic_method = new GenericMethod (
-					ec.DeclContainer.NamespaceEntry,
-					(TypeContainer) ec.TypeContainer, member_name,
-					new TypeExpression (invoke_mb.ReturnType, loc),
-					Parameters);
+			public AnonymousMethodHost Host {
+				get { return host; }
+			}
 
-				generic_method.SetParameterInfo (null);
-			} else
-				member_name = new MemberName (name, loc);
+			protected override bool DoResolveInternal (EmitContext ec)
+			{
+				Report.Debug (64, "RESOLVE ANONYMOUS METHOD HOST INITIALIZER",
+					      this, Host, Host.ScopeType, Host.ParentType, loc);
 
-			method = new Method (
-				(TypeContainer) ec.TypeContainer, generic_method,
-				new TypeExpression (invoke_mb.ReturnType, loc),
-				method_modifiers, false, member_name, Parameters, null);
-			method.Block = Block;
+				//
+				// Copy the parameter values, if any
+				//
+				if (Host.HostsParameters){
+					Hashtable hash = Host.CaptureContext.captured_parameters;
+					foreach (CapturedParameter cp in hash.Values) {
+						FieldExpr fe = (FieldExpr) Expression.MemberLookup (
+							ec.ContainerType, type, cp.Field.Name, loc);
+						if (fe == null)
+							throw new InternalErrorException ();
 
-			//
-			// Swap the TypeBuilder while we define the method, then restore
-			//
-			if (current_type != null)
-				ec.TypeContainer.TypeBuilder = type_host;
-			bool res = method.Define ();
-			if (current_type != null)
-				ec.TypeContainer.TypeBuilder = current_type;
+						fe.InstanceExpression = this;
+						cp.FieldInstance = fe;
+					}
+				}
 
-			return res;
+				return base.DoResolveInternal (ec);
+			}
+
+			protected override void EmitScopeConstructor (EmitContext ec)
+			{
+				if ((host.THIS != null) || (host.ParentLink != null))
+					ec.ig.Emit (OpCodes.Ldarg_0);
+
+				if (Host.HostsParameters) {
+					Hashtable hash = Host.CaptureContext.captured_parameters;
+					foreach (CapturedParameter cp in hash.Values) {
+						EmitParameterReference (ec, cp);
+					}
+				}
+
+				base.EmitScopeConstructor (ec);
+			}
 		}
 
+	}
+
+	public interface IAnonymousContainer
+	{
+		ToplevelBlock Container {
+			get;
+		}
+
+		GenericMethod GenericMethod {
+			get;
+		}
+
+		AnonymousMethodHost RootScope {
+			get;
+		}
+
+		bool IsIterator {
+			get;
+		}
+	}
+
+	public class AnonymousMethodExpression : Expression, IAnonymousContainer
+	{
+		public readonly AnonymousMethodExpression Parent;
+		public readonly TypeContainer Host;
+		public readonly Parameters Parameters;
+
+		public ToplevelBlock Block;
+		protected AnonymousMethod anonymous;
+
+		protected readonly ToplevelBlock container;
+		protected readonly GenericMethod generic;
+
+		public ToplevelBlock Container {
+			get { return container; }
+		}
+
+		public GenericMethod GenericMethod {
+			get { return generic; }
+		}
+
+		public AnonymousMethod AnonymousMethod {
+			get { return anonymous; }
+		}
+
+		public AnonymousMethodHost RootScope {
+			get { return container.AnonymousMethodHost; }
+		}
+
+		public AnonymousMethodExpression (AnonymousMethodExpression parent,
+						  GenericMethod generic, TypeContainer host,
+						  Parameters parameters, ToplevelBlock container,
+						  Location loc)
+		{
+			this.Parent = parent;
+			this.generic = parent != null ? null : generic;
+			this.Host = host;
+			this.Parameters = parameters;
+			this.container = container;
+			this.loc = loc;
+
+			Report.Debug (64, "NEW ANONYMOUS METHOD EXPRESSION", this, parent, host,
+				      container, loc);
+
+			container.SetHaveAnonymousMethods (loc, this);
+			container.CreateAnonymousMethodHost (Host);
+		}
+
+		public override string ExprClassName {
+			get {
+				return "anonymous method";
+			}
+		}
+
 		void Error_ParameterMismatch (Type t)
 		{
 			Report.Error (1661, loc, "Anonymous method could not be converted to delegate `" +
-				      "{0}' since there is a parameter mismatch", TypeManager.CSharpName (t));
+				      "{0}' since there is a parameter mismatch",
+				      TypeManager.CSharpName (t));
 		}
 
 		public bool ImplicitStandardConversionExists (Type delegate_type)
@@ -318,8 +742,9 @@
 			if (Parameters == null)
 				return true;
 
-			MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (host.TypeBuilder, delegate_type, loc);
-			invoke_mb = (MethodInfo) invoke_mg.Methods [0];
+			MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
+				Host.TypeBuilder, delegate_type, loc);
+			MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
 			ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
 
 			if (Parameters.Count != invoke_pd.Count)
@@ -338,31 +763,20 @@
 		//
 		public Expression Compatible (EmitContext ec, Type delegate_type)
 		{
-			if (anonymous_delegate != null)
-				return anonymous_delegate;
-			
+			if (anonymous != null)
+				return anonymous.AnonymousDelegate;
+
 			//
 			// At this point its the first time we know the return type that is 
 			// needed for the anonymous method.  We create the method here.
 			//
 
-			MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (ec.ContainerType, delegate_type, loc);
-			invoke_mb = (MethodInfo) invoke_mg.Methods [0];
+			MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
+				ec.ContainerType, delegate_type, loc);
+			MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
 			ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
 
-			if (delegate_type.IsGenericType) {
-				Type def = delegate_type.GetGenericTypeDefinition ();
-
-				if (def != delegate_type) {
-					Type[] tparam = TypeManager.GetTypeArguments (def);
-
-					TypeArguments = TypeManager.GetTypeArguments (delegate_type);
-					TypeParameters = new string [tparam.Length];
-					for (int i = 0; i < tparam.Length; i++)
-						TypeParameters [i] = tparam [i].Name;
-				}
-			}
-
+			Parameters parameters;
 			if (Parameters == null) {
 				//
 				// We provide a set of inaccessible parameters
@@ -375,7 +789,9 @@
 						"+" + i, invoke_pd.ParameterModifier (i), null, loc);
 				}
 								
-				Parameters = new Parameters (fixedpars);
+				parameters = new Parameters (fixedpars);
+				if (!parameters.Resolve (ec))
+					return null;
 			} else {
 				if (Parameters.Count != invoke_pd.Count) {
 					Report.SymbolRelatedToPreviousError (delegate_type);
@@ -407,8 +823,10 @@
 						return null;
 					}
 				}
+
+				parameters = Parameters;
 			}
-			
+
 			//
 			// Second: the return type of the delegate must be compatible with 
 			// the anonymous type.   Instead of doing a pass to examine the block
@@ -419,135 +837,329 @@
 			//MethodBuilder builder = method_data.MethodBuilder;
 			//ILGenerator ig = builder.GetILGenerator ();
 
-			aec = new EmitContext (ec.ResolveContext,
-				ec.TypeContainer, ec.DeclContainer, loc, null,
-				invoke_mb.ReturnType,
-				/* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
-				(ec.InUnsafe ? Modifiers.UNSAFE : 0) |
-				(ec.IsStatic ? Modifiers.STATIC : 0),
-				/* No constructor */ false);
+			Report.Debug (64, "COMPATIBLE", this, Parent, GenericMethod, Host,
+				      Container, Block, invoke_mb.ReturnType, delegate_type,
+				      delegate_type.IsGenericType, loc);
 
-			aec.CurrentAnonymousMethod = this;
-			ContainerAnonymousMethod = ec.CurrentAnonymousMethod;
-			ContainingBlock = ec.CurrentBlock;
+			anonymous = new AnonymousMethod (
+				Parent != null ? Parent.AnonymousMethod : null, Host,
+				GenericMethod, parameters, Container, Block, invoke_mb.ReturnType,
+				delegate_type, loc);
 
-			if (aec.ResolveTopBlock (ec, Block, Parameters, null, out unreachable)){
-				anonymous_delegate = new AnonymousDelegate (
-					this, delegate_type, loc).Resolve (ec);
-				return anonymous_delegate;
-			}
-			return null;
+			if (!anonymous.Resolve (ec))
+				return null;
+
+			return anonymous.AnonymousDelegate;
 		}
 
 		public override Expression DoResolve (EmitContext ec)
 		{
-			if (!ec.IsAnonymousMethodAllowed) {
-				Report.Error (1706, loc, "Anonymous methods are not allowed in the attribute declaration");
-				return null;
-			}
+			//
+			// Set class type, set type
+			//
 
-			if (Parameters != null && !Parameters.Resolve (ec)) {
+			eclass = ExprClass.Value;
+
+			//
+			// This hack means `The type is not accessible
+			// anywhere', we depend on special conversion
+			// rules.
+			// 
+			type = TypeManager.anonymous_method_type;
+
+			if ((Parameters != null) && !Parameters.Resolve (ec))
 				return null;
-			}
 
-			return base.DoResolve (ec);
+			return this;
 		}
 
+		public override void Emit (EmitContext ec)
+		{
+			// nothing, as we only exist to not do anything.
+		}
 
-		public override string ExprClassName {
-			get {
-				return "anonymous method";
-			}
+		public bool IsIterator {
+			get { return false; }
 		}
+	}
 
-		public MethodInfo GetMethodBuilder ()
+	public abstract class AnonymousContainer : IAnonymousContainer
+	{
+		// Used to generate unique method names.
+		protected static int anonymous_method_count;
+
+		public readonly Location Location;
+
+		// An array list of AnonymousMethodParameter or null
+		public readonly Parameters Parameters;
+
+		//
+		// The block that makes up the body for the anonymous mehtod
+		//
+		public readonly ToplevelBlock Block;
+
+		public readonly Type ReturnType;
+		public readonly TypeContainer Host;
+
+		//
+		// The implicit method we create
+		//
+		protected Method method;
+		protected EmitContext aec;
+
+		// The emit context for the anonymous method
+		protected bool unreachable;
+		protected readonly Location loc;
+		protected readonly ToplevelBlock container;
+		protected readonly GenericMethod generic;
+		protected readonly AnonymousMethodHost root_scope;
+
+		//
+		// Points to our container anonymous method if its present
+		//
+		public readonly AnonymousContainer ContainerAnonymousMethod;
+
+		protected AnonymousContainer (AnonymousContainer parent, TypeContainer host,
+					      GenericMethod generic, Parameters parameters,
+					      ToplevelBlock container, ToplevelBlock block,
+					      Type return_type, int mod, Location loc)
 		{
-			MethodInfo builder = method.MethodBuilder;
-			if (TypeArguments != null)
-				return builder.MakeGenericMethod (TypeArguments);
-			else
-				return builder;
+			this.ContainerAnonymousMethod = parent;
+			this.ReturnType = return_type;
+			this.Host = host;
+
+			this.container = container;
+			this.generic = parent != null ? null : generic;
+			this.root_scope = container.AnonymousMethodHost;
+			this.Parameters = parameters;
+			this.Block = block;
+			this.loc = loc;
 		}
 
-		public override string GetSignatureForError ()
+#if FIXME
+		protected AnonymousContainer (TypeContainer host, GenericMethod generic,
+					      Parameters parameters, ToplevelBlock container,
+					      int mod, Location loc)
+			: this (null, generic, host, parameters, container, null, mod, loc)
 		{
-			string s = TypeManager.CSharpSignature (invoke_mb);
-			return s.Substring (0, s.IndexOf (".Invoke("));
+			Block = new ToplevelBlock (container, parameters, loc);
+			Block.SetHaveAnonymousMethods (loc, this);
 		}
-		
-		public bool EmitMethod (EmitContext ec)
+#endif
+
+		public Method Method {
+			get { return method; }
+		}
+
+		public virtual AnonymousMethodHost RootScope {
+			get { return root_scope; }
+		}
+
+		public ScopeInfo Scope {
+			get { return ContainerCaptureContext.Scope; }
+		}
+
+		public string GetSignatureForError ()
 		{
-			if (!CreateMethodHost (ec))
+			return RootScope.GetSignatureForError ();
+		}
+
+		protected virtual CaptureContext ContainerCaptureContext {
+			get { return Container.CaptureContext; }
+		}
+
+		protected virtual CaptureContext CaptureContext {
+			get { return Block.CaptureContext; }
+		}
+
+		public virtual bool Resolve (EmitContext ec)
+		{
+			if (!ec.IsAnonymousMethodAllowed) {
+				Report.Error (1706, loc,
+					      "Anonymous methods are not allowed in the " +
+					      "attribute declaration");
 				return false;
+			}
 
-			MethodBuilder builder = method.MethodBuilder;
-			ILGenerator ig = builder.GetILGenerator ();
-			aec.ig = ig;
+			Report.Debug (64, "RESOLVE ANONYMOUS METHOD", this, loc, ec,
+				      RootScope, Parameters, ec.IsStatic);
 
-			Parameters.ApplyAttributes (builder);
+			aec = new EmitContext (
+				ec.ResolveContext, ec.TypeContainer, RootScope, loc, null, ReturnType,
+				/* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
+				(ec.InUnsafe ? Modifiers.UNSAFE : 0), /* No constructor */ false);
 
-			//
-			// Adjust based on the computed state of the
-			// method from CreateMethodHost
-			
-			aec.MethodIsStatic = (method_modifiers & Modifiers.STATIC) != 0;
-			
-			aec.EmitMeta (Block);
-			aec.EmitResolvedTopBlock (Block, unreachable);
+			aec.capture_context = CaptureContext;
+			aec.CurrentAnonymousMethod = this;
+
+			Report.Debug (64, "RESOLVE ANONYMOUS METHOD #1", this, loc, ec, aec,
+				      RootScope, Parameters, Block, Block.CaptureContext);
+
+			bool unreachable;
+			if (!aec.ResolveTopBlock (ec, Block, Parameters, null, out unreachable))
+				return false;
+
+			Report.Debug (64, "RESOLVE ANONYMOUS METHOD #3", this, ec, aec, Block,
+				      ec.capture_context);
+
+			ContainerCaptureContext.ComputeMethodHost ();
+
+			Report.Debug (64, "RESOLVE ANONYMOUS METHOD #4", this, Scope);
+
+			if (Scope == null)
+				throw new InternalErrorException ();
+
+			method = DoCreateMethodHost (ec);
+
 			return true;
 		}
 
-		public override void CreateScopeType (EmitContext ec, ScopeInfo scope)
+		protected abstract Method DoCreateMethodHost (EmitContext ec);
+
+		public ToplevelBlock Container {
+			get { return container; }
+		}
+
+		public GenericMethod GenericMethod {
+			get { return generic; }
+		}
+
+		public abstract bool IsIterator {
+			get;
+		}
+
+#if FIXME
+		public override string ToString ()
 		{
-			TypeBuilder container = ec.TypeContainer.TypeBuilder;
-			string name = String.Format ("<>AnonHelp<{0}>", scope.id);
+			return String.Format ("{0} ({1})", GetType (), Name);
+		}
+#endif
 
-			scope.ScopeTypeBuilder = container.DefineNestedType (name,
-				TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit | TypeAttributes.NestedPrivate,
-					 TypeManager.object_type);
+		protected class AnonymousMethodMethod : Method
+		{
+			public AnonymousContainer AnonymousMethod;
 
-			Type [] constructor_types = Type.EmptyTypes;
-			ConstructorBuilder ctor = scope.ScopeTypeBuilder.DefineConstructor (
-				MethodAttributes.Public | MethodAttributes.HideBySig |
-				MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
-				CallingConventions.HasThis, constructor_types);
-			TypeManager.RegisterMethod (ctor, Parameters.EmptyReadOnlyParameters);
+			public AnonymousMethodMethod (AnonymousContainer am, GenericMethod generic,
+						      TypeExpr return_type, int mod, MemberName name,
+						      Parameters parameters)
+				: base (am.RootScope, generic, return_type, mod, false,
+					name, parameters, null)
+			{
+				this.AnonymousMethod = am;
 
-			ILGenerator cig = ctor.GetILGenerator ();
-			cig.Emit (OpCodes.Ldarg_0);
-			cig.Emit (OpCodes.Call, TypeManager.object_ctor);
-			cig.Emit (OpCodes.Ret);
+				am.RootScope.CheckMembersDefined ();
+				am.Scope.AddMethod (this);
+				Block = am.Block;
+			}
 
-			if (ec.TypeContainer.IsGeneric) {
-				TypeParameter[] tparam = ec.TypeContainer.TypeParameters;
-				string[] names = new string [tparam.Length];
-				Type[] types = new Type [tparam.Length];
+			public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
+			{
+				EmitContext aec = AnonymousMethod.aec;
+				aec.ig = ig;
+				return aec;
+			}
+		}
+	}
 
-				for (int i = 0; i < names.Length; i++) {
-					names [i] = tparam [i].Name;
-					types [i] = tparam [i].Type;
-				}
+	public class AnonymousMethod : AnonymousContainer
+	{
+		public readonly Type DelegateType;
 
-				scope.ScopeTypeBuilder.DefineGenericParameters (names);
-				scope.ScopeTypeBuilder.GetGenericTypeDefinition ();
+		//
+		// The value return by the Compatible call, this ensure that
+		// the code works even if invoked more than once (Resolve called
+		// more than once, due to the way Convert.ImplicitConversion works
+		//
+		Expression anonymous_delegate;
 
-				scope.ScopeType = scope.ScopeTypeBuilder.MakeGenericType (types);
+		public AnonymousMethod (AnonymousMethod parent, TypeContainer host,
+					GenericMethod generic, Parameters parameters,
+					ToplevelBlock container, ToplevelBlock block,
+					Type return_type, Type delegate_type, Location loc)
+			: base (parent, host, generic, parameters, container, block,
+				return_type, 0, loc)
+		{
+			this.DelegateType = delegate_type;
+
+			// Container.CaptureContext.RegisterScope (RootScope);
+		}
+
+		public override bool IsIterator {
+			get { return false; }
+		}
+
+		public Expression AnonymousDelegate {
+			get { return anonymous_delegate; }
+		}
+
+		//
+		// Creates the host for the anonymous method
+		//
+		protected override Method DoCreateMethodHost (EmitContext ec)
+		{
+			string name = "<>c__AnonymousMethod" + anonymous_method_count++;
+			MemberName member_name;
+
+			GenericMethod generic_method = null;
+			if (DelegateType.IsGenericType) {
+				TypeArguments args = new TypeArguments (loc);
+
+				Type[] tparam = TypeManager.GetTypeArguments (DelegateType);
+				for (int i = 0; i < tparam.Length; i++)
+					args.Add (new SimpleName (tparam [i].Name, loc));
+
+				member_name = new MemberName (name, args, loc);
+
+				generic_method = new GenericMethod (
+					Scope.NamespaceEntry, Scope, member_name,
+					new TypeExpression (ReturnType, loc), Parameters);
+
+				generic_method.SetParameterInfo (null);
 			} else
-				scope.ScopeType = scope.ScopeTypeBuilder;
+				member_name = new MemberName (name, loc);
 
+			return new AnonymousMethodMethod (
+				this, generic_method, new TypeExpression (ReturnType, loc),
+				Modifiers.INTERNAL, member_name, Parameters);
+		}
 
-			if (ec.TypeContainer.IsGeneric)
-				scope.ScopeConstructor = TypeBuilder.GetConstructor (
-					scope.ScopeType, ctor);
-			else
-				scope.ScopeConstructor = ctor;
+		public override bool Resolve (EmitContext ec)
+		{
+			if (!base.Resolve (ec))
+				return false;
+
+			anonymous_delegate = new AnonymousDelegate (this, DelegateType, loc).Resolve (ec);
+			if (anonymous_delegate == null)
+				return false;
+
+			return true;
 		}
 
+		public MethodInfo GetMethodBuilder (EmitContext ec)
+		{
+			MethodInfo builder = method.MethodBuilder;
+			if (RootScope.IsGeneric) {
+				MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookup (
+					ec.ContainerType, RootScope.ScopeType, builder.Name, loc);
+
+				if (mg == null)
+					throw new InternalErrorException ();
+				builder = (MethodInfo) mg.Methods [0];
+			}
+
+			if (!DelegateType.IsGenericType)
+				return builder;
+
+			Type[] targs = TypeManager.GetTypeArguments (DelegateType);
+			return builder.MakeGenericMethod (targs);
+		}
+
 		public static void Error_AddressOfCapturedVar (string name, Location loc)
 		{
 			Report.Error (1686, loc,
-				"Local variable `{0}' or its members cannot have their address taken and be used inside an anonymous method block",
-				name);
+				      "Local variable `{0}' or its members cannot have their " +
+				      "address taken and be used inside an anonymous method block",
+				      name);
 		}
 	}
 
@@ -573,69 +1185,41 @@
 		
 		public override void Emit (EmitContext ec)
 		{
-			if (!am.EmitMethod (ec))
-				return;
+			Report.Debug (64, "ANONYMOUS DELEGATE", this, am, ec.ContainerType, type,
+				      ec, ec.capture_context, loc);
 
 			//
 			// Now emit the delegate creation.
 			//
-			if ((am.method.ModFlags & Modifiers.STATIC) == 0)
-				delegate_instance_expression = new AnonymousInstance (am);
-			
+			if ((am.Method.ModFlags & Modifiers.STATIC) == 0) {
+				delegate_instance_expression = am.RootScope.GetScopeInitializer (ec);
+				Report.Debug (64, "ANONYMOUS DELEGATE #0", this,
+					      delegate_instance_expression);
+
+				if (delegate_instance_expression == null)
+					throw new InternalErrorException ();
+			}
+
 			Expression ml = Expression.MemberLookup (ec.ContainerType, type, ".ctor", loc);
 			constructor_method = ((MethodGroupExpr) ml).Methods [0];
-			delegate_method = am.GetMethodBuilder ();
+			delegate_method = am.GetMethodBuilder (ec);
+			Report.Debug (64, "ANONYMOUS DELEGATE #1", constructor_method, delegate_method,
+				      delegate_method.GetType (), delegate_instance_expression);
 			base.Emit (ec);
 		}
-
-		class AnonymousInstance : Expression {
-			AnonymousMethod am;
-			
-			public AnonymousInstance (AnonymousMethod am)
-			{
-				this.am = am;
-				eclass = ExprClass.Value;
-			}
-
-			public override Expression DoResolve (EmitContext ec)
-			{
-				return this;
-			}
-			
-			public override void Emit (EmitContext ec)
-			{
-				am.aec.EmitMethodHostInstance (ec, am);
-			}
-		}
 	}
 
-	class CapturedParameter {
-		public Type Type;
-		public FieldBuilder FieldBuilder;
-		public int Idx;
-
-		public CapturedParameter (Type type, int idx)
-		{
-			Type = type;
-			Idx = idx;
-		}
-	}
-
 	//
 	// Here we cluster all the variables captured on a given scope, we also
 	// keep some extra information that might be required on each scope.
 	//
-	public class ScopeInfo {
-		public CaptureContext CaptureContext;
+	public class ScopeInfo : ScopeInfoBase {
 		public ScopeInfo ParentScope;
 		public Block ScopeBlock;
-		public bool NeedThis = false;
-		public bool HostsParameters = false;
 		
 		// For tracking the number of scopes created.
 		public int id;
 		static int count;
-		bool inited = false;
 		
 		ArrayList locals = new ArrayList ();
 		ArrayList children = new ArrayList ();
@@ -643,40 +1227,59 @@
 		//
 		// The types and fields generated
 		//
-		public TypeBuilder ScopeTypeBuilder;
-		public Type ScopeType;
-		public ConstructorInfo ScopeConstructor;
-		public FieldBuilder THIS;
-		public FieldBuilder ParentLink;
+		public readonly Location loc;
 
-		//
-		// Points to the object of type `ScopeTypeBuilder' that
-		// holds the data for the scope
-		//
-		LocalBuilder scope_instance;
-		
-		public ScopeInfo (CaptureContext cc, Block b)
+		public ScopeInfo (CaptureContext cc, Block block)
+			: base (cc.Host.RootScope, cc.Host.GenericMethod,
+				Modifiers.PUBLIC, cc.loc)
 		{
 			CaptureContext = cc;
-			ScopeBlock = b;
+			ScopeBlock = block;
+			loc = cc.loc;
 			id = count++;
 
+			Report.Debug (64, "NEW SCOPE", this);
+
 			cc.RegisterCaptureContext ();
+
+#if FIXME
+			if (!Define ())
+				throw new InternalErrorException ();
+			if (DefineType () == null)
+				throw new InternalErrorException ();
+#endif
 		}
 
-		public void AddLocal (LocalInfo li)
+		public ScopeInfo (CaptureContext cc, ToplevelBlock toplevel, TypeContainer parent,
+				  GenericMethod generic)
+			: base (parent, generic, 0, toplevel.StartLocation)
 		{
-			if (locals.Contains (li))
-				return;
+			CaptureContext = cc;
+			ScopeBlock = toplevel;
+			loc = cc.loc;
+			id = count++;
 
-			locals.Add (li);
-}
-	
-		public bool IsCaptured (LocalInfo li)
+			Report.Debug (64, "NEW ROOT SCOPE", this);
+
+			cc.RegisterCaptureContext ();
+		}
+
+		public override AnonymousMethodHost Host {
+			get { return CaptureContext.Host.RootScope; }
+		}
+
+		public Variable AddLocal (LocalInfo local)
 		{
-			return locals.Contains (li);
+			CapturedLocal cl = new CapturedLocal (this, local);
+			locals.Add (cl);
+			return cl;
 		}
-		
+
+		public Variable AddParameter (Parameter par, int idx)
+		{
+			return new CapturedParameter (this, par, idx);
+		}
+
 		internal void AddChild (ScopeInfo si)
 		{
 			if (children.Contains (si))
@@ -703,7 +1306,7 @@
 					children.Remove (child);
 				}
 			}
-		} 
+		}
 
 		static int indent = 0;
 
@@ -719,8 +1322,6 @@
 			Pad ();
 			Console.WriteLine ("START");
 			indent++;
-			Pad ();
-			Console.WriteLine ("NeedThis=" + NeedThis);
 			foreach (LocalInfo li in locals){
 				Pad ();
 				Console.WriteLine ("var {0}", MakeFieldName (li.Name));
@@ -733,168 +1334,18 @@
 			Console.WriteLine ("END");
 		}
 
-		private string MakeFieldName (string local_name)
+		protected string MakeFieldName (string local_name)
 		{
 			return "<" + id + ":" + local_name + ">";
 		}
 
-		public void EmitScopeType (EmitContext ec)
-		{
-			// EmitDebug ();
+		bool resolved;
 
-			if (ScopeTypeBuilder != null)
-				return;
-			
-			Type container;
-			if (ec.TypeContainer.CurrentType != null)
-				container = ec.TypeContainer.CurrentType;
-			else
-				container = ec.TypeContainer.TypeBuilder;
-
-			CaptureContext.Host.CreateScopeType (ec, this);
-			
-			if (NeedThis)
-				THIS = ScopeTypeBuilder.DefineField ("<>THIS", container, FieldAttributes.Assembly);
-
-			if (ParentScope != null){
-				if (ParentScope.ScopeTypeBuilder == null){
-					throw new Exception (String.Format ("My parent has not been initialized {0} and {1}", ParentScope, this));
-				}
-
-				if (ParentScope.ScopeTypeBuilder != ScopeTypeBuilder)
-					ParentLink = ScopeTypeBuilder.DefineField (
-						"<>parent", ParentScope.ScopeType, FieldAttributes.Assembly);
-			}
-			
-			if (NeedThis && ParentScope != null)
-				throw new Exception ("I was not expecting THIS && having a parent");
-
-			foreach (LocalInfo info in locals)
-				info.FieldBuilder = ScopeTypeBuilder.DefineField (
-					MakeFieldName (info.Name), info.VariableType, FieldAttributes.Assembly);
-
-			if (HostsParameters){
-				Hashtable captured_parameters = CaptureContext.captured_parameters;
-				
-				foreach (DictionaryEntry de in captured_parameters){
-					string name = (string) de.Key;
-					CapturedParameter cp = (CapturedParameter) de.Value;
-					FieldBuilder fb;
-					
-					fb = ScopeTypeBuilder.DefineField ("<p:" + name + ">", cp.Type, FieldAttributes.Assembly);
-					cp.FieldBuilder = fb;
-				}
-			}
-
-			foreach (ScopeInfo si in children){
-				si.EmitScopeType (ec);
-			}
-		}
-
-		public void CloseTypes ()
+		protected override ScopeInitializerBase CreateScopeInitializer ()
 		{
-			RootContext.RegisterCompilerGeneratedType (ScopeTypeBuilder);
-			foreach (ScopeInfo si in children)
-				si.CloseTypes ();
+			return new ScopeInitializer (this);
 		}
 
-		//
-		// Emits the initialization code for the scope
-		//
-		public void EmitInitScope (EmitContext ec)
-		{
-			ILGenerator ig = ec.ig;
-
-			if (inited)
-				return;
-
-			if (ScopeConstructor == null)
-				throw new Exception ("ScopeConstructor is null for" + this.ToString ());
-			
-			if (!CaptureContext.Host.IsIterator) {
-				scope_instance = ig.DeclareLocal (ScopeType);
-				ig.Emit (OpCodes.Newobj, ScopeConstructor);
-				ig.Emit (OpCodes.Stloc, scope_instance);
-			}
-
-			if (THIS != null){
-				if (CaptureContext.Host.IsIterator) {
-					ig.Emit (OpCodes.Ldarg_0);
-					ig.Emit (OpCodes.Ldarg_1);
-				} else {
-					ig.Emit (OpCodes.Ldloc, scope_instance);
-					ig.Emit (OpCodes.Ldarg_0);
-				}
-				ig.Emit (OpCodes.Stfld, THIS);
-			}
-
-			//
-			// Copy the parameter values, if any
-			//
-			int extra = ec.IsStatic ? 0 : 1;
-			if (CaptureContext.Host.IsIterator)
-				extra++;
-			if (HostsParameters){
-				Hashtable captured_parameters = CaptureContext.captured_parameters;
-				
-				foreach (DictionaryEntry de in captured_parameters){
-					CapturedParameter cp = (CapturedParameter) de.Value;
-
-					EmitScopeInstance (ig);
-					ParameterReference.EmitLdArg (ig, cp.Idx + extra);
-					ig.Emit (OpCodes.Stfld, cp.FieldBuilder);
-				}
-			}
-
-			if (ParentScope != null){
-				if (!ParentScope.inited)
-					ParentScope.EmitInitScope (ec);
-
-				if (ParentScope.ScopeTypeBuilder != ScopeTypeBuilder) {
-					//
-					// Only emit initialization in our capturecontext world
-					//
-					if (ParentScope.CaptureContext == CaptureContext){
-						EmitScopeInstance (ig);
-						ParentScope.EmitScopeInstance (ig);
-						ig.Emit (OpCodes.Stfld, ParentLink);
-					} else {
-						EmitScopeInstance (ig);
-						ig.Emit (OpCodes.Ldarg_0);
-						ig.Emit (OpCodes.Stfld, ParentLink);
-					}
-				}
-			}
-			inited = true;
-		}
-
-		public void EmitScopeInstance (ILGenerator ig)
-		{
-			if (CaptureContext.Host.IsIterator)
-				ig.Emit (OpCodes.Ldarg_0);
-			else {
-				if (scope_instance == null){
-					//
-					// This is needed if someone overwrites the Emit method
-					// of Statement and manually calls Block.Emit without
-					// this snippet first:
-					// 
-					//   ec.EmitScopeInitFromBlock (The_Block);
-					//   The_Block.Emit (ec);
-					// 
-
-					Console.WriteLine (
-				        	"The scope_instance has not been emitted, this typically means\n" +
-						"that inside the compiler someone is calling Block.Emit without\n" +
-						"first calling EmitScopeInitFromBlock for the block.  See compiler" +
-						"source code for an explanation");
-					throw new Exception ("Internal compiler error");
-					
-				}
-				ig.Emit (OpCodes.Ldloc, scope_instance);
-			}
-		}
-
 		public static void CheckCycles (string msg, ScopeInfo s)
 		{
 			ArrayList l = new ArrayList ();
@@ -935,6 +1386,174 @@
 
 			return sb.ToString ();
 		}
+
+		protected class CapturedParameter : Variable {
+			public readonly ScopeInfo Scope;
+			public readonly Parameter Parameter;
+			public readonly Field Field;
+			public readonly int Idx;
+
+			public FieldExpr FieldInstance;
+
+			public CapturedParameter (ScopeInfo scope, Parameter par, int idx)
+			{
+				this.Scope = scope;
+				this.Parameter = par;
+				this.Idx = idx;
+				Field = scope.CaptureVariable (
+					"<p:" + par.Name + ">", par.ParameterType);
+			}
+
+			public override Type Type {
+				get { return Field.MemberType; }
+			}
+
+			public override bool HasInstance {
+				get { return true; }
+			}
+
+			public override bool NeedsTemporary {
+				get { return true; }
+			}
+
+			protected FieldInfo GetField (EmitContext ec)
+			{
+				if ((Scope.Host is IteratorHost) ||
+				    (ec.capture_context != Scope.CaptureContext))
+					return Field.FieldBuilder;
+				else
+					return FieldInstance.FieldInfo;
+			}
+
+			public override void EmitInstance (EmitContext ec)
+			{
+				ec.capture_context.EmitParameterInstance (ec, Parameter);
+			}
+
+			public override void Emit (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldfld, GetField (ec));
+			}
+
+			public override void EmitAssign (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Stfld, GetField (ec));
+			}
+
+			public override void EmitAddressOf (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldflda, GetField (ec));
+			}
+
+			public override string ToString ()
+			{
+				return String.Format ("{0} ({1})", GetType (), Field);
+			}
+		}
+
+		protected class CapturedLocal : Variable {
+			public readonly ScopeInfo Scope;
+			public readonly LocalInfo Local;
+			public readonly Field Field;
+
+			public FieldExpr FieldInstance;
+
+			public CapturedLocal (ScopeInfo scope, LocalInfo local)
+			{
+				this.Scope = scope;
+				this.Local = local;
+				Field = scope.CaptureVariable (
+					scope.MakeFieldName (local.Name), local.VariableType);
+			}
+
+			public override Type Type {
+				get { return Field.MemberType; }
+			}
+
+			public override bool HasInstance {
+				get { return true; }
+			}
+
+			public override bool NeedsTemporary {
+				get { return true; }
+			}
+
+			public override void EmitInstance (EmitContext ec)
+			{
+				ec.capture_context.EmitCapturedVariableInstance (
+					ec, Local.Block, ec.CurrentAnonymousMethod);
+			}
+
+			public override void Emit (EmitContext ec)
+			{
+				if (ec.capture_context == Scope.CaptureContext)
+					ec.ig.Emit (OpCodes.Ldfld, FieldInstance.FieldInfo);
+				else
+					ec.ig.Emit (OpCodes.Ldfld, Field.FieldBuilder);
+			}
+
+			public override void EmitAssign (EmitContext ec)
+			{
+				if (ec.capture_context == Scope.CaptureContext)
+					ec.ig.Emit (OpCodes.Stfld, FieldInstance.FieldInfo);
+				else
+					ec.ig.Emit (OpCodes.Stfld, Field.FieldBuilder);
+			}
+
+			public override void EmitAddressOf (EmitContext ec)
+			{
+				if (ec.capture_context == Scope.CaptureContext)
+					ec.ig.Emit (OpCodes.Ldflda, FieldInstance.FieldInfo);
+				else
+					ec.ig.Emit (OpCodes.Ldflda, Field.FieldBuilder);
+			}
+		}
+
+		protected class ScopeInitializer : ScopeInitializerBase
+		{
+			ScopeInfo scope;
+
+			public ScopeInitializer (ScopeInfo scope)
+				: base (scope)
+			{
+				this.scope = scope;
+			}
+
+			new public ScopeInfo Scope {
+				get { return scope; }
+			}
+
+			protected override bool DoResolveInternal (EmitContext ec)
+			{
+				Report.Debug (64, "RESOLVE SCOPE INITIALIZER", this, Scope,
+					      Scope.ParentScope, Scope.ScopeType, ec,
+					      ec.TypeContainer.Name, ec.DeclContainer,
+					      ec.DeclContainer.Name, ec.DeclContainer.IsGeneric);
+
+				foreach (CapturedLocal local in Scope.locals) {
+					FieldExpr fe = (FieldExpr) Expression.MemberLookup (
+						ec.ContainerType, type, local.Field.Name, loc);
+					Report.Debug (64, "RESOLVE SCOPE INITIALIZER #2", this, Scope,
+						      Scope, ec, ec.ContainerType, type,
+						      local.Field, local.Field.Name, loc, fe);
+					if (fe == null)
+						throw new InternalErrorException ();
+
+					fe.InstanceExpression = this;
+					local.FieldInstance = fe;
+				}
+
+				return base.DoResolveInternal (ec);
+			}
+
+			protected virtual void EmitParameterReference (EmitContext ec,
+								       CapturedParameter cp)
+			{
+				int extra = ec.IsStatic ? 0 : 1;
+				ParameterReference.EmitLdArg (ec.ig, cp.Idx + extra);
+			}
+
+		}
 	}
 
 	//
@@ -952,7 +1571,8 @@
 		//
 		// Points to the toplevel block that owns this CaptureContext
 		//
-		ToplevelBlock toplevel_owner;
+		public readonly ToplevelBlock ToplevelOwner;
+		public readonly IAnonymousContainer Host;
 
 		//
 		// All the scopes we capture
@@ -965,25 +1585,23 @@
 		ArrayList roots = new ArrayList ();
 		
 		bool have_captured_vars = false;
-		bool referenced_this = false;
 
 		//
 		// Captured fields
 		//
 		Hashtable captured_fields = new Hashtable ();
 		Hashtable captured_variables = new Hashtable ();
-		public Hashtable captured_parameters = new Hashtable ();
-		public AnonymousContainer Host;
-		
+		internal Hashtable captured_parameters = new Hashtable ();
+
 		public CaptureContext (ToplevelBlock toplevel_owner, Location loc,
-				       AnonymousContainer host)
+				       IAnonymousContainer host)
 		{
 			cc_id = count++;
-			this.toplevel_owner = toplevel_owner;
+			this.ToplevelOwner = toplevel_owner;
+			this.Host = host;
 			this.loc = loc;
 
-			if (host != null)
-				Host = host;
+			Report.Debug (64, "NEW CAPTURE CONTEXT", this, toplevel_owner, loc);
 		}
 
 		void DoPath (StringBuilder sb, CaptureContext cc)
@@ -995,17 +1613,6 @@
 			sb.Append (cc.cc_id.ToString ());
 		}
 
-		public void ReParent (ToplevelBlock new_toplevel, AnonymousContainer new_host)
-		{
-			toplevel_owner = new_toplevel;
-			Host = new_host;
-
-			for (CaptureContext cc = ParentCaptureContext; cc != null;
-			     cc = cc.ParentCaptureContext) {
-				cc.Host = new_host;
-			}
-		}
-		
 		public override string ToString ()
 		{
 			StringBuilder sb = new StringBuilder ();
@@ -1017,7 +1624,7 @@
 
 		public ToplevelBlock ParentToplevel {
 			get {
-				return toplevel_owner.Container;
+				return ToplevelOwner.Container;
 			}
 		}
 
@@ -1029,124 +1636,264 @@
 			}
 		}
 
-		ScopeInfo GetScopeForBlock (Block block)
+		// The method scope
+		ScopeInfo method_scope;
+		bool computed_method_scope = false;
+		
+		//
+		// Track the scopes that this method has used.  At the
+		// end this is used to determine the ScopeInfo that will
+		// host the method
+		//
+		ArrayList scopes_used = new ArrayList ();
+		
+		public void RegisterScope (ScopeInfo scope)
 		{
+			if (scopes_used.Contains (scope))
+				return;
+			scopes_used.Add (scope);
+		}
+
+		// Returns the deepest of two scopes
+		ScopeInfo Deepest (ScopeInfo a, ScopeInfo b)
+		{
+			ScopeInfo p;
+
+			Report.Debug (64, "DEEPEST", this, a, a.ParentScope, b, b.ParentScope);
+
+			if (a == null)
+				return b;
+			if (b == null)
+				return a;
+			if (a == b)
+				return a;
+
+			//
+			// If they Scopes are on the same CaptureContext, we do the double
+			// checks just so if there is an invariant change in the future,
+			// we get the exception at the end
+			//
+			for (p = a; p != null; p = p.ParentScope)
+				if (p == b)
+					return a;
+			
+			for (p = b; p != null; p = p.ParentScope)
+				if (p == a)
+					return b;
+
+			CaptureContext ca = a.CaptureContext;
+			CaptureContext cb = b.CaptureContext;
+
+			for (CaptureContext c = ca; c != null; c = c.ParentCaptureContext)
+				if (c == cb)
+					return a;
+
+			for (CaptureContext c = cb; c != null; c = c.ParentCaptureContext)
+				if (c == ca)
+					return b;
+			throw new Exception ("Should never be reached");
+		}
+
+		//
+		// Determines the proper host for a method considering the
+		// scopes it references
+		//
+		public void ComputeMethodHost ()
+		{
+			Report.Debug (64, "COMPUTE METHOD HOST", this, computed_method_scope,
+				      method_scope, scopes_used);
+
+			if (computed_method_scope)
+				return;
+
+			LinkScopes ();
+			
+			method_scope = null;
+			int top = scopes_used.Count;
+			computed_method_scope = true;
+
+			if (top == 0)
+				return;
+			
+			method_scope = (ScopeInfo) scopes_used [0];
+			if (top == 1)
+				return;
+
+			Report.Debug (64, "COMPUTE METHOD HOST #1", this, method_scope,
+				      scopes_used);
+			
+			for (int i = 1; i < top; i++)
+				method_scope = Deepest (method_scope, (ScopeInfo) scopes_used [i]);
+		}
+
+		public ScopeInfo Scope {
+			get {
+				if (computed_method_scope)
+					return method_scope;
+
+				//
+				// This means that ComputeMethodHost is not being called, most
+				// likely by someone who overwrote the CreateMethodHost method
+				//
+				throw new InternalErrorException (
+					"AnonymousContainer.Scope is being used before its " +
+					"container is computed");
+			}
+		}
+
+		internal AnonymousMethodHost CreateRootScope (TypeContainer parent, GenericMethod generic)
+		{
+			Report.Debug (64, "CREATE ROOT SCOPE", this, parent.Name, ToplevelOwner,
+				      ToplevelOwner.ScopeInfo);
+
+			AnonymousMethodHost root_scope = new AnonymousMethodHost (
+				this, ToplevelOwner, parent, generic);
+			AddRootScope (root_scope);
+			return root_scope;
+		}
+
+		internal void AddRootScope (ScopeInfo root_scope)
+		{
+			if (ToplevelOwner.ScopeInfo != null)
+				throw new InternalErrorException ();
+
+			ToplevelOwner.ScopeInfo = root_scope;
+			scopes.Add (ToplevelOwner.ID, root_scope);
+			RegisterScope (root_scope);
+		}
+
+		internal ScopeInfo GetScopeForBlock (Block block)
+		{
+			while (block.Implicit)
+				block = block.Parent;
+
 			ScopeInfo si = (ScopeInfo) scopes [block.ID];
+			Report.Debug (64, "GET SCOPE FOR BLOCK", this, block,
+				      block.ScopeInfo, block.Parent, si);
 			if (si != null)
 				return si;
-			si = new ScopeInfo (this, block);
+
+			block.ScopeInfo = si = new ScopeInfo (this, block);
 			scopes [block.ID] = si;
 			return si;
 		}
-		
-		public void AddLocal (AnonymousContainer am, LocalInfo li)
+
+		public Variable AddLocal (LocalInfo li)
 		{
-			if (li.Block.Toplevel != toplevel_owner){
-				ParentCaptureContext.AddLocal (am, li);
-				return;
-			}
+			Report.Debug (64, "ADD LOCAL", this, li.Name, loc, li.Block,
+				      li.Block.Toplevel, ToplevelOwner);
+
+			if (li.Block.Toplevel != ToplevelOwner)
+				return ParentCaptureContext.AddLocal (li);
+
 			ScopeInfo scope = GetScopeForBlock (li.Block);
 
 			//
 			// Adjust the owner
 			//
-			if (Host != null)
-				Host.RegisterScope (scope);
+			RegisterScope (scope);
 
+#if FIXME
 			//
 			// Adjust the user
 			//
 			am.RegisterScope (scope);
-			
-			if (captured_variables [li] != null)
-				return;
-			
+#endif
+
+			Variable var = (Variable) captured_variables [li];
+			Report.Debug (64, "ADD LOCAL #1", this, li.Name, scope, var);
+			if (var == null) {
+				var = scope.AddLocal (li);
+				captured_variables.Add (li, var);
+			}
+
 			have_captured_vars = true;
-			captured_variables [li] = li;
-			scope.AddLocal (li);
+			return var;
 		}
 
 		//
-		// Retursn the CaptureContext for the block that defines the parameter `name'
+		// Returns the CaptureContext for the block that defines the parameter `name'
 		//
-		static CaptureContext _ContextForParameter (ToplevelBlock current, string name)
+		static CaptureContext _ContextForParameter (ToplevelBlock current, Parameter par)
 		{
 			ToplevelBlock container = current.Container;
 			if (container != null){
-				CaptureContext cc = _ContextForParameter (container, name);
+				CaptureContext cc = _ContextForParameter (container, par);
 				if (cc != null)
 					return cc;
 			}
-			if (current.IsParameterReference (name))
+			if (current.IsParameterReference (par.Name))
 				return current.ToplevelBlockCaptureContext;
 			return null;
 		}
 
-		static CaptureContext ContextForParameter (ToplevelBlock current, string name)
+		static CaptureContext ContextForParameter (ToplevelBlock current, Parameter par)
 		{
-			CaptureContext cc = _ContextForParameter (current, name);
+			CaptureContext cc = _ContextForParameter (current, par);
 			if (cc == null)
-				throw new Exception (String.Format ("request for parameteter {0} failed: not found", name));
+				throw new InternalErrorException (
+					"Request for parameteter {0} failed: not found", par.Name);
 			return cc;
 		}
-		
+
 		//
 		// Records the captured parameter at the appropriate CaptureContext
 		//
-		public void AddParameter (EmitContext ec, AnonymousContainer am,
-					  string name, Type t, int idx)
+		public Variable AddParameter (EmitContext ec, Parameter par, int idx)
 		{
-			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
-
-			cc.AddParameterToContext (am, name, t, idx);
+			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, par);
+			return cc.AddParameterToContext (par, idx);
 		}
 
 		//
 		// Records the parameters in the context
 		//
-		public void AddParameterToContext (AnonymousContainer am, string name, Type t, int idx)
+		public Variable AddParameterToContext (Parameter par, int idx)
 		{
 			if (captured_parameters == null)
 				captured_parameters = new Hashtable ();
-			if (captured_parameters [name] == null)
-				captured_parameters [name] = new CapturedParameter (t, idx);
 
-			ScopeInfo scope = GetScopeForBlock (toplevel_owner);
-			scope.HostsParameters = true;
-			am.RegisterScope (scope);
+			AnonymousMethodHost host = ToplevelOwner.AnonymousMethodHost;
+			host.HostsParameters = true;
+
+			Variable var = (Variable) captured_parameters [par];
+			if (var == null) {
+				var = host.AddParameter (par, idx);
+				captured_parameters.Add (par, var);
+			}
+
+			return var;
 		}
 
 		//
 		// Captured fields are only recorded on the topmost CaptureContext, because that
 		// one is the one linked to the owner of instance fields
 		//
-		public void AddField (EmitContext ec, AnonymousContainer am, FieldExpr fe)
+		public void AddField (EmitContext ec, FieldExpr fe)
 		{
 			if (fe.FieldInfo.IsStatic)
-				throw new Exception ("Attempt to register a static field as a captured field");
+				throw new InternalErrorException (
+					"Attempt to register a static field as a captured field");
+
 			CaptureContext parent = ParentCaptureContext;
 			if (parent != null) {
-				parent.AddField (ec, am, fe);
+				parent.AddField (ec, fe);
 				return;
 			}
 
-			ScopeInfo scope = GetScopeForBlock (toplevel_owner);
-			am.RegisterScope (scope);
+			ScopeInfo scope = GetScopeForBlock (ToplevelOwner);
+			RegisterScope (scope);
 		}
 
-		public void CaptureThis (AnonymousContainer am)
+		public void CaptureThis ()
 		{
-			if (am == null)
-				throw new Exception ("Internal Compiler error: Capturethis called with a null method");
 			CaptureContext parent = ParentCaptureContext;
 			if (parent != null) {
-				parent.CaptureThis (am);
+				parent.CaptureThis ();
 				return;
 			}
-			referenced_this = true;
 
-			ScopeInfo scope = GetScopeForBlock (toplevel_owner);
-			am.RegisterScope (scope);
+			Host.RootScope.CaptureThis ();
 		}
 
 		public bool HaveCapturedVariables {
@@ -1164,21 +1911,23 @@
 			}
 		}
 
-		public bool IsCaptured (LocalInfo local)
+		public Variable GetCapturedVariable (LocalInfo local)
 		{
-			foreach (ScopeInfo si in scopes.Values){
-				if (si.IsCaptured (local))
-					return true;
-			}
-			return false;
+			return (Variable) captured_variables [local];
 		}
 
+		public Variable GetCapturedParameter (Parameter par)
+		{
+			return (Variable) captured_parameters [par];
+		}
+
 		//
 		// Returns whether the parameter is captured
 		//
 		public bool IsParameterCaptured (string name)
 		{
-			if (ParentCaptureContext != null && ParentCaptureContext.IsParameterCaptured (name))
+			if ((ParentCaptureContext != null) &&
+			    ParentCaptureContext.IsParameterCaptured (name))
 				return true;
 			
 			if (captured_parameters != null)
@@ -1186,88 +1935,58 @@
 			return false;
 		}
 
-		public void EmitAnonymousHelperClasses (EmitContext ec)
+		public ExpressionStatement GetScopeInitializerForBlock (EmitContext ec, Block b)
 		{
-			if (roots.Count != 0){
-				foreach (ScopeInfo root in roots){
-					//
-					// FIXME: We really should do this in a per-ScopeInfo
-					// basis, instead of having the NeedThis applied to
-					// all of the roots.
-					//
-					root.NeedThis = HaveCapturedFields || referenced_this;
-					
-					root.EmitScopeType (ec);
-				}
-			} 
-		}
-
-		public void CloseAnonymousHelperClasses ()
-		{
-			if (roots.Count != 0)
-				foreach (ScopeInfo root in roots)
-					root.CloseTypes ();
-		}
-
-		public void EmitInitScope (EmitContext ec)
-		{
-			EmitAnonymousHelperClasses (ec);
-			if (roots.Count != 0)
-				foreach (ScopeInfo root in roots)
-					root.EmitInitScope (ec);		}
-
-		//
-		// This is called externally when we start emitting code for a block
-		// if the block has a ScopeInfo associated, emit the init code
-		//
-		public void EmitScopeInitFromBlock (EmitContext ec, Block b)
-		{
+			Report.Debug (64, "GET SCOPE INIT FOR BLOCK", this, Host, b);
 			ScopeInfo si = (ScopeInfo) scopes [b.ID];
 			if (si == null)
-				return;
+				return null;
 
-			si.EmitInitScope (ec);
+			Report.Debug (64, "GET SCOPE INIT FOR BLOCK #1", this, Host, b, si);
+			return si.GetScopeInitializer (ec);
 		}
 		
 		//
 		// Emits the opcodes necessary to load the instance of the captured
 		// variable in `li'
 		//
-		public void EmitCapturedVariableInstance (EmitContext ec, LocalInfo li,
+		public void EmitCapturedVariableInstance (EmitContext ec, Block block,
 							  AnonymousContainer am)
 		{
 			ILGenerator ig = ec.ig;
 			ScopeInfo si;
 
-			if (li.Block.Toplevel == toplevel_owner){
-				si = (ScopeInfo) scopes [li.Block.ID];
-				si.EmitScopeInstance (ig);
+			Report.Debug (64, "EMIT CAPTURED VARIABLE INSTANCE", this,
+				      am, block.ID, block.Toplevel.ID, ToplevelOwner.ID,
+				      block, block.Toplevel, ToplevelOwner);
+
+			while (block.Implicit)
+				block = block.Parent;
+
+			if (block.Toplevel == ToplevelOwner){
+				si = (ScopeInfo) scopes [block.ID];
+				si.EmitScopeInstance (ec);
 				return;
 			}
 
-			si = am.Scope;
+			Report.Debug (64, "EMIT CAPTURED VARIABLE INSTANCE #1", this,
+				      am, block.Toplevel, ToplevelOwner, am.Scope);
+
+			AnonymousMethodHost host = am.RootScope;
 			ig.Emit (OpCodes.Ldarg_0);
-			if (si != null){
-				if (am.IsIterator && (si.ScopeBlock.Toplevel == li.Block.Toplevel)) {
-					return;
-				}
+			if (host != null) {
+				Report.Debug (64, "EMIT CAPTURED VARIABLE INSTANCE #2", this,
+					      host, host.ParentLink, host.ScopeBlock,
+					      block, block.Toplevel);
 
-				while (si.ScopeBlock.ID != li.Block.ID){
-					if (si.ParentLink != null)
-						ig.Emit (OpCodes.Ldfld, si.ParentLink);
-					si = si.ParentScope;
-					if (si == null) {
-						si = am.Scope;
-						Console.WriteLine ("Target: {0} {1}", li.Block.ID, li.Name);
-						while (si.ScopeBlock.ID != li.Block.ID){
-							Console.WriteLine ("Trying: {0}", si.ScopeBlock.ID);
-							si = si.ParentScope;
-						}
-
-						throw new Exception (
-							     String.Format ("Never found block {0} starting at {1} while looking up {2}",
-									    li.Block.ID, am.Scope.ScopeBlock.ID, li.Name));
-					}
+				while (host.ScopeBlock.ID != block.ID){
+					if (host.ParentLink != null)
+						ig.Emit (OpCodes.Ldfld, host.ParentLink.FieldBuilder);
+					host = host.ParentHost;
+					if (host == null)
+						throw new InternalErrorException (
+							"Never found block {0} starting at {1}",
+							block.ID, am.RootScope.ScopeBlock.ID);
 				}
 			}
 		}
@@ -1275,135 +1994,34 @@
 		//
 		// Internal routine that loads the instance to reach parameter `name'
 		//
-		void EmitParameterInstance (EmitContext ec, string name)
+		public void EmitParameterInstance (EmitContext ec, Parameter par)
 		{
-			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
+			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, par);
 			if (cc != this){
-				cc.EmitParameterInstance (ec, name);
+				cc.EmitParameterInstance (ec, par);
 				return;
 			}
 
-			CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
-			if (par_info != null){
-				// 
-				// FIXME: implementing this.
-				//
+			if (ec.CurrentBlock.Toplevel == ToplevelOwner) {
+				ScopeInfo si = (ScopeInfo) scopes [ToplevelOwner.ID];
+				si.EmitScopeInstance (ec);
+				return;
 			}
-			ILGenerator ig = ec.ig;
 
-			ScopeInfo si;
+			AnonymousMethodHost host = ec.CurrentAnonymousMethod.RootScope;
+			ec.ig.Emit (OpCodes.Ldarg_0);
 
-			if (ec.CurrentBlock.Toplevel == toplevel_owner) {
-				si = (ScopeInfo) scopes [toplevel_owner.ID];
-				si.EmitScopeInstance (ig);
-			} else {
-				si = ec.CurrentAnonymousMethod.Scope;
-				ig.Emit (OpCodes.Ldarg_0);
-			}
-
-			if (si != null){
-				while (si.ParentLink != null) {
-					ig.Emit (OpCodes.Ldfld, si.ParentLink);
-					si = si.ParentScope;
+			if (host != null) {
+				while (host.ParentLink != null) {
+					ec.ig.Emit (OpCodes.Ldfld, host.ParentLink.FieldBuilder);
+					host = host.ParentHost;
 				} 
 			}
 		}
 
-		//
-		// Emits the code necessary to load the parameter named `name' within
-		// an anonymous method.
-		//
-		public void EmitParameter (EmitContext ec, string name, bool leave_copy, bool prepared, ref LocalTemporary temp)
-		{
-			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
-			if (cc != this){
-				cc.EmitParameter (ec, name, leave_copy, prepared, ref temp);
-				return;
-			}
-			if (!prepared)
-				EmitParameterInstance (ec, name);
-			CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
-			if (par_info != null){
-				// 
-				// FIXME: implementing this.
-				//
-			}
-			ec.ig.Emit (OpCodes.Ldfld, par_info.FieldBuilder);
-
-			if (leave_copy){
-				ec.ig.Emit (OpCodes.Dup);
-				temp = new LocalTemporary (par_info.FieldBuilder.FieldType);
-				temp.Store (ec);
-			}
-		}
-
-		//
-		// Implements the assignment of `source' to the paramenter named `name' within
-		// an anonymous method.
-		//
-		public void EmitAssignParameter (EmitContext ec, string name, Expression source, bool leave_copy, bool prepare_for_load, ref LocalTemporary temp)
-		{
-			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
-			if (cc != this){
-				cc.EmitAssignParameter (ec, name, source, leave_copy, prepare_for_load, ref temp);
-				return;
-			}
-			ILGenerator ig = ec.ig;
-			CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
-
-			EmitParameterInstance (ec, name);
-			if (prepare_for_load)
-				ig.Emit (OpCodes.Dup);
-			source.Emit (ec);
-			if (leave_copy){
-				ig.Emit (OpCodes.Dup);
-				temp = new LocalTemporary (par_info.FieldBuilder.FieldType);
-				temp.Store (ec);
-			}
-			ig.Emit (OpCodes.Stfld, par_info.FieldBuilder);
-			if (temp != null)
-				temp.Emit (ec);
-		}
-
-		//
-		// Emits the address for the parameter named `name' within
-		// an anonymous method.
-		//
-		public void EmitAddressOfParameter (EmitContext ec, string name)
-		{
-			CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
-			if (cc != this){
-				cc.EmitAddressOfParameter (ec, name);
-				return;
-			}
-			EmitParameterInstance (ec, name);
-			CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
-			ec.ig.Emit (OpCodes.Ldflda, par_info.FieldBuilder);
-		}
-
-		//
-		// The following methods are only invoked on the host for the
-		// anonymous method.
-		//
-		public void EmitMethodHostInstance (EmitContext target, AnonymousContainer am)
-		{
-			ILGenerator ig = target.ig;
-			ScopeInfo si = am.Scope;
-
-			AnonymousContainer container = am.ContainerAnonymousMethod;
-
-			if ((si == null) || ((container != null) && (si == container.Scope))) {
-				ig.Emit (OpCodes.Ldarg_0);
-				return;
-			}
-
-			si.EmitInitScope (target);
-			si.EmitScopeInstance (ig);
-		}
-
 		public void RegisterCaptureContext ()
 		{
-			toplevel_owner.RegisterCaptureContext (this);
+			ToplevelOwner.RegisterCaptureContext (this);
 		}
 
 		//
@@ -1412,7 +2030,10 @@
 		//
 		bool IsAncestor (ScopeInfo probe, ScopeInfo scope)
 		{
+			Report.Debug (64, "IS ANCESTOR", scope, scope.ScopeBlock,
+				      scope.ScopeBlock.Parent, probe, probe.ScopeBlock);
 			for (Block b = scope.ScopeBlock.Parent; b != null; b = b.Parent){
+				Report.Debug (64, "IS ANCESTOR #1", b, probe.ScopeBlock);
 				if (probe.ScopeBlock == b)
 					return true;
 			}
@@ -1474,7 +2095,7 @@
 			}
 			return parent;
 		}
-		
+
 		//
 		// Links all the scopes
 		//
@@ -1483,7 +2104,9 @@
 		{
 			if (linked)
 				return;
-			
+
+			Report.Debug (64, "LINK SCOPES", this, ParentCaptureContext);
+
 			linked = true;
 			if (ParentCaptureContext != null)
 				ParentCaptureContext.LinkScopes ();
@@ -1492,9 +2115,14 @@
 			ScopeInfo [] scope_list = new ScopeInfo [scope_count];
 			scopes.Values.CopyTo (scope_list, 0);
 
+			Report.Debug (64, "LINK SCOPES #1", this, scope_list);
+
 			for (int i = 0; i < scope_count; i++){
 				ScopeInfo parent = GetParentScope (scope_list [i], scope_list);
 
+				Report.Debug (64, "LINK SCOPES #2", this, scope_list, i,
+					      scope_list [i], parent);
+
 				if (parent == null){
 					roots.Add (scope_list [i]);
 					continue;
@@ -1504,17 +2132,28 @@
 				parent.AddChild (scope_list [i]);
 			}
 
+			Report.Debug (64, "LINK SCOPES #3", this, ParentCaptureContext, roots);
+
 			//
 			// Link the roots to their parent containers if any.
 			//
 			if (ParentCaptureContext != null && roots.Count != 0){
 				ScopeInfo one_root = (ScopeInfo) roots [0];
 				bool found = false;
-				
+
+				Report.Debug (64, "LINK SCOPES #4", this, one_root,
+					      ParentCaptureContext.roots);
+
 				foreach (ScopeInfo a_parent_root in ParentCaptureContext.roots){
+					Report.Debug (64, "LINK SCOPES #5", this, a_parent_root,
+						      one_root);
+
 					if (!IsAncestor (a_parent_root, one_root))
 						continue;
 
+					Report.Debug (64, "LINK SCOPES #6", this, a_parent_root,
+						      one_root, roots);
+
 					found = true;
 					
 					// Found, link all the roots to this root
@@ -1533,6 +2172,13 @@
 					throw new Exception ("Internal compiler error: Did not find the parent for the root in the chain");
 				}
 			}
+
+			foreach (ScopeInfo si in scope_list) {
+				if (!si.Define ())
+					throw new InternalErrorException ();
+				if (si.DefineType () == null)
+					throw new InternalErrorException ();
+			}
 		}
 	}
 }
Index: expression.cs
===================================================================
--- expression.cs	(revision 63019)
+++ expression.cs	(working copy)
@@ -3309,6 +3309,7 @@
 		bool is_readonly;
 		bool prepared;
 		LocalTemporary temp;
+		Variable variable;
 
 		public LocalVariableReference (Block block, string name, Location l)
 		{
@@ -3363,20 +3364,18 @@
 			if (!VerifyAssigned (ec))
 				return null;
 
-			if (ec.CurrentAnonymousMethod != null){
-				//
-				// If we are referencing a variable from the external block
-				// flag it for capturing
-				//
-				if ((local_info.Block.Toplevel != ec.CurrentBlock.Toplevel) ||
-				    ec.CurrentAnonymousMethod.IsIterator)
-				{
-					if (local_info.AddressTaken){
-						AnonymousMethod.Error_AddressOfCapturedVar (local_info.Name, loc);
-						return null;
-					}
-					ec.CaptureVariable (local_info);
+			//
+			// If we are referencing a variable from the external block
+			// flag it for capturing
+			//
+			if (ec.MustCaptureVariable (local_info)) {
+				if (local_info.AddressTaken){
+					AnonymousMethod.Error_AddressOfCapturedVar (local_info.Name, loc);
+					return null;
 				}
+
+				variable = ec.CaptureVariable (local_info);
+				type = variable.Type;
 			}
 
 			return this;
@@ -3439,90 +3438,56 @@
 			return Name == lvr.Name && Block == lvr.Block;
 		}
 
+		public Variable Variable {
+			get { return variable != null ? variable : local_info.Variable; }
+		}
+
 		public override void Emit (EmitContext ec)
 		{
-			ILGenerator ig = ec.ig;
-
-			if (local_info.FieldBuilder == null){
-				//
-				// A local variable on the local CLR stack
-				//
-				ig.Emit (OpCodes.Ldloc, local_info.LocalBuilder);
-			} else {
-				//
-				// A local variable captured by anonymous methods.
-				//
-				if (!prepared)
-					ec.EmitCapturedVariableInstance (local_info);
-				
-				ig.Emit (OpCodes.Ldfld, local_info.FieldBuilder);
-			}
+			Report.Debug (64, "EMIT LOCAL VARIABLE REFERENCE", this, ec, Variable, loc);
+			if (!prepared)
+				Variable.EmitInstance (ec);
+			Variable.Emit (ec);
 		}
 		
 		public void Emit (EmitContext ec, bool leave_copy)
 		{
 			Emit (ec);
-			if (leave_copy){
+			if (leave_copy) {
 				ec.ig.Emit (OpCodes.Dup);
-				if (local_info.FieldBuilder != null){
+				if (Variable.NeedsTemporary) {
 					temp = new LocalTemporary (Type);
 					temp.Store (ec);
 				}
 			}
 		}
-		
-		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+
+		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy,
+					bool prepare_for_load)
 		{
 			ILGenerator ig = ec.ig;
 			prepared = prepare_for_load;
 
-			if (local_info.FieldBuilder == null){
-				//
-				// A local variable on the local CLR stack
-				//
-				if (local_info.LocalBuilder == null)
-					throw new Exception ("This should not happen: both Field and Local are null");
-
-				source.Emit (ec);
-				if (leave_copy)
-					ec.ig.Emit (OpCodes.Dup);
-				ig.Emit (OpCodes.Stloc, local_info.LocalBuilder);
-			} else {
-				//
-				// A local variable captured by anonymous methods or itereators.
-				//
-				ec.EmitCapturedVariableInstance (local_info);
-
-				if (prepare_for_load)
-					ig.Emit (OpCodes.Dup);
-				source.Emit (ec);
-				if (leave_copy){
-					ig.Emit (OpCodes.Dup);
+			Variable.EmitInstance (ec);
+			if (prepare_for_load && Variable.HasInstance)
+				ig.Emit (OpCodes.Dup);
+			source.Emit (ec);
+			if (leave_copy) {
+				ig.Emit (OpCodes.Dup);
+				if (Variable.NeedsTemporary) {
 					temp = new LocalTemporary (Type);
 					temp.Store (ec);
 				}
-				ig.Emit (OpCodes.Stfld, local_info.FieldBuilder);
-				if (temp != null)
-					temp.Emit (ec);
 			}
+			Variable.EmitAssign (ec);
+			if (temp != null)
+				temp.Emit (ec);
 		}
 		
 		public void AddressOf (EmitContext ec, AddressOp mode)
 		{
-			ILGenerator ig = ec.ig;
-
-			if (local_info.FieldBuilder == null){
-				//
-				// A local variable on the local CLR stack
-				//
-				ig.Emit (OpCodes.Ldloca, local_info.LocalBuilder);
-			} else {
-				//
-				// A local variable captured by anonymous methods or iterators
-				//
-				ec.EmitCapturedVariableInstance (local_info);
-				ig.Emit (OpCodes.Ldflda, local_info.FieldBuilder);
-			}
+			Variable.EmitInstance (ec);
+			Variable.EmitAddressOf (ec);
 		}
 
 		public override string ToString ()
@@ -3562,6 +3527,7 @@
 		}
 
 		LocalTemporary temp;
+		Variable variable;
 		
 		public ParameterReference (Parameter par, Block block, int idx, Location loc)
 		{
@@ -3577,6 +3543,10 @@
 			get { return vi; }
 		}
 
+		public Variable Variable {
+			get { return variable != null ? variable : par.Variable; }
+		}
+
 		public bool VerifyFixed ()
 		{
 			// A parameter is fixed if it's a value parameter (i.e., no modifier like out, ref, param).
@@ -3636,15 +3606,6 @@
 						par.Name);
 					return false;
 				}
-
-				//
-				// If we are referencing the parameter from the external block
-				// flag it for capturing
-				//
-				//Console.WriteLine ("Is parameter `{0}' local? {1}", name, block.IsLocalParameter (name));
-				if (!block.Toplevel.IsLocalParameter (name)){
-					ec.CaptureParameter (name, type, idx);
-				}
 			}
 
 			return true;
@@ -3681,9 +3642,15 @@
 			if (!DoResolveBase (ec))
 				return null;
 
-			if (is_out && ec.DoFlowAnalysis && (!ec.OmitStructFlowAnalysis || !vi.TypeInfo.IsStruct) && !IsAssigned (ec, loc))
+			if (is_out && ec.DoFlowAnalysis &&
+			    (!ec.OmitStructFlowAnalysis || !vi.TypeInfo.IsStruct) && !IsAssigned (ec, loc))
 				return null;
 
+			if (ec.MustCaptureParameter (block, name)) {
+				variable = ec.CaptureParameter (par, idx);
+				type = variable.Type;
+			}
+
 			return this;
 		}
 
@@ -3694,6 +3661,11 @@
 
 			SetAssigned (ec);
 
+			if (ec.MustCaptureParameter (block, name)) {
+				variable = ec.CaptureParameter (par, idx);
+				type = variable.Type;
+			}
+
 			return this;
 		}
 
@@ -3731,7 +3703,68 @@
 			// FIXME: Review for anonymous methods
 			//
 		}
+
+		public override void Emit (EmitContext ec)
+		{
+			Emit (ec, false);
+		}
 		
+		public void Emit (EmitContext ec, bool leave_copy)
+		{
+			if (!prepared)
+				Variable.EmitInstance (ec);
+			Variable.Emit (ec);
+
+			if (is_ref) {
+				if (prepared)
+					ec.ig.Emit (OpCodes.Dup);
+	
+				//
+				// If we are a reference, we loaded on the stack a pointer
+				// Now lets load the real value
+				//
+				LoadFromPtr (ec.ig, type);
+			}
+
+			if (leave_copy) {
+				ec.ig.Emit (OpCodes.Dup);
+
+				if (is_ref || Variable.NeedsTemporary) {
+					temp = new LocalTemporary (Type);
+					temp.Store (ec);
+				}
+			}
+		}
+
+		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy,
+					bool prepare_for_load)
+		{
+			ILGenerator ig = ec.ig;
+			prepared = prepare_for_load;
+
+			Variable.EmitInstance (ec);
+			if (prepare_for_load)
+				ig.Emit (OpCodes.Dup);
+			source.Emit (ec);
+			if (leave_copy) {
+				ig.Emit (OpCodes.Dup);
+				if (Variable.NeedsTemporary) {
+					temp = new LocalTemporary (Type);
+					temp.Store (ec);
+				}
+			}
+			Variable.EmitAssign (ec);
+			if (temp != null)
+				temp.Emit (ec);
+		}
+		
+		public void AddressOf (EmitContext ec, AddressOp mode)
+		{
+			Variable.EmitInstance (ec);
+			Variable.EmitAddressOf (ec);
+		}
+
+#if FIXME
 		public override void Emit (EmitContext ec)
 		{
 			Emit (ec, false);
@@ -3742,8 +3775,11 @@
 			ILGenerator ig = ec.ig;
 			int arg_idx = idx;
 
-			if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){				
-				ec.EmitParameter (name, leave_copy, prepared, ref temp);
+			Report.Debug (64, "EMIT PARAMETER REF", this, name, ec.capture_context,
+				      ec.CurrentBlock, ec.CurrentBlock.Toplevel, loc);
+
+			if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)) {
+				ec.capture_context.EmitParameter (ec, name, leave_copy, prepared, ref temp);
 				return;
 			}
 
@@ -3772,20 +3808,19 @@
 				}
 			}
 		}
-		
+
 		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
 		{
 			prepared = prepare_for_load;
 			if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
-				ec.EmitAssignParameter (name, source, leave_copy, prepare_for_load, ref temp);
+				ec.capture_context.EmitAssignParameter (
+					ec, name, source, leave_copy, prepare_for_load, ref temp);
 				return;
 			}
 
 			ILGenerator ig = ec.ig;
 			int arg_idx = idx;
-			
-			
-			
+
 			if (!ec.MethodIsStatic)
 				arg_idx++;
 
@@ -3818,7 +3853,7 @@
 		public void AddressOf (EmitContext ec, AddressOp mode)
 		{
 			if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
-				ec.EmitAddressOfParameter (name);
+				ec.capture_context.EmitAddressOfParameter (ec, name);
 				return;
 			}
 			
@@ -3839,6 +3874,7 @@
 					ec.ig.Emit (OpCodes.Ldarga, arg_idx);
 			}
 		}
+#endif
 
 		public override string ToString ()
 		{
Index: codegen.cs
===================================================================
--- codegen.cs	(revision 63019)
+++ codegen.cs	(working copy)
@@ -9,7 +9,7 @@
 //
 
 #if !DEBUG
-	#define PRODUCTION
+//	#define PRODUCTION
 #endif
 
 using System;
@@ -363,12 +363,7 @@
 		///    The current iterator
 		/// </summary>
 		public Iterator CurrentIterator {
-			get {
-				if (CurrentAnonymousMethod != null)
-					return CurrentAnonymousMethod.Iterator;
-				else
-					return null;
-			}
+			get { return CurrentAnonymousMethod as Iterator; }
 		}
 
 		/// <summary>
@@ -529,12 +524,6 @@
 			get { return capture_context != null; }
 		}
 
-		public void EmitScopeInitFromBlock (Block b)
-		{
-			if (capture_context != null)
-				capture_context.EmitScopeInitFromBlock (this, b);
-		}
-
 		// <summary>
 		//   Starts a new code branching.  This inherits the state of all local
 		//   variables and parameters from the current branching.
@@ -618,29 +607,28 @@
 			current_flow_branching = current_flow_branching.Parent;
 		}
 
-		public void CaptureVariable (LocalInfo li)
+		public Variable CaptureVariable (LocalInfo li)
 		{
-			capture_context.AddLocal (CurrentAnonymousMethod, li);
 			li.IsCaptured = true;
+			return capture_context.AddLocal (li);
 		}
 
-		public void CaptureParameter (string name, Type t, int idx)
+		public Variable CaptureParameter (Parameter par, int idx)
 		{
-			capture_context.AddParameter (this, CurrentAnonymousMethod, name, t, idx);
+			return capture_context.AddParameter (this, par, idx);
 		}
 
 		public void CaptureThis ()
 		{
-			capture_context.CaptureThis (CurrentAnonymousMethod);
-		}
+			capture_context.CaptureThis ();
+		}		
 		
-		
 		//
 		// Use to register a field as captured
 		//
 		public void CaptureField (FieldExpr fe)
 		{
-			capture_context.AddField (this, CurrentAnonymousMethod, fe);
+			capture_context.AddField (this, fe);
 		}
 
 		//
@@ -664,25 +652,21 @@
 		}
 
 		//
-		// Emits the instance pointer for the host method
+		// Returns whether the `local' variable has been captured by an anonymous
+		// method
 		//
-		public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am)
+		public Variable GetCapturedVariable (LocalInfo local)
 		{
 			if (capture_context != null)
-				capture_context.EmitMethodHostInstance (target, am);
-			else if (IsStatic)
-				target.ig.Emit (OpCodes.Ldnull);
-			else
-				target.ig.Emit (OpCodes.Ldarg_0);
+				return capture_context.GetCapturedVariable (local);
+			return null;
 		}
 
-		//
-		// Returns whether the `local' variable has been captured by an anonymous
-		// method
-		//
-		public bool IsCaptured (LocalInfo local)
+		public Variable GetCapturedParameter (Parameter par)
 		{
-			return capture_context.IsCaptured (local);
+			if (capture_context != null)
+				return capture_context.GetCapturedParameter (par);
+			return null;
 		}
 
 		public bool IsParameterCaptured (string name)
@@ -691,11 +675,28 @@
 				return capture_context.IsParameterCaptured (name);
 			return false;
 		}
+
+		public bool MustCaptureParameter (Block block, string name)
+		{
+			if (CurrentAnonymousMethod == null)
+				return false;
+			if (CurrentAnonymousMethod.IsIterator)
+				return true;
+			else
+				return !block.Toplevel.IsLocalParameter (name);
+		}
+
+		public bool MustCaptureVariable (LocalInfo local)
+		{
+			if (CurrentAnonymousMethod == null)
+				return false;
+			if (CurrentAnonymousMethod.IsIterator)
+				return true;
+			return local.Block.Toplevel != CurrentBlock.Toplevel;
+		}
 		
 		public void EmitMeta (ToplevelBlock b)
 		{
-			if (capture_context != null)
-				capture_context.EmitAnonymousHelperClasses (this);
 			b.EmitMeta (this);
 
 			if (HasReturnLabel)
@@ -734,7 +735,8 @@
 			if (resolved)
 				return true;
 
-			capture_context = block.CaptureContext;
+			if (capture_context == null)
+				capture_context = block.CaptureContext;
 
 			if (!loc.IsNull)
 				CurrentFile = loc.File;
@@ -745,6 +747,11 @@
 				if (!block.ResolveMeta (this, ip))
 					return false;
 
+				if ((md != null) && (md.Iterator != null)) {
+					if (!md.Iterator.Resolve (this))
+						throw new InternalErrorException ();
+				}
+
 				using (this.With (EmitContext.Flags.DoFlowAnalysis, true)) {
 					FlowBranchingToplevel top_level;
 					if (anonymous_method_host != null)
@@ -783,12 +790,14 @@
 					return false;
 				} else if (!CurrentAnonymousMethod.IsIterator) {
 					Report.Error (1643, CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
-						CurrentAnonymousMethod.GetSignatureForError ());
+						      CurrentAnonymousMethod.GetSignatureForError ());
 					return false;
 				}
 			}
 
-			block.CompleteContexts ();
+			if (!block.CompleteContexts (this))
+				return false;
+
 			resolved = true;
 			return true;
 		}
@@ -829,12 +838,6 @@
 					ig.Emit (OpCodes.Ret);
 				}
 			}
-
-			//
-			// Close pending helper classes if we are the toplevel
-			//
-			if (capture_context != null && capture_context.ParentToplevel == null)
-				capture_context.CloseAnonymousHelperClasses ();
 		}
 
 		/// <summary>
@@ -995,6 +998,8 @@
 				HasReturnLabel = true;
 		}
 
+		static int next_temp = 0;
+
 		//
 		// Emits the proper object to address fields on a remapped
 		// variable/parameter to field in anonymous-method/iterator proxy classes.
@@ -1003,49 +1008,30 @@
 		{
 			ig.Emit (OpCodes.Ldarg_0);
 			if (capture_context != null && CurrentAnonymousMethod != null){
-				ScopeInfo si = CurrentAnonymousMethod.Scope;
-				while (si != null){
-					if (si.ParentLink != null)
-						ig.Emit (OpCodes.Ldfld, si.ParentLink);
-					if (si.THIS != null){
-						if (need_address && TypeManager.IsValueType (si.THIS.FieldType))
-							ig.Emit (OpCodes.Ldflda, si.THIS);
+				AnonymousMethodHost host = CurrentAnonymousMethod.RootScope;
+				ig.Emit (OpCodes.Ldc_I4, ++next_temp);
+				ig.Emit (OpCodes.Pop);
+				Report.Debug (64, "EMIT THIS", this, capture_context,
+					      CurrentAnonymousMethod, next_temp, host);
+
+				while (host != null){
+					Report.Debug (64, "EMIT THIS #1", this, capture_context,
+						      CurrentAnonymousMethod, next_temp, host,
+						      host.THIS, host.ParentLink);
+					if (host.ParentLink != null)
+						ig.Emit (OpCodes.Ldfld, host.ParentLink.FieldBuilder);
+					if (host.THIS != null){
+						if (need_address && TypeManager.IsValueType (host.THIS.MemberType))
+							ig.Emit (OpCodes.Ldflda, host.THIS.FieldBuilder);
 						else
-							ig.Emit (OpCodes.Ldfld, si.THIS);
+							ig.Emit (OpCodes.Ldfld, host.THIS.FieldBuilder);
 						break;
 					}
-					si = si.ParentScope;
+					host = host.ParentHost;
 				}
 			} 
 		}
 
-		//
-		// Emits the code necessary to load the instance required
-		// to access the captured LocalInfo
-		//
-		public void EmitCapturedVariableInstance (LocalInfo li)
-		{
-			if (capture_context == null)
-				throw new Exception ("Calling EmitCapturedContext when there is no capture_context");
-			
-			capture_context.EmitCapturedVariableInstance (this, li, CurrentAnonymousMethod);
-		}
-
-		public void EmitParameter (string name, bool leave_copy, bool prepared, ref LocalTemporary temp)
-		{
-			capture_context.EmitParameter (this, name, leave_copy, prepared, ref temp);
-		}
-
-		public void EmitAssignParameter (string name, Expression source, bool leave_copy, bool prepare_for_load, ref LocalTemporary  temp)
-		{
-			capture_context.EmitAssignParameter (this, name, source, leave_copy, prepare_for_load, ref temp);
-		}
-
-		public void EmitAddressOfParameter (string name)
-		{
-			capture_context.EmitAddressOfParameter (this, name);
-		}
-		
 		public Expression GetThis (Location loc)
 		{
 			This my_this;
Index: statement.cs
===================================================================
--- statement.cs	(revision 63019)
+++ statement.cs	(working copy)
@@ -962,23 +962,35 @@
 		}
 	}
 
+	public abstract class Variable
+	{
+		public abstract Type Type {
+			get;
+		}
+
+		public abstract bool HasInstance {
+			get;
+		}
+
+		public abstract bool NeedsTemporary {
+			get;
+		}
+
+		public abstract void EmitInstance (EmitContext ec);
+
+		public abstract void Emit (EmitContext ec);
+
+		public abstract void EmitAssign (EmitContext ec);
+
+		public abstract void EmitAddressOf (EmitContext ec);
+	}
+
 	//
 	// The information about a user-perceived local variable
 	//
 	public class LocalInfo {
 		public Expression Type;
 
-		//
-		// Most of the time a variable will be stored in a LocalBuilder
-		//
-		// But sometimes, it will be stored in a field (variables that have been
-		// hoisted by iterators or by anonymous methods).  The context of the field will
-		// be stored in the EmitContext
-		//
-		//
-		public LocalBuilder LocalBuilder;
-		public FieldBuilder FieldBuilder;
-
 		public Type VariableType;
 		public readonly string Name;
 		public readonly Location Location;
@@ -986,6 +998,11 @@
 
 		public VariableInfo VariableInfo;
 
+		Variable var;
+		public Variable Variable {
+			get { return var; }
+		}
+
 		[Flags]
  		enum Flags : byte {
  			Used = 1,
@@ -1022,18 +1039,23 @@
 			Location = l;
 		}
 
-		public void DeclareLocal (ILGenerator ig)
+		public void ResolveVariable (EmitContext ec)
 		{
-			if (Pinned) {
-				//
-				// This is needed to compile on both .NET 1.x and .NET 2.x
-				// the later introduced `DeclareLocal (Type t, bool pinned)'
-				//
-				LocalBuilder = TypeManager.DeclareLocalPinned (ig, VariableType);
-				return;
+			var = ec.GetCapturedVariable (this);
+			Report.Debug (64, "LOCAL RESOLVE VARIABLE", this, var);
+			if (var == null) {
+				LocalBuilder builder;
+				if (Pinned)
+					//
+					// This is needed to compile on both .NET 1.x and .NET 2.x
+					// the later introduced `DeclareLocal (Type t, bool pinned)'
+					//
+					builder = TypeManager.DeclareLocalPinned (ec.ig, VariableType);
+				else
+					builder = ec.ig.DeclareLocal (VariableType);
+
+				var = new LocalVariable (this, builder);
 			}
-			if (!IsThis && !IsConstant)
-				LocalBuilder = ig.DeclareLocal (VariableType);
 		}
 
 		public bool IsThisAssigned (EmitContext ec, Location loc)
@@ -1185,6 +1207,50 @@
 				flags = value ? (flags | Flags.IsThis) : (flags & ~Flags.IsThis);
 			}
 		}
+
+		protected class LocalVariable : Variable
+		{
+			public readonly LocalInfo LocalInfo;
+			LocalBuilder builder;
+
+			public LocalVariable (LocalInfo local, LocalBuilder builder)
+			{
+				this.LocalInfo = local;
+				this.builder = builder;
+			}
+
+			public override Type Type {
+				get { return LocalInfo.VariableType; }
+			}
+
+			public override bool HasInstance {
+				get { return false; }
+			}
+
+			public override bool NeedsTemporary {
+				get { return false; }
+			}
+
+			public override void EmitInstance (EmitContext ec)
+			{
+				// Do nothing.
+			}
+
+			public override void Emit (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldloc, builder);
+			}
+
+			public override void EmitAssign (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Stloc, builder);
+			}
+
+			public override void EmitAddressOf (EmitContext ec)
+			{
+				ec.ig.Emit (OpCodes.Ldloca, builder);
+			}
+		}
 	}
 		
 	/// <summary>
@@ -1239,7 +1305,7 @@
 		//
 		// The statements in this block
 		//
-		ArrayList statements;
+		protected ArrayList statements;
 		int num_statements;
 
 		//
@@ -1275,6 +1341,8 @@
 		//
 		Block switch_block;
 
+		ExpressionStatement scope_init;
+
 		protected static int id;
 
 		int this_id;
@@ -1589,6 +1657,8 @@
 
 		public LocalInfo AddTemporaryVariable (TypeExpr te, Location loc)
 		{
+			Report.Debug (64, "ADD TEMPORARY", this, Toplevel, loc);
+
 			if (temporary_variables == null)
 				temporary_variables = new ArrayList ();
 
@@ -1679,6 +1749,8 @@
 			}
 		}
 
+		public ScopeInfo ScopeInfo;
+
 		/// <summary>
 		///   Emits the variable declarations and labels.
 		/// </summary>
@@ -1688,6 +1760,8 @@
 		/// </remarks>
 		public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, Parameters ip)
 		{
+			Report.Debug (64, "BLOCK RESOLVE META", this, Parent, toplevel);
+
 			// If some parent block was unsafe, we remain unsafe even if this block
 			// isn't explicitly marked as such.
 			using (ec.With (EmitContext.Flags.InUnsafe, ec.InUnsafe | Unsafe)) {
@@ -1791,39 +1865,19 @@
 		//
 		// Emits the local variable declarations for a block
 		//
-		public void EmitMeta (EmitContext ec)
+		public virtual void EmitMeta (EmitContext ec)
 		{
-			ILGenerator ig = ec.ig;
-			
+			if (ec.capture_context != null)
+				scope_init = ec.capture_context.GetScopeInitializerForBlock (ec, this);
+
 			if (variables != null){
-				bool have_captured_vars = ec.HaveCapturedVariables ();
-				
-				foreach (DictionaryEntry de in variables){
-					LocalInfo vi = (LocalInfo) de.Value;
-
-					if (have_captured_vars && ec.IsCaptured (vi))
-						continue;
-
-					vi.DeclareLocal (ig);
-				}
+				foreach (LocalInfo vi in variables.Values)
+					vi.ResolveVariable (ec);
 			}
 
 			if (temporary_variables != null) {
-				AnonymousContainer am = ec.CurrentAnonymousMethod;
-				TypeBuilder scope = null;
-				if ((am != null) && am.IsIterator) {
-					scope = am.Scope.ScopeTypeBuilder;
-					if (scope == null)
-						throw new InternalErrorException ();
-				}
-				foreach (LocalInfo vi in temporary_variables) {
-					if (scope != null) {
-						if (vi.FieldBuilder == null)
-							vi.FieldBuilder = scope.DefineField (
-								vi.Name, vi.VariableType, FieldAttributes.Assembly);
-					} else
-						vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
-				}
+				foreach (LocalInfo vi in temporary_variables)
+					vi.ResolveVariable (ec);
 			}
 
 			if (children != null){
@@ -2031,15 +2085,18 @@
 						string name = (string) de.Key;
 						LocalInfo vi = (LocalInfo) de.Value;
 
+#if FIXME
 						if (vi.LocalBuilder == null)
 							continue;
 
 						ec.DefineLocalVariable (name, vi.LocalBuilder);
+#endif
 					}
 				}
 			}
 			ec.Mark (StartLocation, true);
-			ec.EmitScopeInitFromBlock (this);
+			if (scope_init != null)
+				scope_init.EmitStatement (ec);
 			DoEmit (ec);
 			ec.Mark (EndLocation, true); 
 
@@ -2083,12 +2140,13 @@
 		// Pointer to the host of this anonymous method, or null
 		// if we are the topmost block
 		//
-		ToplevelBlock container;
+		GenericMethod generic;
+		ToplevelBlock container, child;
 		CaptureContext capture_context;
 		FlowBranchingToplevel top_level_branching;
+		AnonymousMethodHost anonymous_method_host;
 
 		Hashtable capture_contexts;
-		ArrayList children;
 
 		public bool HasVarargs {
 			get { return (flags & Flags.HasVarargs) != 0; }
@@ -2105,21 +2163,42 @@
 
 		public void RegisterCaptureContext (CaptureContext cc)
 		{
+			Report.Debug (64, "TOPLEVEL REGISTER CONTEXT", this, capture_contexts, cc);
+
 			if (capture_contexts == null)
 				capture_contexts = new Hashtable ();
 			capture_contexts [cc] = cc;
 		}
 
-		public void CompleteContexts ()
+		public bool CompleteContexts (EmitContext ec)
 		{
-			if (capture_contexts == null)
-				return;
+			Report.Debug (64, "TOPLEVEL COMPLETE CONTEXTS", this, capture_contexts,
+				      container, anonymous_method_host);
 
-			foreach (CaptureContext cc in capture_contexts.Keys){
-				cc.LinkScopes ();
+			if (capture_contexts != null) {
+				foreach (CaptureContext cc in capture_contexts.Keys)
+					cc.LinkScopes ();
 			}
+
+			if ((container == null) && (anonymous_method_host != null)) {
+				Report.Debug (64, "TOPLEVEL COMPLETE CONTEXTS #1", this,
+					      anonymous_method_host);
+
+				if (anonymous_method_host.DefineType () == null)
+					return false;
+				if (!anonymous_method_host.ResolveType ())
+					return false;
+				if (!anonymous_method_host.DefineMembers ())
+					return false;
+			}
+
+			return true;
 		}
 
+		public GenericMethod GenericMethod {
+			get { return generic; }
+		}
+
 		public CaptureContext ToplevelBlockCaptureContext {
 			get { return capture_context; }
 		}
@@ -2128,14 +2207,6 @@
 			get { return container; }
 		}
 
-		protected void AddChild (ToplevelBlock block)
-		{
-			if (children == null)
-				children = new ArrayList ();
-
-			children.Add (block);
-		}
-
 		//
 		// Parent is only used by anonymous blocks to link back to their
 		// parents
@@ -2144,6 +2215,13 @@
 			this (container, (Flags) 0, parameters, start)
 		{
 		}
+
+		public ToplevelBlock (ToplevelBlock container, Parameters parameters, GenericMethod generic,
+				      Location start) :
+			this (container, parameters, start)
+		{
+			this.generic = generic;
+		}
 		
 		public ToplevelBlock (Parameters parameters, Location start) :
 			this (null, (Flags) 0, parameters, start)
@@ -2160,16 +2238,42 @@
 		{
 			this.parameters = parameters == null ? Parameters.EmptyReadOnlyParameters : parameters;
 			this.container = container;
+		}
 
+		public ToplevelBlock (Location loc) : this (null, (Flags) 0, null, loc)
+		{
+		}
+
+		public void CreateAnonymousMethodHost (TypeContainer host)
+		{
+			if (anonymous_method_host != null)
+				return;
 			if (container != null)
-				container.AddChild (this);
+				anonymous_method_host = capture_context.CreateRootScope (
+					container.anonymous_method_host, null);
+			else
+				anonymous_method_host = capture_context.CreateRootScope (
+					host, generic);
 		}
 
-		public ToplevelBlock (Location loc) : this (null, (Flags) 0, null, loc)
+		public void CreateIteratorHost (AnonymousMethodHost root_scope)
 		{
+			Report.Debug (64, "CREATE ITERATOR HOST", this, container,
+				      anonymous_method_host, root_scope);
+			if ((container != null) || (anonymous_method_host != null))
+				throw new InternalErrorException ();
+
+			capture_context.AddRootScope (root_scope);
+			anonymous_method_host = root_scope;
 		}
 
-		public void SetHaveAnonymousMethods (Location loc, AnonymousContainer host)
+		public AnonymousMethodHost AnonymousMethodHost {
+			get {
+				return anonymous_method_host;
+			}
+		}
+
+		public void SetHaveAnonymousMethods (Location loc, IAnonymousContainer host)
 		{
 			if (capture_context == null)
 				capture_context = new CaptureContext (this, loc, host);
@@ -2192,15 +2296,12 @@
 		// null.  Later on, when resolving the iterator, we need to move the
 		// anonymous method into that iterator.
 		//
-		public void ReParent (ToplevelBlock new_parent, AnonymousContainer new_host)
+		public void ReParent (ToplevelBlock new_parent)
 		{
-			foreach (ToplevelBlock block in children) {
-				if (block.CaptureContext == null)
-					continue;
-
-				block.container = new_parent;
-				block.CaptureContext.ReParent (new_parent, new_host);
-			}
+			Report.Debug (64, "TOPLEVEL REPARENT", this, Parent, new_parent);
+			container = new_parent;
+			Parent = new_parent;
+			new_parent.child = this;
 		}
 
 		//
@@ -2290,10 +2391,58 @@
 
 			ResolveMeta (this, ec, ip);
 
+			if (child != null)
+				child.ResolveMeta (this, ec, ip);
+
 			top_level_branching = ec.StartFlowBranching (this);
 
 			return Report.Errors == errors;
 		}
+
+		public override void EmitMeta (EmitContext ec)
+		{
+			base.EmitMeta (ec);
+			parameters.ResolveVariable (ec);
+		}
+
+		public void MakeIterator (Iterator iterator)
+		{
+			Report.Debug (64, "TOPLEVEL MAKE ITERATOR", this, statements);
+
+			Block block = new Block (this);
+			foreach (Statement stmt in statements)
+				block.AddStatement (stmt);
+			statements = new ArrayList ();
+			statements.Add (new MoveNextStatement (iterator, block));
+		}
+
+		protected class MoveNextStatement : Statement {
+			Iterator iterator;
+			Block block;
+
+			public MoveNextStatement (Iterator iterator, Block block)
+			{
+				this.iterator = iterator;
+				this.block = block;
+				this.loc = iterator.Location;
+			}
+
+			public override bool Resolve (EmitContext ec)
+			{
+				return block.Resolve (ec);
+			}
+
+			protected override void DoEmit (EmitContext ec)
+			{
+				iterator.EmitMoveNext (ec, block);
+			}
+		}
+
+		public override string ToString ()
+		{
+			return String.Format ("{0} ({1}:{2}{3}:{4})", GetType (), ID, StartLocation,
+					      capture_context, anonymous_method_host);
+		}
 	}
 	
 	public class SwitchLabel {
@@ -3299,7 +3448,7 @@
 			}
 
 			public abstract void Emit (EmitContext ec);
-			public abstract void EmitExit (ILGenerator ig);
+			public abstract void EmitExit (EmitContext ec);
 		}
 
 		class ExpressionEmitter : Emitter {
@@ -3313,14 +3462,14 @@
 				// Store pointer in pinned location
 				//
 				converted.Emit (ec);
-				ec.ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+				vi.Variable.EmitAssign (ec);
 			}
 
-			public override void EmitExit (ILGenerator ig)
+			public override void EmitExit (EmitContext ec)
 			{
-				ig.Emit (OpCodes.Ldc_I4_0);
-				ig.Emit (OpCodes.Conv_U);
-				ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+				ec.ig.Emit (OpCodes.Ldc_I4_0);
+				ec.ig.Emit (OpCodes.Conv_U);
+				vi.Variable.EmitAssign (ec);
 			}
 		}
 
@@ -3350,13 +3499,13 @@
 					return;
 
 				converted.Emit (ec);
-				ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+				vi.Variable.EmitAssign (ec);
 			}
 
-			public override void EmitExit(ILGenerator ig)
+			public override void EmitExit (EmitContext ec)
 			{
-				ig.Emit (OpCodes.Ldnull);
-				ig.Emit (OpCodes.Stloc, pinned_string);
+				ec.ig.Emit (OpCodes.Ldnull);
+				ec.ig.Emit (OpCodes.Stloc, pinned_string);
 			}
 		}
 
@@ -3554,13 +3703,11 @@
 			if (has_ret)
 				return;
 
-			ILGenerator ig = ec.ig;
-
 			//
 			// Clear the pinned variable
 			//
 			for (int i = 0; i < data.Length; i++) {
-				data [i].EmitExit (ig);
+				data [i].EmitExit (ec);
 			}
 		}
 	}
@@ -3772,22 +3919,24 @@
 				
 				ig.BeginCatchBlock (c.CatchType);
 
+#if FIXME
 				if (c.VarBlock != null)
 					ec.EmitScopeInitFromBlock (c.VarBlock);
+#endif
 				if (c.Name != null){
 					vi = c.Block.GetLocalInfo (c.Name);
 					if (vi == null)
 						throw new Exception ("Variable does not exist in this block");
 
-					if (vi.IsCaptured){
+					if (vi.Variable.NeedsTemporary) {
 						LocalBuilder e = ig.DeclareLocal (vi.VariableType);
 						ig.Emit (OpCodes.Stloc, e);
-						
-						ec.EmitCapturedVariableInstance (vi);
+
+						vi.Variable.EmitInstance (ec);
 						ig.Emit (OpCodes.Ldloc, e);
-						ig.Emit (OpCodes.Stfld, vi.FieldBuilder);
+						vi.Variable.EmitAssign (ec);
 					} else
-						ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+						vi.Variable.EmitAssign (ec);
 				} else
 					ig.Emit (OpCodes.Pop);
 
@@ -4164,7 +4313,7 @@
 
 			Type var_type = texpr.Type;
 
-			if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethod) {
+			if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethodExpression) {
 				Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
 					expr.ExprClassName);
 				return false;
@@ -4220,7 +4369,7 @@
 			{
 				EmitThis (ec);
 				ec.ig.Emit (OpCodes.Ldc_I4_0);
-				EmitStore (ec.ig);
+				EmitStore (ec);
 			}
 
 			public void Increment (EmitContext ec)
@@ -4229,7 +4378,7 @@
 				Emit (ec);
 				ec.ig.Emit (OpCodes.Ldc_I4_1);
 				ec.ig.Emit (OpCodes.Add);
-				EmitStore (ec.ig);
+				EmitStore (ec);
 			}
 		}
 
@@ -4323,7 +4472,7 @@
 
 					lengths [i].EmitThis (ec);
 					((ArrayAccess) access).EmitGetLength (ec, i);
-					lengths [i].EmitStore (ig);
+					lengths [i].EmitStore (ec);
 				}
 
 				for (int i = 0; i < rank; i++) {
