if (VERIFY_INTEGRITY)
if (Debug.VERIFY_INTEGRITY)
	public void build() {		InstructionHandle first = methodGen.getInstructionList().getStart();		BasicBlock start = getBlock(first, emptyStack); // adds start block to work list		addEdge(cfg.getEntry(), start, START_EDGE);// add edge from entry to start block		// Keep going until worklist is empty.		// This will construct basic blocks and add normal control flow and		// handled exception edges.		while (!workList.isEmpty()) {			WorkListItem item = (WorkListItem) workList.removeFirst();			BasicBlock bb = item.bb;			LinkedList<InstructionHandle> jsrStack = item.jsrStack;			// Scan through instructions, adding them to the basic block,			// until we get to a branch or merge (either of which ends the block).			InstructionHandle handle = item.firstInstruction, next;			if (DEBUG) System.out.println("START: " + handle);			TargetEnumeratingVisitor visitor = null;			boolean isMerge = false;			boolean isPotentialThrow = false;			while (true) {				if (handle == null) throw new IllegalStateException();				if (DEBUG) System.out.println("ADDING: " + handle);				bb.addInstruction(handle);				// This variable will be assigned if control transfers to				// an instruction which is not the next in the PC value sequence;				// i.e., for JSR or RET instructions.				next = null;				// Mark the instruction as now being a member of a BasicBlock.				// Note that an instruction may not be part of two basic blocks				// UNLESS it is reachable by a JSR instruction.				assert !bbHandles.contains(handle) || inSubroutine(jsrStack);				bbHandles.add(handle);				Instruction ins = handle.getInstruction();				//				// Handle JSRs, RETs, and branch instructions.				//				if (ins instanceof JsrInstruction) {					// JSR subroutines are inlined into the current					// control flow path.					jsrStack.addLast(handle);	// remember where we came from					JsrInstruction jsr = (JsrInstruction) ins;					next = jsr.getTarget();		// transfer control to the subroutine				} else if (ins instanceof RET) {					// Return control to the instruction following					// the most recently executed JSR.					next = jsrStack.removeLast().getNext(); // return control to ins after JSR					if (!NO_RET_MERGE) {						isMerge = true;			// conservatively assume that RET ends the basic block						break;					}				} else {					// See if the instruction is some kind of branch.					// See if this instruction is a branch (thus ending the BasicBlock)					visitor = new TargetEnumeratingVisitor(handle, methodGen.getConstantPool());					if (visitor.isEndOfBasicBlock())						break;				}						// If we're in INSTRUCTION_MODE, each instruction is a separate basic block.				if (mode == INSTRUCTION_MODE) {					isMerge = true;					break;				}						if (next == null)					next = handle.getNext();				if (next == null)					throw new IllegalStateException("No next?: " + handle);				// See if the next instruction is a control flow merge				// (which would make the current instruction the end of				// the basic block.)				if (isMerge(next)) {					isMerge = true;					break;				}				// If we're in EXCEPTION_SENSITIVE_MODE and the current instruction				// is a potential exception thrower, end the basic block.				if (mode == EXCEPTION_SENSITIVE_MODE && (handle.getInstruction() instanceof ExceptionThrower)) {					isPotentialThrow = true;					break;				}				// Continue to next instruction				handle = next;				assert handle != null;			}			if (DEBUG) System.out.println("END: " + handle);			// Add exception edges from the basic block to all possible handlers.			addExceptionEdges(bb, jsrStack);			if (isMerge) {				// Fall through.				addFallThroughEdge(bb, next, jsrStack);			} else if (visitor.instructionIsReturn() || visitor.instructionIsExit()) {				// Return from method (or process exit, which we treat as method return).				addEdge(bb, cfg.getExit(), RETURN_EDGE);			} else if (visitor.instructionIsThrow()) {				// NOTE: nothing to do - unhandled exceptions will be taken				// care of after the main worklist loop has completed.			} else if (isPotentialThrow) {				// Instruction has been marked as a potential exception thrower,				// and we're in EXCEPTION_SENSITIVE_MODE.  Add a fall through				// edge to the next instruction, if there is one.				if (next != null)					addFallThroughEdge(bb, next, jsrStack);			} else {				// Explicit branch.				addBranchEdges(bb, visitor, jsrStack);			}		}		// For each basic block containing instructions which can throw		// exceptions, add unhandled exception edges.  We conservatively		// assume that any basic block capable of throwing an exception		// may throw throw the exception out of the method.		Iterator<BasicBlock> bbIter = cfg.blockIterator();		while (bbIter.hasNext()) {			BasicBlock bb = bbIter.next();			boolean canThrow = false;			Iterator<InstructionHandle> insIter = bb.instructionIterator();			while (insIter.hasNext()) {				InstructionHandle handle = insIter.next();				Instruction ins = handle.getInstruction();				if (ins instanceof ExceptionThrower) {					ExceptionThrower exceptionThrower = (ExceptionThrower) ins;					java.lang.Class[] exceptionList = exceptionThrower.getExceptions();					if (exceptionList.length > 0) {						canThrow = true;						break;					}				}			}			if (canThrow)				// Unhandled exception edges can duplicate ordinary return edges				addDuplicateEdge(bb, cfg.getExit(), UNHANDLED_EXCEPTION_EDGE);		}		if (VERIFY_INTEGRITY)			cfg.checkIntegrity();	}