Program: 15701
Project: 15701
Buggy source:
/** 
 * Determines whether a type is convertible to another type via  method invocation conversion, and if so, what kind of conversion is needed. It treates the object type counterpart of primitive types as if they were the primitive types (that is, a Boolean actual parameter type matches boolean primitive formal type). This behavior is because this method is used to determine applicable methods for  an actual parameter list, and primitive types are represented by  their object duals in reflective method calls.
 * @param formal the parameter type to which the actual parameter type should be convertible; possibly a primitive type
 * @param actual the argument type; not a primitive type, maybe {@link Null}.
 * @return One of the <tt>CONVERSION_DIFFICULTY_...</tt> constants.
 */
private int isMethodInvocationConvertible(final Class formal,final Class actual){
  if (formal.isAssignableFrom(actual) && actual != CharacterOrString.class) {
    return CONVERSION_DIFFICULTY_REFLECTION;
  }
 else   if (bugfixed) {
    final Class formalNP;
    if (formal.isPrimitive()) {
      if (actual == Null.class) {
        return CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
      formalNP=ClassUtil.primitiveClassToBoxingClass(formal);
      if (actual == formalNP) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
    }
 else {
      if (actual == Null.class) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
      formalNP=formal;
    }
    if (Number.class.isAssignableFrom(actual) && Number.class.isAssignableFrom(formalNP)) {
      return OverloadedNumberUtil.getArgumentConversionPrice(actual,formalNP) == Integer.MAX_VALUE ? CONVERSION_DIFFICULTY_IMPOSSIBLE : CONVERSION_DIFFICULTY_REFLECTION;
    }
 else     if (formal.isArray()) {
      return List.class.isAssignableFrom(actual) ? CONVERSION_DIFFICULTY_FREEMARKER : CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
 else     if (List.class.isAssignableFrom(formal)) {
      return actual.isArray() ? CONVERSION_DIFFICULTY_FREEMARKER : CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
 else     if (actual == CharacterOrString.class && (formal.isAssignableFrom(String.class) || formal.isAssignableFrom(Character.class) || formal == char.class)) {
      return CONVERSION_DIFFICULTY_FREEMARKER;
    }
 else {
      return CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
  }
 else {
    if (formal.isPrimitive()) {
      if (formal == Boolean.TYPE) {
        return actual == Boolean.class ? CONVERSION_DIFFICULTY_REFLECTION : CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
 else       if (formal == Double.TYPE && (actual == Double.class || actual == Float.class || actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Integer.TYPE && (actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Long.TYPE && (actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Float.TYPE && (actual == Float.class || actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Character.TYPE) {
        return actual == Character.class ? CONVERSION_DIFFICULTY_REFLECTION : CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
 else       if (formal == Byte.TYPE && actual == Byte.class) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Short.TYPE && (actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (BigDecimal.class.isAssignableFrom(actual) && ClassUtil.isNumerical(formal)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else {
        return CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
    }
 else {
      return CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
  }
}

Fixed version (ground truth):
/** 
 * Determines whether a type is convertible to another type via  method invocation conversion, and if so, what kind of conversion is needed. It treates the object type counterpart of primitive types as if they were the primitive types (that is, a Boolean actual parameter type matches boolean primitive formal type). This behavior is because this method is used to determine applicable methods for  an actual parameter list, and primitive types are represented by  their object duals in reflective method calls.
 * @param formal the parameter type to which the actual parameter type should be convertible; possibly a primitive type
 * @param actual the argument type; not a primitive type, maybe {@link Null}.
 * @return One of the <tt>CONVERSION_DIFFICULTY_...</tt> constants.
 */
private int isMethodInvocationConvertible(final Class formal,final Class actual){
  if (formal.isAssignableFrom(actual) && actual != CharacterOrString.class) {
    return CONVERSION_DIFFICULTY_REFLECTION;
  }
 else   if (bugfixed) {
    final Class formalNP;
    if (formal.isPrimitive()) {
      if (actual == Null.class) {
        return CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
      formalNP=ClassUtil.primitiveClassToBoxingClass(formal);
      if (actual == formalNP) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
    }
 else {
      if (actual == Null.class) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
      formalNP=formal;
    }
    if (Number.class.isAssignableFrom(actual) && Number.class.isAssignableFrom(formalNP)) {
      return OverloadedNumberUtil.getArgumentConversionPrice(actual,formalNP) == Integer.MAX_VALUE ? CONVERSION_DIFFICULTY_IMPOSSIBLE : CONVERSION_DIFFICULTY_REFLECTION;
    }
 else     if (formal.isArray()) {
      return List.class.isAssignableFrom(actual) ? CONVERSION_DIFFICULTY_FREEMARKER : CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
 else     if (actual.isArray() && formal.isAssignableFrom(List.class)) {
      return CONVERSION_DIFFICULTY_FREEMARKER;
    }
 else     if (actual == CharacterOrString.class && (formal.isAssignableFrom(String.class) || formal.isAssignableFrom(Character.class) || formal == char.class)) {
      return CONVERSION_DIFFICULTY_FREEMARKER;
    }
 else {
      return CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
  }
 else {
    if (formal.isPrimitive()) {
      if (formal == Boolean.TYPE) {
        return actual == Boolean.class ? CONVERSION_DIFFICULTY_REFLECTION : CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
 else       if (formal == Double.TYPE && (actual == Double.class || actual == Float.class || actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Integer.TYPE && (actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Long.TYPE && (actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Float.TYPE && (actual == Float.class || actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Character.TYPE) {
        return actual == Character.class ? CONVERSION_DIFFICULTY_REFLECTION : CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
 else       if (formal == Byte.TYPE && actual == Byte.class) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (formal == Short.TYPE && (actual == Short.class || actual == Byte.class)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else       if (BigDecimal.class.isAssignableFrom(actual) && ClassUtil.isNumerical(formal)) {
        return CONVERSION_DIFFICULTY_REFLECTION;
      }
 else {
        return CONVERSION_DIFFICULTY_IMPOSSIBLE;
      }
    }
 else {
      return CONVERSION_DIFFICULTY_IMPOSSIBLE;
    }
  }
}