/// <summary>
        /// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step.
        /// </summary>
        ILBlock CreateILAst(MethodDefinition method)
        {
            if (method == null || !method.HasBody)
            {
                throw new YieldAnalysisFailedException();
            }

            ILBlock ilMethod   = new ILBlock();
            var     astBuilder = ILMethodAstBuilder.Build(method, true);

            ilMethod.Body = astBuilder.Nodes.ToList();
            ILAstOptimizer optimizer = new ILAstOptimizer();

            optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn);
            return(ilMethod);
        }
		/// <summary>
		/// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step.
		/// </summary>
		ILBlock CreateILAst(MethodDefinition method)
		{
			if (method == null || !method.HasBody)
				throw new YieldAnalysisFailedException();
			
			ILBlock ilMethod = new ILBlock();
            var astBuilder = ILMethodAstBuilder.Build(method, true);
			ilMethod.Body = astBuilder.Nodes.ToList();
			ILAstOptimizer optimizer = new ILAstOptimizer();
			optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn);
			return ilMethod;
		}
		public BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> parameters,
		                                       /*Concurrent*/Dictionary<int, IEnumerable<ILVariable>> localVariables)
		{
			if (methodDef.Body == null) return null;
			
			if (localVariables == null)
				throw new ArgumentException("localVariables must be instantiated");
			
			context.VerifyProgress();
			ILBlock ilMethod = new ILBlock();
            var astBuilder = ILMethodAstBuilder.Build(methodDef, true);
			ilMethod.Body = astBuilder.Nodes.ToList();
			
			context.VerifyProgress();
			ILAstOptimizer bodyGraph = new ILAstOptimizer();
			bodyGraph.Optimize(context, ilMethod);
			context.VerifyProgress();
			
			var allVariables =
                (from e in ilMethod.EnumerateSelfAndChildrenRecursive().OfType<ILExpression>()
                let v = e.Operand as ILVariable
                where v!=null && !v.IsParameter
                select v).Distinct();
			Debug.Assert(context.CurrentMethod == methodDef);
			NameVariables.AssignNamesToVariables(context, astBuilder.Parameters, allVariables, ilMethod);
			
			if (parameters != null) {
				foreach (var pair in (from p in parameters
				                      join v in astBuilder.Parameters on p.Annotation<ParameterDefinition>() equals v.OriginalParameter
				                      select new { p, v.Name }))
				{
					pair.p.Name = pair.Name;
				}
			}
			
			context.VerifyProgress();
			BlockStatement astBlock = TransformBlock(ilMethod);
			CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments
			
			Statement insertionPoint = astBlock.Statements.FirstOrDefault();
			foreach (ILVariable v in localVariablesToDefine) {
				AstType type;
				if (v.Type.ContainsAnonymousType())
					type = new SimpleType("var");
				else
					type = AstBuilder.ConvertType(v.Type);
				var newVarDecl = new VariableDeclarationStatement(type, v.Name);
				astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
			}
			
			// store the variables - used for debugger
			int token = methodDef.MetadataToken.ToInt32();
			localVariables[token] = allVariables;
			
			return astBlock;
		}