/** Returns a new, optimized code info structure. */
  public CodeInfo getCodeInfo() {
    CodeInfo codeInfo;

    codeInfo =
        new CodeInfo(
            buildInstructionArray(), handlers, buildLineNumberInfo(), buildLocalVariableInfo());

    // replace instruction handles by actual instructions
    try {
      AccessorTransformer transformer =
          new AccessorTransformer() {
            public InstructionAccessor transform(
                InstructionAccessor accessor, AccessorContainer container) {
              // the only accessors to resolve are instruction handles
              return ((InstructionHandle) accessor).getInstruction();
            }
          };

      codeInfo.transformAccessors(transformer);
    } catch (BadAccessorException e) {
      throw new InconsistencyException(e.getMessage()); // !!!!
    }

    return codeInfo;
  }
  /** Install handles around instructions. */
  private InstructionHandle installInstructionHandles(CodeInfo info) {
    Instruction[] insns = info.getInstructions();

    InstructionHandle[] handles = new InstructionHandle[insns.length];
    for (int i = 0; i < handles.length; i++) {
      // this also sets the field next in handles
      handles[i] = new InstructionHandle(insns[i], i == 0 ? null : handles[i - 1]);
    }

    try {
      info.transformAccessors(new HandleCreator(insns, handles));
    } catch (BadAccessorException e) {
      // !!!DEBUG
      dumpCode(insns);
      // !!!DEBUG
      throw new InconsistencyException(e.getMessage()); // !!!!
    }

    return handles[0];
  }