private void buildTrees(final Block firstBlock, final Map labelPos) {
		db("  Building trees for " + firstBlock);

		// Maps a "catch block" (beginning of exception handler that
		// stores the exception) to a "catch body" (the code immediately
		// follows the "catch block" -- the rest of the handler).
		final HashMap catchBodies = new HashMap(
				method.tryCatches().size() * 2 + 1);

		final Iterator tryCatches = method.tryCatches().iterator();

		while (tryCatches.hasNext()) {
			final TryCatch tc = (TryCatch) tryCatches.next();

			// We create two blocks for each handler.
			// catchBlock is the handler target. It contains the code
			// which saves the exception on the operand stack.
			// catchBody is the block following the handler target.
			// It contains the code for the exception handler body.
			// We need to split these two blocks so that the handler target
			// cannot possibly be a loop header.

			// This block will be the target of the exception handler.
			final Block catchBlock = newBlock();

			// This block will hold the instructions in the catch body.
			final Block catchBody = (Block) getNode(tc.handler());

			catchBodies.put(catchBlock, catchBody);

			// Make sure we include the new block in any protected area
			// containing the catch body.
			Integer pos = (Integer) labelPos.get(tc.handler());
			labelPos.put(catchBlock.label(), pos);

			addEdge(catchBlock, catchBody);
			trace.add(trace.indexOf(catchBody), catchBlock);

			Type type = tc.type();

			if (type == null) {
				type = Type.NULL;
			}

			catchBlocks.add(catchBlock);

			// Save the exception to the stack.
			final StackExpr lhs = new StackExpr(0, Type.THROWABLE);
			final CatchExpr rhs = new CatchExpr(type, Type.THROWABLE);
			final StoreExpr store = new StoreExpr(lhs, rhs, Type.THROWABLE);

			// Build the tree for the exception handler target block.
			final Tree tree = new Tree(catchBlock, new OperandStack());
			catchBlock.setTree(tree);
			tree.addStmt(new ExprStmt(store));
			tree.addStmt(new GotoStmt(catchBody));

			// Create the Handler.
			final Integer start = (Integer) labelPos.get(tc.start());
			final Integer end = (Integer) labelPos.get(tc.end());

			final Handler handler = new Handler(catchBlock, type);
			handlers.put(catchBlock, handler);

			final Iterator blocks = nodes().iterator();

			// Examine all of the basic blocks in this CFG. If the block's
			// offset into the code is between the start and end points of
			// the TryCatch, then it is a protected block. So, the block
			// should be added to the Handler's list of protected blocks.
			while (blocks.hasNext()) {
				final Block block = (Block) blocks.next();

				pos = (Integer) labelPos.get(block.label());

				if (pos == null) {
					// This is one of the special blocks such as the source,
					// sink, and init block.
					continue;
				}

				if (start.intValue() <= pos.intValue()) {
					if ((end == null) || (pos.intValue() < end.intValue())) {
						handler.protectedBlocks().add(block);
					}
				}
			}
		}

		addEdge(srcBlock, iniBlock);
		addEdge(srcBlock, snkBlock);
		addEdge(iniBlock, firstBlock);

		buildSpecialTrees(catchBodies, labelPos);

		// Build the trees for the blocks reachable from the firstBlock.
		buildTreeForBlock(firstBlock, iniBlock.tree().stack(), null, labelPos,
				catchBodies);
	}