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 shouldChooseLaterVariadicWhenTwoObjVariadicsMatch() {
    // Given:
    givenFunctions(
            function(OTHER, 1, GenericType.of("A"), OBJ_VARARGS, STRING, DOUBLE),
            function(EXPECTED, 2, GenericType.of("B"), INT, OBJ_VARARGS, DOUBLE)
    );

    // When:
    final KsqlScalarFunction fun = udfIndex.getFunction(ImmutableList.of(
            SqlArgument.of(SqlTypes.BIGINT),
            SqlArgument.of(SqlTypes.INTEGER),
            SqlArgument.of(SqlTypes.STRING),
            SqlArgument.of(SqlTypes.DOUBLE))
    );

    // Then:
    assertThat(fun.name(), equalTo(EXPECTED));
  }