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 shouldThrowOnInvalidLambdaMapping() {
    // Given:
    givenFunctions(
        function(OTHER, -1, GENERIC_MAP, LAMBDA_BI_FUNCTION)
    );

    // When:
    final Exception e1 = assertThrows(
        Exception.class,
        () -> udfIndex.getFunction(
            ImmutableList.of(
                SqlArgument.of(MAP1_ARG),
                SqlArgument.of(
                    SqlLambdaResolved.of(
                        ImmutableList.of(SqlTypes.BOOLEAN, SqlTypes.STRING),
                        INTEGER))))
    );

    final Exception e2 = assertThrows(
        Exception.class,
        () -> udfIndex.getFunction(
            ImmutableList.of(
                SqlArgument.of(MAP1_ARG),
                SqlArgument.of(
                    SqlLambdaResolved.of(
                        ImmutableList.of(SqlTypes.STRING, SqlTypes.STRING, SqlTypes.STRING),
                        INTEGER)
                )))
    );

    // Then:
    assertThat(e1.getMessage(), containsString("does not accept parameters (" +
        "MAP<STRING, STRING>, LAMBDA (BOOLEAN, STRING) => INTEGER)."));
    assertThat(e1.getMessage(), containsString("Valid alternatives are:"
        + lineSeparator()
        + "other(MAP<A, B>, LAMBDA (A, B) => C)"));

    assertThat(e2.getMessage(), containsString("does not accept parameters (" +
        "MAP<STRING, STRING>, LAMBDA (STRING, STRING, STRING) => INTEGER)."));
    assertThat(e2.getMessage(), containsString("Valid alternatives are:"
        + lineSeparator()
        + "other(MAP<A, B>, LAMBDA (A, B) => C)"));
  }