T getFunction(final List<SqlArgument> arguments) {

    // first try to get the candidates without any implicit casting
    Optional<T> candidate = findMatchingCandidate(arguments, false);
    if (candidate.isPresent()) {
      return candidate.get();
    } else if (!supportsImplicitCasts) {
      throw createNoMatchingFunctionException(arguments);
    }

    // if none were found (candidate isn't present) try again with implicit casting
    candidate = findMatchingCandidate(arguments, true);
    if (candidate.isPresent()) {
      return candidate.get();
    }
    throw createNoMatchingFunctionException(arguments);
  }
@Test
  public void shouldThrowOnAmbiguousImplicitCastWithGenericsAndVariadics() {
    // Given:
    givenFunctions(
            function(FIRST_FUNC, 3, LONG, GenericType.of("A"), GenericType.of("B"), INT_VARARGS),
            function(SECOND_FUNC, 3, DOUBLE, GenericType.of("A"), GenericType.of("B"), INT_VARARGS)
    );

    // When:
    final KsqlException e = assertThrows(KsqlException.class,
            () -> udfIndex.getFunction(ImmutableList.of(
                    SqlArgument.of(INTEGER), SqlArgument.of(INTEGER),
                    SqlArgument.of(INTEGER), SqlArgument.of(INTEGER))
            ));

    // Then:
    assertThat(e.getMessage(), containsString("Function 'name' cannot be resolved due "
            + "to ambiguous method parameters "
            + "(INTEGER, INTEGER, INTEGER, INTEGER)"));
  }