private void injectCode(MethodInfo methodInfo) throws IOException {
    if (methodInfo.getCode() == null) {
      return;
    }

    InterceptorConstants interceptorConstants =
        getOrInsertInterceptorConstants(methodInfo.getInterceptorClass());

    fixupSignature(methodInfo.getSignature());

    Map<String, Integer> wrapperMethods =
        getOrInsertPrimitiveWrapperMethods(methodInfo.getSignature());

    ByteArrayOutputStream codeToInject = new ByteArrayOutputStream();
    InstructionsFacility instructionsFacility =
        new InstructionsFacility(
            new DataOutputStream(codeToInject),
            methodInfo.getSignature(),
            interceptorConstants,
            wrapperMethods);

    instructionsFacility.generateInterceptorInstantiationCode();

    instructionsFacility.generateInterceptorMethodParametersCode(getObjectClassIndex());

    instructionsFacility.generateObjectArrayFillingCode();

    instructionsFacility.generateInterceptorInvocationCode(
        interceptorConstants.getInterceptorMethod());

    Code code = methodInfo.getCode();

    int originalStackSize = code.getMaxStack();
    code.setMaxStack(Math.max(originalStackSize, instructionsFacility.getStackSizeNeeded()));

    code.setInjected(codeToInject.toByteArray());
    code.refresh();
  }
  private InterceptorConstants getOrInsertInterceptorConstants(Class interceptorClass)
      throws IOException {
    if (interceptorClass.getDeclaredMethods().length == 0) {
      throw new InvalidClassException("Interceptor class format not valid.");
    }

    InterceptorConstants interceptorConstants = new InterceptorConstants();

    interceptorConstants.setInterceptorClassName(
        getOrInsertUtf8(interceptorClass.getName().replace(".", "/")));
    interceptorConstants.setInterceptorClass(
        getOrInsertClass(interceptorConstants.getInterceptorClassName()));

    interceptorConstants.setInterceptorMethodName(
        getOrInsertUtf8(Constants.INTERCEPTOR_METHOD_NAME));
    interceptorConstants.setInterceptorMethodType(
        getOrInsertUtf8(Constants.INTERCEPTOR_METHOD_TYPE));
    interceptorConstants.setInterceptorMethodNameAndType(
        getOrInsertNameAndType(
            interceptorConstants.getInterceptorMethodName(),
            interceptorConstants.getInterceptorMethodType()));
    interceptorConstants.setInterceptorMethod(
        getOrInsertMethodRef(
            interceptorConstants.getInterceptorClass(),
            interceptorConstants.getInterceptorMethodNameAndType()));

    interceptorConstants.setConstructorName(getOrInsertUtf8(Constants.DEFAULT_CONSTRUCTOR_NAME));
    interceptorConstants.setConstructorType(getOrInsertUtf8(Constants.DEFAULT_CONSTRUCTOR_TYPE));
    interceptorConstants.setConstructorNameAndType(
        getOrInsertNameAndType(
            interceptorConstants.getConstructorName(), interceptorConstants.getConstructorType()));
    interceptorConstants.setConstructor(
        getOrInsertMethodRef(
            interceptorConstants.getInterceptorClass(),
            interceptorConstants.getConstructorNameAndType()));

    return interceptorConstants;
  }