code: public static <T, R, C, V> Collector<T, ?, ImmutableTable<R, C, V>> toImmutableTable(
        Function<? super T, ? extends R> rowFunction,
        Function<? super T, ? extends C> columnFunction,
        Function<? super T, ? extends V> valueFunction,
        BinaryOperator<V> mergeFunction) {
  
      checkNotNull(rowFunction, "rowFunction");
      checkNotNull(columnFunction, "columnFunction");
      checkNotNull(valueFunction, "valueFunction");
      checkNotNull(mergeFunction, "mergeFunction");
  
      /*
       * No mutable Table exactly matches the insertion order behavior of ImmutableTable.Builder, but
       * the Builder can't efficiently support merging of duplicate values.  Getting around this
       * requires some work.
       */
  
      return Collector.of(
          () -> new CollectorState<R, C, V>()
          /* GWT isn't currently playing nicely with constructor references? */ ,
          (state, input) ->
              state.put(
                  rowFunction.apply(input),
                  columnFunction.apply(input),
                  valueFunction.apply(input),
                  mergeFunction),
          (s1, s2) -> s1.combine(s2, mergeFunction),
          state -> state.toTable());
    }
docs: Returns a {@code Collector} that accumulates elements into an {@code ImmutableTable}. Each
  input element is mapped to one cell in the returned table, with the rows, columns, and values
  generated by applying the specified functions. If multiple inputs are mapped to the same row
  and column pair, they will be combined with the specified merging function in encounter order.
  
  <p>The returned {@code Collector} will throw a {@code NullPointerException} at collection time
  if the row, column, value, or merging functions return null on any input.
  
  @since 21.0