static <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> Seq<R> zipAll(Seq<? extends T1> s1, Seq<? extends T2> s2, Seq<? extends T3> s3, Seq<? extends T4> s4, Seq<? extends T5> s5, Seq<? extends T6> s6, Seq<? extends T7> s7, Seq<? extends T8> s8, Seq<? extends T9> s9, T1 default1, T2 default2, T3 default3, T4 default4, T5 default5, T6 default6, T7 default7, T8 default8, T9 default9, Function9<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? extends R> zipper) {
        final Iterator<? extends T1> it1 = s1.iterator();
        final Iterator<? extends T2> it2 = s2.iterator();
        final Iterator<? extends T3> it3 = s3.iterator();
        final Iterator<? extends T4> it4 = s4.iterator();
        final Iterator<? extends T5> it5 = s5.iterator();
        final Iterator<? extends T6> it6 = s6.iterator();
        final Iterator<? extends T7> it7 = s7.iterator();
        final Iterator<? extends T8> it8 = s8.iterator();
        final Iterator<? extends T9> it9 = s9.iterator();

        class ZipAll implements Iterator<R> {
            
            @Override
            public boolean hasNext() {
                return it1.hasNext() || it2.hasNext() || it3.hasNext() || it4.hasNext() || it5.hasNext() || it6.hasNext() || it7.hasNext() || it8.hasNext() || it9.hasNext();
            }

            @Override
            public R next() {
                boolean b1 = it1.hasNext();
                boolean b2 = it2.hasNext();
                boolean b3 = it3.hasNext();
                boolean b4 = it4.hasNext();
                boolean b5 = it5.hasNext();
                boolean b6 = it6.hasNext();
                boolean b7 = it7.hasNext();
                boolean b8 = it8.hasNext();
                boolean b9 = it9.hasNext();
                
                if (!b1 && !b2 && !b3 && !b4 && !b5 && !b6 && !b7 && !b8 && !b9)
                    throw new NoSuchElementException("next on empty iterator");
                
                return zipper.apply(
                    b1 ? it1.next() : default1,
                    b2 ? it2.next() : default2,
                    b3 ? it3.next() : default3,
                    b4 ? it4.next() : default4,
                    b5 ? it5.next() : default5,
                    b6 ? it6.next() : default6,
                    b7 ? it7.next() : default7,
                    b8 ? it8.next() : default8,
                    b9 ? it9.next() : default9
                );
            }
        }

        return seq(new ZipAll()).onClose(SeqUtils.closeAll(s1, s2, s3, s4, s5, s6, s7, s8, s9));
    }
Zip two streams into one using a {@link BiFunction} to produce resulting values,
when one of streams will end, a default value for that stream will be provided instead -
so the resulting stream will be as long as the longest of the two streams.
<p>
<pre><code>
// ("1:a", "2:x", "3:x")
Seq.zipAll(Seq.of(1, 2, 3), Seq.of("a"), 0, "x", (i, s) -> i + ":" + s)
</code></pre>
jOOL/src/main/java/org/jooq/lambda/Seq.java