docs: public static <I, O> void crossProduct(List<I> left, List<I> right, Function<I, List<O>> transformer, BiConsumer<Pair<Integer, Integer>, List<O>> rowConsumer) {
          final int SIZE = left.size() * right.size();
  
          for (int i = 0; i < SIZE; i++) {
              List<O> newRowValues = new ArrayList<>();
              int j = 1;
              List<Integer> currentIndexes = new ArrayList<>();
              for (List<I> rowsList : new ArrayList<List<I>>() {
                  {
                      add(left);
                      add(right);
                  }
              }) {
                  final int index = ( i / j ) % rowsList.size();
                  currentIndexes.add(index);
                  I row = rowsList.get(index);
                  List<O> rowPart = transformer.apply(row);
                  newRowValues.addAll(rowPart);
                  j *= rowsList.size();
              }
              if (currentIndexes.size() == 2) {
                  rowConsumer.accept(new Pair<>(currentIndexes.get(0), currentIndexes.get(1)), newRowValues);
              }
          }
      }