private void copyBlock(int origLabel, int newLabel) {

      BasicBlock origBlock = labelToBlock(origLabel);

      final IntList origSuccessors = origBlock.getSuccessors();
      IntList successors;
      int primarySuccessor = -1;
      Subroutine subroutine;

      if (isSubroutineCaller(origBlock)) {
        /*
         * A subroutine call inside a subroutine call.
         * Set up so we can recurse. The caller block should have
         * it's first successor be a copied block that will be
         * the subroutine's return point. It's second successor will
         * be copied when we recurse, and remains as the original
         * label of the start of the inner subroutine.
         */

        successors =
            IntList.makeImmutable(mapOrAllocateLabel(origSuccessors.get(0)), origSuccessors.get(1));
        // primary successor will be set when this block is replaced
      } else if (null != (subroutine = subroutineFromRetBlock(origLabel))) {
        /*
         * this is a ret block -- its successor
         * should be subroutineSuccessor
         */

        // Sanity check
        if (subroutine.startBlock != subroutineStart) {
          throw new RuntimeException(
              "ret instruction returns to label "
                  + Hex.u2(subroutine.startBlock)
                  + " expected: "
                  + Hex.u2(subroutineStart));
        }

        successors = IntList.makeImmutable(subroutineSuccessor);
        primarySuccessor = subroutineSuccessor;
      } else {
        // Map all the successor labels

        int origPrimary = origBlock.getPrimarySuccessor();
        int sz = origSuccessors.size();

        successors = new IntList(sz);

        for (int i = 0; i < sz; i++) {
          int origSuccLabel = origSuccessors.get(i);
          int newSuccLabel = mapOrAllocateLabel(origSuccLabel);

          successors.add(newSuccLabel);

          if (origPrimary == origSuccLabel) {
            primarySuccessor = newSuccLabel;
          }
        }

        successors.setImmutable();
      }

      addBlock(
          new BasicBlock(
              newLabel,
              filterMoveReturnAddressInsns(origBlock.getInsns()),
              successors,
              primarySuccessor),
          labelToSubroutines.get(newLabel));
    }
Copies a basic block, mapping its successors along the way.

@param origLabel original block label
@param newLabel label that the new block should have
android/android_framework/dex-maker/src/main/java/com/android/dx/cf/code/Ropper.java