@Override
  protected void addMethodsFromClass(ClassFile proxyClassType) {
    Method initializerMethod = null;
    int delegateParameterPosition = -1;
    if (delegateInjectionPoint instanceof ParameterInjectionPoint<?, ?>) {
      ParameterInjectionPoint<?, ?> parameterIP =
          (ParameterInjectionPoint<?, ?>) delegateInjectionPoint;
      if (parameterIP.getMember() instanceof Method) {
        initializerMethod = ((Method) parameterIP.getMember());
        delegateParameterPosition = parameterIP.getPosition();
      }
    }
    try {
      if (delegateParameterPosition >= 0) {
        addHandlerInitializerMethod(proxyClassType);
      }
      Class<?> cls = getBeanType();
      while (cls != null) {
        for (Method method : cls.getDeclaredMethods()) {
          MethodInformation methodInfo = new RuntimeMethodInformation(method);
          if (!method.getDeclaringClass().getName().equals("java.lang.Object")
              || method.getName().equals("toString")) {
            Bytecode methodBody = null;
            if ((delegateParameterPosition >= 0) && (initializerMethod.equals(method))) {
              methodBody =
                  createDelegateInitializerCode(
                      proxyClassType, methodInfo, delegateParameterPosition);
            }
            if (Modifier.isAbstract(method.getModifiers())) {
              methodBody = createAbstractMethodCode(proxyClassType, methodInfo);
            }

            if (methodBody != null) {
              log.trace("Adding method " + method);
              proxyClassType.addMethod(
                  MethodUtils.makeMethod(
                      methodInfo,
                      method.getExceptionTypes(),
                      methodBody,
                      proxyClassType.getConstPool()));
            }
          }
        }
        cls = cls.getSuperclass();
      }
    } catch (Exception e) {
      throw new WeldException(e);
    }
  }
 private void addHandlerInitializerMethod(ClassFile proxyClassType) throws Exception {
   StaticMethodInformation methodInfo =
       new StaticMethodInformation(
           "_initMH",
           new Class[] {Object.class},
           void.class,
           proxyClassType.getName(),
           Modifier.PRIVATE);
   proxyClassType.addMethod(
       MethodUtils.makeMethod(
           methodInfo,
           new Class[] {},
           createMethodHandlerInitializerBody(proxyClassType),
           proxyClassType.getConstPool()));
 }
  /** Add a method to a class that simply delegates to the parent implementation of the method */
  public static void addDelegatingMethod(ClassFile file, MethodData mData)
      throws BadBytecode, DuplicateMemberException {
    MethodInfo m =
        new MethodInfo(file.getConstPool(), mData.getMethodName(), mData.getDescriptor());
    m.setAccessFlags(mData.getAccessFlags());
    Bytecode code = new Bytecode(file.getConstPool());

    String[] params = DescriptorUtils.descriptorStringToParameterArray(mData.getDescriptor());
    code.add(Opcode.ALOAD_0); // push this
    int count = 1; // zero is the this pointer
    int maxLocals = 1;
    for (String p : params) {
      // int char short boolean byte
      if (p.equals("I") || p.equals("C") || p.equals("S") || p.equals("Z") || p.equals("B")) {
        // push integer 0
        code.addIload(count);
        maxLocals++;
      }
      // long
      else if (p.equals("J")) {
        code.addLload(count);
        maxLocals += 2;
        count++;
      }
      // double
      else if (p.equals("D")) {
        code.addDload(count);
        maxLocals += 2;
        count++;
      }
      // float
      else if (p.equals("F")) {
        code.addFload(count);
        maxLocals++;
      }
      // arrays and reference types
      else {
        code.addAload(count);
        maxLocals++;
      }
      count++;
    }
    code.addInvokespecial(file.getSuperclass(), mData.getMethodName(), mData.getDescriptor());
    String p = DescriptorUtils.getReturnTypeInJvmFormat(mData.getDescriptor());
    // int char short boolean byte
    if (p.equals("I") || p.equals("C") || p.equals("S") || p.equals("Z") || p.equals("B")) {
      code.add(Opcode.IRETURN);
    }
    // long
    else if (p.equals("J")) {
      code.add(Opcode.LRETURN);
    }
    // double
    else if (p.equals("D")) {
      code.add(Opcode.DRETURN);
    }
    // float
    else if (p.equals("F")) {
      code.add(Opcode.FRETURN);
    }
    // void
    else if (p.equals("V")) {
      code.add(Opcode.RETURN);
    }
    // arrays and reference types
    else {
      code.add(Opcode.ARETURN);
    }
    CodeAttribute ca = code.toCodeAttribute();
    ca.computeMaxStack();
    ca.setMaxLocals(maxLocals);
    m.setCodeAttribute(ca);
    file.addMethod(m);
  }