private void produceNext() {
        for (int i = index; i < iterables.size(); i++) {
            if (iterators.get(i) == null || (!iterators.get(i).hasNext() && i > 0)) {
                iterators.set(i, iterables.get(i).iterator());
            }
            if (!iterators.get(i).hasNext()) {
                hasNext = i == 0 ? Boolean.FALSE : null;
                return;
            }
            values[i] = iterators.get(i).next();
            lastEntry[i] = !iterators.get(i).hasNext();
            hasNext = Boolean.TRUE;
        }
        index = iterables.size() - 1;
        while (lastEntry[index] && index > 0) {
            index--;
        }
    }
MultiIterator provides a cartesian view on the given iterators

<pre>
e.g. (1,2) and (100, 200, 300)
are expanded to (1, 100) (1, 200) (1, 300) (2, 100) (2, 200) (2, 300)
</pre>

@author tiwe
@param <T> element type
querydsl-core/src/main/java/com/querydsl/core/util/MultiIterator.java