BitSet getBasicBlocks() {
      if (basicBlocks == null) {
        Instruction[] code = mi.getInstructions();
        BitSet bb = new BitSet(code.length);

        bb.set(0); // first insn is always a bb start

        // first, look at the insn type
        for (int i = 0; i < code.length; i++) {
          Instruction insn = code[i];
          if (insn instanceof IfInstruction) {
            IfInstruction ifInsn = (IfInstruction) insn;

            Instruction tgt = ifInsn.getTarget();
            bb.set(tgt.getInstructionIndex());

            tgt = ifInsn.getNext();
            bb.set(tgt.getInstructionIndex());
          } else if (insn instanceof GOTO) {
            Instruction tgt = ((GOTO) insn).getTarget();
            bb.set(tgt.getInstructionIndex());
          } else if (insn instanceof InvokeInstruction) {
            // hmm, this might be a bit too conservative, but who says we
            // don't jump out of a caller into a handler, or even that we
            // ever return from the call?
            Instruction tgt = insn.getNext();
            bb.set(tgt.getInstructionIndex());
          }
        }

        // and now look at the handlers (every first insn is a bb start)
        ExceptionHandler[] handlers = mi.getExceptions();
        if (handlers != null) {
          for (int i = 0; i < handlers.length; i++) {
            Instruction tgt = mi.getInstructionAt(handlers[i].getHandler());
            bb.set(tgt.getInstructionIndex());
          }
        }

        basicBlocks = bb;

        /** dump
         * System.out.println();
         * System.out.println(mi.getFullName());
         * for (int i=0; i<code.length; i++) {
         * System.out.print(String.format("%1$2d %2$c ",i, bb.get(i) ? '>' : ' '));
         * System.out.println(code[i]);
         * }
         **/
      }

      return basicBlocks;
    }
    BitSet getHandlerStarts() {
      BitSet b = new BitSet(mi.getInstructions().length);
      ExceptionHandler[] handler = mi.getExceptions();

      if (handler != null) {
        for (int i = 0; i < handler.length; i++) {
          Instruction hs = mi.getInstructionAt(handler[i].getHandler());
          b.set(hs.getInstructionIndex());
        }
      }

      return b;
    }