@Contract(pure = true)
  public static @NotNull <T> String join(@NotNull Iterable<? extends T> items,
                                         @NotNull Function<? super T, ? extends CharSequence> f,
                                         @NotNull String separator) {
    StringBuilder result = new StringBuilder();
    join(items, f, separator, result);
    return result.toString();
  }
@Contract(pure = true)
  public static @NotNull <T> String join(@NotNull Iterable<? extends T> items,
                                         @NotNull Function<? super T, ? extends CharSequence> f,
                                         @NotNull String separator)