class ImmutableTableFactory {

    public static <R, C, V, M, N, W> ImmutableTable<M, N, W> create(
            Table<R, C, V> baseTable,
            Function<? super R, ? extends M> rowMapper,
            Function<? super C, ? extends N> columnMapper,
            Function<? super V, ? extends W> valueMapper) {
        ImmutableTable.Builder<M, N, W> mappedTableBuilder = ImmutableTable.builder();

        TableUtils.forEach(baseTable, (r, c, v) -> mappedTableBuilder.put(
                rowMapper.apply(r),
                columnMapper.apply(c),
                valueMapper.apply(v)));

        try {
            return mappedTableBuilder.build();
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Multiple input cells mapped to the same ouput cell", e);
        }
    }

}