Program: 102041
Project: 102041
Buggy source:
/** 
 * Get the conversions that are needed to call the named function with arguments of the given type.  In the case of an exact match, the list will contain all nulls. In other cases the list will contain one or more non-null values where the value is a conversion function that can be used to convert to the proper types for executing the function.
 * @param name Name of function
 * @param returnType
 * @param args 
 * @param types Existing types passed to the function
 * @return Null if no conversion could be found, otherwise an array of conversionsto apply to each argument.  The list should match 1-to-1 with the parameters. Parameters that do not need a conversion are null; parameters that do are FunctionDescriptors.
 * @throws Exception
 */
public ConversionResult determineNecessaryConversions(String name,Class<?> returnType,Expression[] args,Class<?>[] types,boolean hasUnknownType) throws Exception {
  if (types.length == 0) {
    if (getTeiidVersion().isLessThan(Version.TEIID_8_0.get()))     return new ConversionResult(null);
    return null;
  }
  final Collection<FunctionMethod> functionMethods=new LinkedList<FunctionMethod>();
  functionMethods.addAll(this.systemFunctions.findFunctionMethods(name,types.length));
  if (this.userFunctions != null) {
    for (    FunctionTree tree : this.userFunctions) {
      functionMethods.addAll(tree.findFunctionMethods(name,types.length));
    }
  }
  int bestScore=Integer.MAX_VALUE;
  boolean ambiguous=false;
  FunctionMethod result=null;
  boolean isSystem=false;
  boolean narrowing=false;
  outer:   for (  FunctionMethod nextMethod : functionMethods) {
    int currentScore=0;
    boolean nextNarrowing=false;
    final List<FunctionParameter> methodTypes=nextMethod.getInputParameters();
    for (int i=0; i < types.length; i++) {
      final String tmpTypeName=methodTypes.get(Math.min(i,methodTypes.size() - 1)).getType();
      Class<?> targetType=getDataTypeManager().getDataTypeClass(tmpTypeName);
      Class<?> sourceType=types[i];
      if (sourceType == null) {
        currentScore++;
        continue;
      }
      if (sourceType.isArray() && targetType.isArray() && sourceType.getComponentType().equals(targetType.getComponentType())) {
        currentScore++;
        continue;
      }
      if (sourceType.isArray()) {
        if (isVarArgArrayParam(nextMethod,types,i,targetType)) {
          continue;
        }
        sourceType=DataTypeManagerService.DefaultDataTypes.OBJECT.getTypeClass();
      }
      try {
        Transform t=getConvertFunctionDescriptor(sourceType,targetType);
        if (t != null) {
          if (t.isExplicit()) {
            if (!(args[i] instanceof Constant) || ResolverUtil.convertConstant(getDataTypeManager().getDataTypeName(sourceType),tmpTypeName,(Constant)args[i]) == null) {
              continue outer;
            }
            nextNarrowing=true;
            currentScore++;
          }
 else {
            currentScore++;
          }
        }
      }
 catch (      Exception e) {
        continue outer;
      }
    }
    if (currentScore > bestScore) {
      continue;
    }
    if (hasUnknownType) {
      if (returnType != null) {
        try {
          Transform t=getConvertFunctionDescriptor(getDataTypeManager().getDataTypeClass(nextMethod.getOutputParameter().getType()),returnType);
          if (t != null) {
            if (t.isExplicit()) {
              currentScore+=types.length + 1;
              nextNarrowing=true;
            }
 else {
              currentScore++;
            }
          }
        }
 catch (        Exception e) {
          currentScore+=(types.length * types.length);
        }
      }
    }
    if (nextNarrowing && result != null && !narrowing) {
      continue;
    }
    boolean useNext=false;
    if (!nextNarrowing && narrowing) {
      useNext=true;
    }
    boolean isSystemNext=nextMethod.getParent() == null || INTERNAL_SCHEMAS.contains(nextMethod.getParent().getName());
    if ((isSystem && isSystemNext) || (!isSystem && !isSystemNext && result != null)) {
      int partCount=partCount(result.getName());
      int nextPartCount=partCount(nextMethod.getName());
      if (partCount < nextPartCount) {
        continue outer;
      }
      if (nextPartCount < partCount) {
        useNext=true;
      }
    }
 else     if (isSystemNext) {
      useNext=true;
    }
    if (currentScore == bestScore && !useNext) {
      ambiguous=true;
      boolean useCurrent=false;
      List<FunctionParameter> bestParams=result.getInputParameters();
      for (int j=0; j < types.length; j++) {
        String t1=bestParams.get(Math.min(j,bestParams.size() - 1)).getType();
        String t2=methodTypes.get((Math.min(j,methodTypes.size() - 1))).getType();
        if (types[j] == null || t1.equals(t2)) {
          continue;
        }
        String commonType=ResolverUtil.getCommonType(teiidVersion,new String[]{t1,t2});
        if (commonType == null) {
          continue outer;
        }
        if (commonType.equals(t1)) {
          if (!useCurrent) {
            useNext=true;
          }
        }
 else         if (commonType.equals(t2)) {
          if (!useNext) {
            useCurrent=true;
          }
        }
 else {
          continue outer;
        }
      }
      if (useCurrent) {
        ambiguous=false;
      }
 else {
        String sysName=result.getProperty(FunctionMethod.SYSTEM_NAME,false);
        String sysNameOther=nextMethod.getProperty(FunctionMethod.SYSTEM_NAME,false);
        if (sysName != null && sysName.equalsIgnoreCase(sysNameOther)) {
          ambiguous=false;
        }
      }
    }
    if (currentScore < bestScore || useNext) {
      ambiguous=false;
      if (currentScore == 0 && isSystemNext) {
        return new ConversionResult(nextMethod);
      }
      bestScore=currentScore;
      result=nextMethod;
      isSystem=isSystemNext;
      narrowing=nextNarrowing;
    }
  }
  if (ambiguous) {
    throw new Exception();
  }
  ConversionResult cr=new ConversionResult(result);
  if (result != null) {
    cr.needsConverion=(bestScore != 0);
  }
  return cr;
}

Fixed version (ground truth):
/** 
 * Get the conversions that are needed to call the named function with arguments of the given type.  In the case of an exact match, the list will contain all nulls. In other cases the list will contain one or more non-null values where the value is a conversion function that can be used to convert to the proper types for executing the function.
 * @param name Name of function
 * @param returnType
 * @param args 
 * @param types Existing types passed to the function
 * @param hasUnknownType
 * @return Null if no conversion could be found, otherwise an array of conversionsto apply to each argument.  The list should match 1-to-1 with the parameters. Parameters that do not need a conversion are null; parameters that do are FunctionDescriptors.
 * @throws Exception
 */
public ConversionResult determineNecessaryConversions(String name,Class<?> returnType,Expression[] args,Class<?>[] types,boolean hasUnknownType) throws Exception {
  final Collection<FunctionMethod> functionMethods=new LinkedList<FunctionMethod>();
  functionMethods.addAll(this.systemFunctions.findFunctionMethods(name,types.length));
  if (this.userFunctions != null) {
    for (    FunctionTree tree : this.userFunctions) {
      functionMethods.addAll(tree.findFunctionMethods(name,types.length));
    }
  }
  int bestScore=Integer.MAX_VALUE;
  boolean ambiguous=false;
  FunctionMethod result=null;
  boolean isSystem=false;
  boolean narrowing=false;
  outer:   for (  FunctionMethod nextMethod : functionMethods) {
    int currentScore=0;
    boolean nextNarrowing=false;
    final List<FunctionParameter> methodTypes=nextMethod.getInputParameters();
    for (int i=0; i < types.length; i++) {
      final String tmpTypeName=methodTypes.get(Math.min(i,methodTypes.size() - 1)).getType();
      Class<?> targetType=getDataTypeManager().getDataTypeClass(tmpTypeName);
      Class<?> sourceType=types[i];
      if (sourceType == null) {
        currentScore++;
        continue;
      }
      if (sourceType.isArray() && targetType.isArray() && sourceType.getComponentType().equals(targetType.getComponentType())) {
        currentScore++;
        continue;
      }
      if (sourceType.isArray()) {
        if (isVarArgArrayParam(nextMethod,types,i,targetType)) {
          continue;
        }
        sourceType=DataTypeManagerService.DefaultDataTypes.OBJECT.getTypeClass();
      }
      try {
        Transform t=getConvertFunctionDescriptor(sourceType,targetType);
        if (t != null) {
          if (t.isExplicit()) {
            if (!(args[i] instanceof Constant) || ResolverUtil.convertConstant(getDataTypeManager().getDataTypeName(sourceType),tmpTypeName,(Constant)args[i]) == null) {
              continue outer;
            }
            nextNarrowing=true;
            currentScore++;
          }
 else {
            currentScore++;
          }
        }
      }
 catch (      Exception e) {
        continue outer;
      }
    }
    if (currentScore > bestScore) {
      continue;
    }
    if (hasUnknownType) {
      if (returnType != null) {
        try {
          Transform t=getConvertFunctionDescriptor(getDataTypeManager().getDataTypeClass(nextMethod.getOutputParameter().getType()),returnType);
          if (t != null) {
            if (t.isExplicit()) {
              currentScore+=types.length + 1;
              nextNarrowing=true;
            }
 else {
              currentScore++;
            }
          }
        }
 catch (        Exception e) {
          currentScore+=(types.length * types.length);
        }
      }
    }
    if (nextNarrowing && result != null && !narrowing) {
      continue;
    }
    boolean useNext=false;
    if (!nextNarrowing && narrowing) {
      useNext=true;
    }
    boolean isSystemNext=nextMethod.getParent() == null || INTERNAL_SCHEMAS.contains(nextMethod.getParent().getName());
    if ((isSystem && isSystemNext) || (!isSystem && !isSystemNext && result != null)) {
      int partCount=partCount(result.getName());
      int nextPartCount=partCount(nextMethod.getName());
      if (partCount < nextPartCount) {
        continue outer;
      }
      if (nextPartCount < partCount) {
        useNext=true;
      }
    }
 else     if (isSystemNext) {
      useNext=true;
    }
    if (currentScore == bestScore && !useNext) {
      ambiguous=true;
      boolean useCurrent=false;
      List<FunctionParameter> bestParams=result.getInputParameters();
      for (int j=0; j < types.length; j++) {
        String t1=bestParams.get(Math.min(j,bestParams.size() - 1)).getType();
        String t2=methodTypes.get((Math.min(j,methodTypes.size() - 1))).getType();
        if (types[j] == null || t1.equals(t2)) {
          continue;
        }
        String commonType=ResolverUtil.getCommonType(teiidVersion,new String[]{t1,t2});
        if (commonType == null) {
          continue outer;
        }
        if (commonType.equals(t1)) {
          if (!useCurrent) {
            useNext=true;
          }
        }
 else         if (commonType.equals(t2)) {
          if (!useNext) {
            useCurrent=true;
          }
        }
 else {
          continue outer;
        }
      }
      if (useCurrent) {
        ambiguous=false;
      }
 else {
        String sysName=result.getProperty(FunctionMethod.SYSTEM_NAME,false);
        String sysNameOther=nextMethod.getProperty(FunctionMethod.SYSTEM_NAME,false);
        if (sysName != null && sysName.equalsIgnoreCase(sysNameOther)) {
          ambiguous=false;
        }
      }
    }
    if (currentScore < bestScore || useNext) {
      ambiguous=false;
      if (currentScore == 0 && isSystemNext) {
        return new ConversionResult(nextMethod);
      }
      bestScore=currentScore;
      result=nextMethod;
      isSystem=isSystemNext;
      narrowing=nextNarrowing;
    }
  }
  if (ambiguous) {
    throw new Exception();
  }
  ConversionResult cr=new ConversionResult(result);
  if (result != null) {
    cr.needsConverion=(bestScore != 0);
  }
  return cr;
}