internal void SetTargets (ActionBlock then, ActionBlock else_)
		{
			if (null == then) throw new ArgumentNullException ("then");
			AddAsPredecessorOf (then);
			if (null != else_) AddAsPredecessorOf (else_);
			_then = then;
			_else = else_;
		}
		internal override void ReplaceSuccessor (ActionBlock existing, ActionBlock newBlock)
		{
			if (existing == _then)
				_then = newBlock;
			else if (existing == _else)
				_else = newBlock;
			else
				throw new ArgumentException ("existing");
		}
		void Remove (ActionBlock block)
		{
			foreach (ActionBlock s in block.Successors) {
				s.RemovePredecessor (block);
				if (0 == s.Predecessors.Count) {
					Remove (s);
				}
			}
			_blocks.Remove (block);
		}
		internal void ReplaceAt (int index, ActionBlock block)
		{
			if (null == block) throw new ArgumentNullException ("block");

			ActionBlock existing = _blocks [index];
			foreach (ActionBlock p in existing.Predecessors.ToArray ()) {
				p.ReplaceSuccessor (existing, block);
			}
			Remove (existing);
			_blocks.Insert (index, block);
		}
		public bool IsBranchTarget (ActionBlock block)
		{
			if (null == block) throw new ArgumentNullException ("block");
			foreach (ActionBlock p in block.Predecessors) {
				switch (p.ActionType) {
				case ActionType.Branch:
					BranchActionBlock br = (BranchActionBlock) p;
					if (br.Target == block) return true;
					break;

				case ActionType.ConditionalBranch:
					ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock) p;
					if (cbr.Then == block) return true;
					break;
				}
			}
			return false;
		}
		internal abstract void ReplaceSuccessor (ActionBlock existing, ActionBlock newBlock);
		internal void RemovePredecessor (ActionBlock block)
		{
			_predecessors.Remove (block);
		}
		protected void AddAsPredecessorOf (ActionBlock block)
		{
			block.Predecessors.Add (this);
		}
		public void Insert (int index, ActionBlock block)
		{
			if (null == block) throw new ArgumentNullException ("block");
			InnerList.Insert (index, block);
		}
		void Add (ActionBlock block)
		{
			if (null == block) throw new ArgumentNullException ("block");
			_blocks.Add (block);
			_instruction2block.Add (_current, block);
		}
		static bool IsReturn (ActionBlock block)
		{
			return block.ActionType == ActionType.Return;
		}
		static bool IsReturnTrueOrFalse (ActionBlock block)
		{
			ReturnActionBlock ret = block as ReturnActionBlock;
			return ret != null && IsTrueOrFalse (ret.Expression);
		}
		internal override void ReplaceSuccessor (ActionBlock existing, ActionBlock newBlock)
		{
			throw new InvalidOperationException ();
		}
		internal override void ReplaceSuccessor (ActionBlock existing, ActionBlock newBlock)
		{
			if (_next != existing) throw new ArgumentException ("existing");
			_next = newBlock;
		}
		internal void SetNext (ActionBlock next)
		{
			if (null == next) return;
			_next = next;
			AddAsPredecessorOf (_next);
		}
		public int IndexOf (ActionBlock block)
		{
			if (null == block) throw new ArgumentNullException ("block");
			return InnerList.IndexOf (block);
		}
			void WriteGoto (ActionFlowGraph afg, ActionBlock target)
			{
				_writer.Write ("goto block{0}", afg.Blocks.IndexOf (target) + 1);
			}
		public void Remove (ActionBlock block)
		{
			if (null == block) throw new ArgumentNullException ("block");
			InnerList.Remove (block);
		}
		internal void SetTarget (ActionBlock target)
		{
			if (null == target) throw new ArgumentNullException ("target");
			_target = target;
			AddAsPredecessorOf (target);
		}