private void connectBlocks(Map<Integer, BasicBlock> mapInstrBlocks) {
    for (int i = 0; i < this.blocks.size(); i++) {

      BasicBlock block = this.blocks.get(i);
      Instruction instr = block.getLastInstruction();

      switch (instr.group) {
        case GROUP_JUMP: {
          int dest = ((JumpInstruction) instr).destination;

          block.addSuccessor(mapInstrBlocks.get(dest));

          // note further code depends on the fact that the fall through case
          // comes after the conditional jump in the successor list
          if (instr.canFallThrough()) {
            if (i >= this.blocks.size() - 1) {
              continue;
            }
            block.addSuccessor(this.blocks.get(i + 1));
          }

          break;
        }
        case GROUP_SWITCH: {
          SwitchInstruction swInstr = (SwitchInstruction) instr;

          // Note: further code relies on the fact that the default branch comes before the other branches
          int defaultDestination = swInstr.getDefaultDestination();
          block.addSuccessor(mapInstrBlocks.get(defaultDestination));

          for (int destination : swInstr.getDestinations()) {
            block.addSuccessor(mapInstrBlocks.get(destination));
          }

          break;
        }
        case GROUP_RETURN: {
          if(instr.opcode != CodeConstants.opc_ret) {
            this.last.addPredecessor(block);
          }
          break;
        }
        case GROUP_GENERAL:
        case GROUP_INVOCATION:
        case GROUP_FIELDACCESS: {
          if (i >= this.blocks.size() - 1) {
            continue;
          }
          BasicBlock nextBlock = this.blocks.get(i + 1);
          block.addSuccessor(nextBlock);
          break;
        }
        default: {
          throw new IllegalStateException("Unknown instruction group");
        }
      }
    }
  }
@param mapInstrBlocks mapping of instruction -> block
src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java