boolean (Statement statement) { class Node { public final Integer id; public final Set<Node> preds = new HashSet<>(); public final Set<Node> succs = new HashSet<>(); Node(Integer id) { this.id = id; } } HashMap<Integer, Node> mapNodes = new HashMap<>(); // checking exceptions and creating nodes for (Statement stat : statement.getStats()) { if (!stat.getSuccessorEdges(EdgeType.EXCEPTION).isEmpty()) { return false; } mapNodes.put(stat.id, new Node(stat.id)); } // connecting nodes for (Statement stat : statement.getStats()) { Node node = mapNodes.get(stat.id); for (Statement succ : stat.getNeighbours(EdgeType.REGULAR, EdgeDirection.FORWARD)) { Node nodeSucc = mapNodes.get(succ.id); node.succs.add(nodeSucc); nodeSucc.preds.add(node); } } // transforming and reducing the graph while (true) { int ttype = 0; Node node = null; for (Node nd : mapNodes.values()) { if (nd.succs.contains(nd)) { // T1 ttype = 1; } else if (nd.preds.size() == 1) { // T2 ttype = 2; } if (ttype != 0) { node = nd; break; } } if (node != null) { if (ttype == 1) { node.succs.remove(node); node.preds.remove(node); } else { Node pred = node.preds.iterator().next(); pred.succs.addAll(node.succs); pred.succs.remove(node); for (Node succ : node.succs) { succ.preds.remove(node); succ.preds.add(pred); } mapNodes.remove(node.id); } } else { // no transformation applicable return mapNodes.size() > 1; // reducible iff one node remains } } }