class ToList<T> extends CrossSpliterator<T, List<T>> {
        private List<T> elements;

        @SuppressWarnings("unchecked")
        ToList(Collection<? extends Collection<T>> source) {
            super(source);
            this.elements = (List<T>) Arrays.asList(new Object[collections.length]);
        }

        private ToList(long est, int splitPos, Spliterator<T>[] spliterators, Collection<T>[] collections,
                List<T> elements) {
            super(est, splitPos, spliterators, collections);
            this.elements = elements;
        }

        @Override
        public boolean tryAdvance(Consumer<? super List<T>> action) {
            if (elements == null)
                return false;
            if (est < Long.MAX_VALUE && est > 0)
                est--;
            if (advance(collections.length - 1)) {
                action.accept(new ArrayList<>(elements));
                return true;
            }
            elements = null;
            est = 0;
            return false;
        }

        @Override
        public void forEachRemaining(Consumer<? super List<T>> action) {
            if (elements == null)
                return;
            List<T> e = elements;
            int l = collections.length - 1;
            while (advance(l)) {
                action.accept(new ArrayList<>(e));
            }
            elements = null;
            est = 0;
        }

        @Override
        Spliterator<List<T>> doSplit(long prefixEst, Spliterator<T>[] prefixSpliterators,
                Collection<T>[] prefixCollections) {
            @SuppressWarnings("unchecked")
            List<T> prefixElements = (List<T>) Arrays.asList(elements.toArray());
            return new ToList<>(prefixEst, splitPos, prefixSpliterators, prefixCollections, prefixElements);
        }

        @Override
        void accumulate(int pos, T t) {
            elements.set(pos, t);
        }
    }

    boolean advance(int i) {
        if (spliterators[i] == null) {
            if (i > 0 && collections[i - 1] != null && !advance(i - 1))
                return false;
            spliterators[i] = collections[i].spliterator();
        }
        Consumer<? super T> action = t -> accumulate(i, t);
        if (!spliterators[i].tryAdvance(action)) {
            if (i == 0 || collections[i - 1] == null || !advance(i - 1))
                return false;
            spliterators[i] = collections[i].spliterator();
            return spliterators[i].tryAdvance(action);
        }
        return true;
    }

    @Override
    public Spliterator<A> trySplit() {<FILL_FUNCTION_BODY>

        if (spliterators[splitPos] == null)
            spliterators[splitPos] = collections[splitPos].spliterator();
        Spliterator<T> res = spliterators[splitPos].trySplit();
        if (res == null) {
            if (splitPos == spliterators.length - 1)
                return null;
            @SuppressWarnings("unchecked")
            T[] arr = (T[]) StreamSupport.stream(spliterators[splitPos], false).toArray();
            if (arr.length == 0)
                return null;
            if (arr.length == 1) {
                accumulate(splitPos, arr[0]);
                splitPos++;
                return trySplit();
            }
            spliterators[splitPos] = Spliterators.spliterator(arr, Spliterator.ORDERED);
            return trySplit();
        }
        long prefixEst = Long.MAX_VALUE;
        long newEst = spliterators[splitPos].getExactSizeIfKnown();
        if (newEst == -1) {
            newEst = Long.MAX_VALUE;
        } else {
            try {
                for (int i = splitPos + 1; i < collections.length; i++) {
                    long size = collections[i].size();
                    newEst = StrictMath.multiplyExact(newEst, size);
                }
                if (est != Long.MAX_VALUE)
                    prefixEst = est - newEst;
            } catch (ArithmeticException e) {
                newEst = Long.MAX_VALUE;
            }
        }
        Spliterator<T>[] prefixSpliterators = spliterators.clone();
        Collection<T>[] prefixCollections = collections.clone();
        prefixSpliterators[splitPos] = res;
        this.est = newEst;
        Arrays.fill(spliterators, splitPos + 1, spliterators.length, null);
        return doSplit(prefixEst, prefixSpliterators, prefixCollections);
    
<no_super_class>