code: public static <S, T> Function<T, S> invert(
          Function<? super S, ? extends T> function, 
          Iterable<? extends S> arguments)
      {
          Map<T, S> map = new LinkedHashMap<T, S>();
          for (S s : arguments)
          {
              T t = function.apply(s);
              map.put(t, s);
          }
          return k -> map.get(k);
      }
docs: Returns a {@link Function} that is the inverse of the given
  {@link Function}, defined for the given arguments. For a
  given function <code>f : S -&gt; T</code> and a set of arguments
  <code>S<sub>0</sub></code>, the returned function will be a
  function that maps each <code>t</code> from
  <code>T<sub>0</sub> = f(S<sub>0</sub>)</code> to the <code>s</code> from
  <code>S<sub>0</sub></code> for which <code>f(s) = t</code>.
  If the given function is not injective (that is, when multiple
  arguments are mapped to the same value), then the resulting
  function will return the last argument that was mapped to the
  respective ambiguous value, based on the order of the given
  arguments sequence.
  
  @param <S> The argument type
  @param <T> The value type
  @param function The {@link Function}
  @param arguments The arguments
  @return The inverse {@link Function}