void ScanLine(YieldVMStat vm, int start, int stop)
		{

			int m = start;



			while (m < stop)
			{
				ILNode node = vm.usefulList [m];
				bool skipNode = false;
				bool jumpped  = false;
				if (node is ILExpression) {
					ILExpression expr = node as ILExpression;
					if (expr.Code == ILCode.Switch) {

						int pendingSwitchExprJumpLableIndex = -1;
						bool isStateSwithPending = false;
						int finalStatVal = 0;

						if (expr.Arguments [0].Code == ILCode.Ldloc && expr.Arguments [0].Operand == vm.statILVariable) {
							isStateSwithPending = true;
							pendingSwitchExprJumpLableIndex = vm.localStat;
							finalStatVal = vm.localStat;
						} else if (expr.Arguments [0].Code == ILCode.Ldfld &&
						           GetFieldDefinition (expr.Arguments [0].Operand as FieldReference) == this.stateField) {
							isStateSwithPending = true;
							pendingSwitchExprJumpLableIndex = vm.fieldStat;
							finalStatVal = vm.fieldStat;
						} else if (expr.Arguments [0].Code == ILCode.Sub) {
							ILExpression iLExpression10 = expr.Arguments [0];
							if (iLExpression10.Arguments [0].Code == ILCode.Ldloc && iLExpression10.Arguments [0].Operand == vm.statILVariable) {
								if (iLExpression10.Arguments [1].Code == ILCode.Ldc_I4) {
									finalStatVal = vm.localStat;
									pendingSwitchExprJumpLableIndex = vm.localStat - (int)iLExpression10.Arguments [1].Operand;
									isStateSwithPending = true;
								}
							} else if (iLExpression10.Arguments [0].Code == ILCode.Ldfld &&
							           GetFieldDefinition (iLExpression10.Arguments [0].Operand as FieldReference) == this.stateField) {
								if (iLExpression10.Arguments [1].Code == ILCode.Ldc_I4) {
									finalStatVal = vm.fieldStat;
									pendingSwitchExprJumpLableIndex = vm.fieldStat - (int)iLExpression10.Arguments [1].Operand;
									isStateSwithPending = true;
								}
							}
						}

						


						if (isStateSwithPending) {
							

							ILLabel jmpLabel = null;
							ILLabel[] lbList = expr.Operand as ILLabel[];
							if (pendingSwitchExprJumpLableIndex >= 0 &&
							    pendingSwitchExprJumpLableIndex < lbList.Length) {
								jmpLabel = lbList [pendingSwitchExprJumpLableIndex];
							} else {
								if (m + 1 >= vm.usefulList.Count
								    || !(vm.usefulList [m + 1] is ILExpression)
								    || (vm.usefulList [m + 1] as ILExpression).Code != ILCode.Br) {
									//impossible 
									throw new SymbolicAnalysisFailedException (); 
								}
								ILExpression switchDefault = vm.usefulList [m + 1] as ILExpression;
								jmpLabel = switchDefault.Operand as ILLabel;
							}

							//convert switch to jmp


							if (pendingSwitchExprJumpLableIndex >= 0 &&
							    pendingSwitchExprJumpLableIndex < lbList.Length) {
								bool addedJump = false;
								if (expr == vm.firstStatSwitchExpr) {
									addedJump = vm.addNewNode (new ILExpression (ILCode.Br, jmpLabel), m);
									if (!addedJump && vm.fieldStatChangedPos.ContainsKey (finalStatVal)) {
										int stateStartPos = vm.fieldStatChangedPos [finalStatVal];
										addedJump = vm.addNewNode (new ILExpression (ILCode.Br, jmpLabel), stateStartPos);
									}

									vm.localStatChangedPos.Clear ();
								} else {
									
									if (vm.localStatChangedPos.ContainsKey (finalStatVal)) {
										int stateStartPos = vm.localStatChangedPos [finalStatVal];

										addedJump = vm.addNewNode (new ILExpression (ILCode.Br, jmpLabel), stateStartPos);

                                        if (!addedJump)
                                        {
                                            if (!vm.addNewNode(new ILExpression(ILCode.Br, jmpLabel), m))
                                            {
                                                //throw new SymbolicAnalysisFailedException (); 
                                            }
                                        }
									}
                                  
								}
								
							} else {
								vm.addNewNode (new ILExpression (ILCode.Br, jmpLabel), m );
							}

							vm.localStatChangedPos.Clear ();
							vm.markingLocalChangePos = false;


							m = vm.labelMaping [jmpLabel];
							skipNode = true;
							jumpped = true;
						} else {
							
							if (vm.markingLocalChangePos) {
								vm.localStatChangedPos.Clear ();
								vm.markingLocalChangePos = false;
							}

							List<int> jumplist = new List<int> ();
							ILLabel[] lbList = expr.Operand as ILLabel[];
							foreach (ILLabel tmp in lbList) {
								jumplist.Add (vm.labelMaping [tmp]);
							}
							jumplist.Add (m + 1); // the default pos;

                            if (!vm.addNewNode(node, m))
                                return;
							skipNode = true;
							foreach (int tmp in jumplist) {
								ScanLine (vm, tmp, vm.usefulList.Count);
							}
							return;
						}
							
					} else if (expr.Code == ILCode.Br || expr.Code == ILCode.Leave) {
						ILLabel lb = expr.Operand as ILLabel;
						if (lb == null) {
							//impossible 
							throw new SymbolicAnalysisFailedException (); 
						}

						int lbPos = vm.labelMaping [lb];
                        if (!vm.addNewNode(node, m))
                            return;
						if (lbPos < m)
							ScanLine (vm, lbPos, m);
						else
                            ScanLine(vm, lbPos, vm.usefulList.Count);
					
						return;

					} else if (isFlowControlCode (expr.Code)) {
						ILLabel lb = expr.Operand as ILLabel;
						if (lb == null) {
							//impossible 
							throw new SymbolicAnalysisFailedException (); 
						}


						if (expr == vm.firstStatSwitchExpr) {

							int testvalue = 0;
							skipNode = true;

							if ((expr.Arguments [0].Code == ILCode.Ldfld
							    && GetFieldDefinition (expr.Arguments [0].Operand as FieldReference) == stateField)) {
								testvalue = vm.fieldStat;
							} else
								testvalue = vm.localStat;

							if (isMatchControlBr (expr.Code, testvalue)) {
								vm.addNewNode (new ILExpression (ILCode.Br, lb), m);
								m = vm.labelMaping [lb];
								jumpped = true;
							} else {
								vm.addNewNode (new ILExpression (ILCode.Nop, null, new List<ILExpression>()), m);
								Console.WriteLine ("not maching, should skip this and continue");
							}

							if (vm.markingLocalChangePos) {
								vm.localStatChangedPos.Clear ();
								vm.markingLocalChangePos = false;
							}
						} else {
							if (vm.markingLocalChangePos) {
								vm.localStatChangedPos.Clear ();
								vm.markingLocalChangePos = false;
							}

							int lbPos = vm.labelMaping [lb];
							if (!vm.addNewNode (node, m))
								return;
							if (lbPos < m) {
								ScanLine (vm, lbPos, m);
								ScanLine (vm, m + 1, vm.usefulList.Count);

							} else {
								ScanLine (vm, m + 1, lbPos);
								ScanLine (vm, lbPos, vm.usefulList.Count);
							}
							return;
						}


					} else if (expr.Code == ILCode.Stloc) {
						if (expr.Operand == vm.statILVariable) {
							
							if (expr.Arguments [0].Code == ILCode.Ldc_I4) {
								vm.localStat = (int)expr.Arguments [0].Operand;
								vm.localStatChangedPos [vm.localStat] = m;
							} else if (expr.Arguments [0].Code == ILCode.Ldfld
							           && GetFieldDefinition (expr.Arguments [0].Operand as FieldReference) == stateField) {


								vm.localStat = vm.fieldStat;
								//mark the local state for use when we process jump
								vm.localStatChangedPos.Clear ();
								vm.markingLocalChangePos = true;
								vm.localStatChangedPos.Add (vm.localStat, m);

							} else {
								throw new SymbolicAnalysisFailedException ();
							}
							skipNode = true;
						} else if (expr.Operand == vm.diposeFlagILVariable) {
							if (expr.Arguments [0].Code != ILCode.Ldc_I4) {
								throw new SymbolicAnalysisFailedException ();
							}
							vm.localDisposeFlag = (int)expr.Arguments [0].Operand;
							skipNode = true;
						} else if (expr.Operand == returnVariable) {
							if (expr.Arguments [0].Code != ILCode.Ldc_I4) {
								throw new SymbolicAnalysisFailedException ();
							}
							vm.localReturnValue = (int)expr.Arguments [0].Operand;
							skipNode = true;
						}

					} else if (expr.Code == ILCode.Stfld) {
						if (expr.Arguments [0].MatchThis ()) {
							if (YieldReturnDecompiler.GetFieldDefinition (expr.Operand as FieldReference) == this.stateField) {
								if (expr.Arguments [1].Code != ILCode.Ldc_I4) {
									throw new SymbolicAnalysisFailedException ();
								}
								vm.fieldStat = (int)expr.Arguments [1].Operand;

								skipNode = true;
							} else if (YieldReturnDecompiler.GetFieldDefinition (expr.Operand as FieldReference) == this.currentField) {
								//state should change
								vm.addNewNode (new ILExpression (ILCode.YieldReturn, null, expr.Arguments [1]), m);

								if (m + 1 < vm.usefulList.Count) {
									ILExpression nextExpr = vm.usefulList [m + 1] as ILExpression;
									if (
										nextExpr.Code == ILCode.Stfld
										&& YieldReturnDecompiler.GetFieldDefinition (nextExpr.Operand as FieldReference) == this.stateField) {
										vm.fieldStat = (int)nextExpr.Arguments [1].Operand;
										vm.fieldStatChangedPos [vm.fieldStat] = m + 1;

									} else {
										throw new SymbolicAnalysisFailedException ();
									}
								} else {
									throw new SymbolicAnalysisFailedException ();
								}

								skipNode = true;
								return;
							}
						}
					} else if (expr.Code == ILCode.Ret) {
						if (expr.Arguments [0].Code == ILCode.Ldloc &&
						    expr.Arguments [0].Operand == returnVariable) {
							if (vm.localReturnValue == 0) {
								skipNode = true;
								vm.addNewNode (new ILExpression (ILCode.YieldBreak, null), m);
							} else {
								//todo nothing.
								skipNode = true;
								vm.addNewNode (new ILExpression (ILCode.Ret, null, new List<ILExpression> ()), m);
							}
						} else if (expr.Arguments [0].Code == ILCode.Ldc_I4) {
							int retval = (int)expr.Arguments [0].Operand;
							if (retval == 0) {
								skipNode = true;
								vm.addNewNode (new ILExpression (ILCode.YieldBreak, null), m);
							} else {
								//todo nothing.
								skipNode = true;
								vm.addNewNode (new ILExpression (ILCode.Ret, null, new List<ILExpression> ()), m);
							}
						} else {
							throw new SymbolicAnalysisFailedException ();
						}

					}

				} 


				if (!skipNode) {
					if(!vm.addNewNode(node,m))
                    {
                        return;
                    }
				}
				if (!jumpped) {
					m++;
				}
				
			}

		}
		void AnalyzeMoveNext2()
		{
			ILBlock ilMethod = CreateILAst(moveNextMethod);
			ILExpression lastReturnArg;
			if (!ilMethod.Body.Last().Match(ILCode.Ret, out lastReturnArg))
				throw new SymbolicAnalysisFailedException();

			if (ilMethod.Body.Count == 6 || ilMethod.Body.Count == 5) {
			
				Console.WriteLine ("Debug Pos" + ilMethod.ToString ());
			}
			 
//			ILVariable stateVar=null;
//			ILVariable diposeFlagVar=null;
			ILLabel lastLabel = null;
		
			//can once to retrive pc , current , pc's local, usage ILNode
			YieldVMStat vm = new YieldVMStat();
		
			for (int i = 0; i < ilMethod.Body.Count; i++) {
				ILNode node = ilMethod.Body [i];

				if (node is ILExpression) {
					ILExpression expr = node as ILExpression;
					switch (expr.Code) {
					case ILCode.Stloc:
						//if arments is stateField;
						//set statelocal = local;
						if (vm.statILVariable == null && expr.Arguments [0].Code == ILCode.Ldfld
						    && GetFieldDefinition (expr.Arguments [0].Operand as FieldReference) == stateField) {
							vm.statILVariable = expr.Operand as ILVariable;
						} 
						break;
					case ILCode.Ret:
						//find out the return Jump Lable and stat
						ILExpression retArg = expr.Arguments [0] as ILExpression;

						if (retArg.Code == ILCode.Ldloc) {
							// a) the compiler uses a variable for returns (in debug builds, or when there are try-finally blocks)
							returnVariable = (ILVariable)lastReturnArg.Operand;
							returnLabel = ilMethod.Body.ElementAtOrDefault (ilMethod.Body.Count - 2) as ILLabel;
							if (returnLabel == null)
								throw new SymbolicAnalysisFailedException ();
						} else {
							// b) the compiler directly returns constants
							if (retArg.Code != ILCode.Ldc_I4) {
								throw new SymbolicAnalysisFailedException ();
							}

							if ((int)retArg.Operand == 0) {
								returnFalseLabel = lastLabel;
							} else {
								returnTrueLabel = lastLabel;
							}

						}

						break;
					}
					vm.usefulList.Add (expr);
				} 
				else if (node is ILTryCatchBlock) {
					ILTryCatchBlock tryBlock = node as ILTryCatchBlock;
					//check if a state try
					//finally block is not null, contains dispose , fault block is null, catch block.count==0
					//exand it to usageList
					bool isStateTry = false;
					if (tryBlock.FaultBlock == null && tryBlock.CatchBlocks.Count == 0 && tryBlock.FinallyBlock != null) {
						foreach (var tn in tryBlock.FinallyBlock.Body) {
							
							if (tn is ILExpression && (tn as ILExpression).Code ==ILCode.Callvirt ) 
							{
								ILExpression tnexp = (tn as ILExpression);
								if ( (tnexp.Operand as MethodReference).Name=="Dispose"
									&& tnexp.Arguments.Count==1
									&& tnexp.Arguments [0] is ILExpression
								) {
									ILExpression disposeArg = tnexp.Arguments [0];
									if (disposeArg.Arguments.Count==1 && disposeArg.Arguments [0].MatchThis ()) {
										isStateTry = true;
									}
								}
							}
						}
					}
					if (isStateTry) {
						foreach (ILNode blkNode in tryBlock.TryBlock.Body) {
							vm.usefulList.Add (blkNode);
						}

						foreach (ILNode blkNode in tryBlock.FinallyBlock.Body) {
							if (blkNode is ILExpression) {
								ILExpression blkExpr = blkNode as ILExpression;
								if (blkExpr.Code == ILCode.Stloc && vm.diposeFlagILVariable == null && blkExpr.Operand != vm.statILVariable && blkExpr.Arguments [0].Code == ILCode.Ldc_I4) {
									vm.diposeFlagILVariable = blkExpr.Operand as ILVariable;
								}
							}
						}
					} else {
						
						if (tryBlock.TryBlock != null) {
							foreach (ILNode blkNode in tryBlock.TryBlock.Body) {
								vm.usefulList.Add (blkNode);
								vm.tryBlockMapping [vm.usefulList.Count - 1] = new ILTryCatchBlockInfo(){blk=tryBlock,nodelistRef=tryBlock.TryBlock.Body};
							}
							tryBlock.TryBlock.Body.Clear ();
						}


						if (tryBlock.FinallyBlock != null) {
							foreach (ILNode blkNode in tryBlock.FinallyBlock.Body) {
								vm.usefulList.Add (blkNode);
								vm.tryBlockMapping [vm.usefulList.Count - 1] = new ILTryCatchBlockInfo(){blk=tryBlock,nodelistRef=tryBlock.FinallyBlock.Body};
							}
							tryBlock.FinallyBlock.Body.Clear ();
						}

						if (tryBlock.CatchBlocks.Count != 0) {
							foreach (ILTryCatchBlock.CatchBlock blk in tryBlock.CatchBlocks) {
								foreach (ILNode blkNode in blk.Body) {
									vm.usefulList.Add (blkNode);
									vm.tryBlockMapping [vm.usefulList.Count - 1] = new ILTryCatchBlockInfo () {
										blk = tryBlock,
										nodelistRef = blk.Body
									};
								}
								blk.Body.Clear ();
							}
						}

						if (tryBlock.FaultBlock != null) {
							foreach (ILNode blkNode in tryBlock.FaultBlock.Body) {
								vm.usefulList.Add (blkNode);
								vm.tryBlockMapping [vm.usefulList.Count - 1] = new ILTryCatchBlockInfo(){blk=tryBlock,nodelistRef=tryBlock.FaultBlock.Body};
							}
							tryBlock.FaultBlock.Body.Clear ();
						}



 						

					}
				} else if (node is ILLabel) {
					lastLabel = node as ILLabel;
					vm.usefulList.Add (node);
				}
				else {
					//add it to usageList
					vm.usefulList.Add (node);
				}
			}

	


			//make all the lable and get first case swith 
			//
			
			bool expectedSwitchFollowBr = false;
			for (int i = 0; i < vm.usefulList.Count; i++) {
				ILNode node = vm.usefulList [i];
				if (node is ILExpression) {
					ILExpression expr = node as ILExpression;
					if (expr.Code == ILCode.Switch
					    && vm.firstStatSwitchExpr == null
					    && expr.Arguments.Count == 1) {
						if ((expr.Arguments [0].Code == ILCode.Ldloc
						    && expr.Arguments [0].Operand == vm.statILVariable)

						    ||

						    (expr.Arguments [0].Code == ILCode.Ldfld
						    && GetFieldDefinition (expr.Arguments [0].Operand as FieldReference) == stateField)) {
						
							foreach (ILLabel lb in (expr.Operand as ILLabel[])) {
								vm.fistStateSwitchLabelList.Add (lb);
							}
							vm.firstStatSwitchExpr = expr;
							expectedSwitchFollowBr = true;
						}
					} else if (isFlowControlCode (expr.Code) && expr.Arguments.Count>0 && expr.Arguments[0].Operand==vm.statILVariable) {
						ILLabel lb = expr.Operand as ILLabel;
						vm.fistStateSwitchLabelList.Add (lb);
						vm.firstStatSwitchExpr = expr;
					}
					else if (expr.Code == ILCode.Br && expectedSwitchFollowBr) {
						expectedSwitchFollowBr = false;
						if (initPCValue < 0) {
							vm.fistStateSwitchLabelList.Insert (0, expr.Operand as ILLabel);
						} else {
							vm.fistStateSwitchLabelList.Add (expr.Operand as ILLabel);

						}
					}

				} else if (node is ILTryCatchBlock) {
					
				}
				else if (node is ILLabel) {
					vm.labelMaping [(node as ILLabel)] = i;
				}
			}


			int scanTimes = vm.fistStateSwitchLabelList.Count;

			if (initPCValue == 0)
				scanTimes -= 1;
			//scan all first swith stat 
			//
			for(int i=0; i<scanTimes;i++)
			{
				vm.resetStatVariable ();
				if(initPCValue==0  )
				{
					vm.fieldStat=i;
				}
				else 
				{
					if(i==0)
					{
						vm.fieldStat=initPCValue;
					}
					else 
					{
						vm.fieldStat =i-1;
					}
				}
				vm.scanningStat = vm.fieldStat;
				ScanLine (vm,0,vm.usefulList.Count);
                if(vm.fieldStatChangedPos.Count==0 && i==0 && i<scanTimes && initPCValue<0)
                {
                    Console.WriteLine("A compiler bug? .fieldStatChangedPos.Count==0 && i==0 && i<scanTimes && initPCValue<0 at method: " + moveNextMethod.FullName + "\n:" + vm.outputNewBody());
                    vm.clearCreatedNodes();
                }
			}

//			vm.fieldStat=initPCValue;
//			ScanLine (vm, 0);

			createdBody = vm.outputNewBody ();
			if (ilMethod.Body.Count == 6 || ilMethod.Body.Count == 5) {
				Console.WriteLine ("xxxx size " + createdBody.Count);
			}
			Console.WriteLine ("create size " + createdBody.Count);

		}