private void splitJsrRange(BasicBlock jsr, BasicBlock ret, Set<BasicBlock> common_blocks) {

    List<BasicBlock> lstNodes = new LinkedList<>();
    Map<Integer, BasicBlock> mapNewNodes = new HashMap<>();

    lstNodes.add(jsr);
    mapNewNodes.put(jsr.id, jsr);

    while (!lstNodes.isEmpty()) {

      BasicBlock node = lstNodes.remove(0);

      for (int j = 0; j < 2; j++) {
        List<BasicBlock> lst;
        if (j == 0) {
          if (node.getLastInstruction().opcode == CodeConstants.opc_ret) {
            if (node.getSuccs().contains(ret)) {
              continue;
            }
          }
          lst = node.getSuccs();
        }
        else {
          if (node == jsr) {
            continue;
          }
          lst = node.getSuccExceptions();
        }


        for (int i = lst.size() - 1; i >= 0; i--) {

          BasicBlock child = lst.get(i);
          int childid = child.id;

          if (mapNewNodes.containsKey(childid)) {
            node.replaceSuccessor(child, mapNewNodes.get(childid));
          }
          else if (common_blocks.contains(child)) {
            // make a copy of the current block
            BasicBlock copy = child.cloneBlock(++last_id);
            // copy all successors
            if (copy.getLastInstruction().opcode == CodeConstants.opc_ret &&
                child.getSuccs().contains(ret)) {
              copy.addSuccessor(ret);
              child.removeSuccessor(ret);
            }
            else {
              for (int k = 0; k < child.getSuccs().size(); k++) {
                copy.addSuccessor(child.getSuccs().get(k));
              }
            }
            for (int k = 0; k < child.getSuccExceptions().size(); k++) {
              copy.addSuccessorException(child.getSuccExceptions().get(k));
            }

            lstNodes.add(copy);
            mapNewNodes.put(childid, copy);

            if (last.getPreds().contains(child)) {
              last.addPredecessor(copy);
            }

            node.replaceSuccessor(child, copy);
            blocks.addWithKey(copy, copy.id);
          }
          else {
            // stop at the first fixed node
            //lstNodes.add(child);
            mapNewNodes.put(childid, child);
          }
        }
      }
    }

    // note: subroutines won't be copied!
    splitJsrExceptionRanges(common_blocks, mapNewNodes);
  }
@param mapInstrBlocks mapping of instruction -> block
src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java