code: public static <K, V> ImmutableListMultimap<K, V> index(
        Iterable<V> values, Function<? super V, K> keyFunction) {
      return index(values.iterator(), keyFunction);
    }
docs: Creates an index {@code ImmutableListMultimap} that contains the results of applying a
  specified function to each item in an {@code Iterable} of values. Each value will be stored as
  a value in the resulting multimap, yielding a multimap with the same size as the input
  iterable. The key used to store that value in the multimap will be the result of calling the
  function on that value. The resulting multimap is created as an immutable snapshot. In the
  returned multimap, keys appear in the order they are first encountered, and the values
  corresponding to each key appear in the same order as they are encountered.
  
  <p>For example,
  
  <pre>{@code
  List<String> badGuys =
  Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
  Function<String, Integer> stringLengthFunction = ...;
  Multimap<Integer, String> index =
  Multimaps.index(badGuys, stringLengthFunction);
  System.out.println(index);
  }</pre>
  
  <p>prints
  
  <pre>{@code
  {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}
  }</pre>
  
  <p>The returned multimap is serializable if its keys and values are all serializable.
  
  @param values the values to use when constructing the {@code ImmutableListMultimap}
  @param keyFunction the function used to produce the key for each value
  @return {@code ImmutableListMultimap} mapping the result of evaluating the function {@code
  keyFunction} on each value in the input collection to that value
  @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
  keyFunction} produces {@code null} for any key