code: public static <T> StreamEx<List<T>> cartesianProduct(Collection<? extends Collection<T>> source) {
          if (source.isEmpty())
              return StreamEx.of(new ConstSpliterator.OfRef<>(Collections.emptyList(), 1, true));
          return of(new CrossSpliterator.ToList<>(source));
      }
docs: Returns a new {@code StreamEx} which elements are {@link List} objects
  containing all possible tuples of the elements of supplied collection of
  collections. The whole stream forms an n-fold Cartesian product (or
  cross-product) of the input collections.
  
  <p>
  Every stream element is the {@code List} of the same size as supplied
  collection. The first element in the list is taken from the first
  collection which appears in source and so on. The elements are ordered
  lexicographically according to the order of the input collections.
  
  <p>
  There are no guarantees on the type, mutability, serializability, or
  thread-safety of the {@code List} elements. It's however guaranteed that
  each element is the distinct object.
  
  <p>
  The supplied collection is assumed to be unchanged during the operation.
  
  @param <T> the type of the elements
  @param source the input collection of collections which is used to
  generate the cross-product.
  @return the new stream of lists.
  @see #cartesianPower(int, Collection)
  @since 0.3.8