You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/11/12 16:43:34 UTC

[1/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Repository: groovy
Updated Branches:
  refs/heads/master f07dbebe0 -> 3ac1abcd0


http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/test/groovy/lang/TupleTest.java
----------------------------------------------------------------------
diff --git a/src/test/groovy/lang/TupleTest.java b/src/test/groovy/lang/TupleTest.java
index 19f07b7..65243cc 100644
--- a/src/test/groovy/lang/TupleTest.java
+++ b/src/test/groovy/lang/TupleTest.java
@@ -18,9 +18,31 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Consumer0;
+import groovy.util.function.Consumer1;
+import groovy.util.function.Consumer2;
 import junit.framework.TestCase;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import static groovy.lang.Tuple.collectors;
+import static groovy.lang.Tuple.tuple;
+import static java.util.stream.Collectors.averagingInt;
+import static java.util.stream.Collectors.counting;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.mapping;
 
 /**
  * @author James Strachan
@@ -41,15 +63,13 @@ public class TupleTest extends TestCase {
         try {
             t.get(-1);
             fail("Should have thrown IndexOut");
-        }
-        catch (IndexOutOfBoundsException e) {
+        } catch (IndexOutOfBoundsException e) {
             // worked
         }
         try {
             t.get(10);
             fail("Should have thrown IndexOut");
-        }
-        catch (IndexOutOfBoundsException e) {
+        } catch (IndexOutOfBoundsException e) {
             // worked
         }
 
@@ -307,4 +327,280 @@ public class TupleTest extends TestCase {
 
         assertEquals(t, t.subTuple(0, t.size()));
     }
+
+    public void testEqualsHashCode() {
+        Set<Tuple2<Integer, String>> set = new HashSet<>();
+
+        set.add(tuple(1, "abc"));
+        assertEquals(1, set.size());
+        set.add(tuple(1, "abc"));
+        assertEquals(1, set.size());
+        set.add(tuple(null, null));
+        assertEquals(2, set.size());
+        set.add(tuple(null, null));
+        assertEquals(2, set.size());
+        set.add(tuple(1, null));
+        assertEquals(3, set.size());
+        set.add(tuple(1, null));
+        assertEquals(3, set.size());
+    }
+
+    public void testEqualsNull() {
+        assertFalse(tuple(1).equals(null));
+        assertFalse(tuple(1, 2).equals(null));
+        assertFalse(tuple(1, 2, 3).equals(null));
+    }
+
+    public void testToMap() {
+        Map<Integer, Object> m = new LinkedHashMap<>();
+        m.put(0, 1);
+        m.put(1, "a");
+        m.put(2, null);
+        assertEquals(m, tuple(1, "a", null).toMap(i -> i));
+    }
+
+    public void testSwap() {
+        assertEquals(tuple(1, "a"), tuple("a", 1).swap());
+        assertEquals(tuple(1, "a"), tuple(1, "a").swap().swap());
+    }
+
+    public void testConcat() {
+        assertEquals(tuple(1, "a"), tuple(1).concat("a"));
+        assertEquals(tuple(1, "a", 2), tuple(1).concat("a").concat(2));
+
+        assertEquals(tuple(1, "a"), tuple(1).concat(tuple("a")));
+        assertEquals(tuple(1, "a", 2, "b", 3, "c", 4, "d"), tuple(1).concat(tuple("a", 2, "b").concat(tuple(3).concat(tuple("c", 4, "d")))));
+    }
+
+    public void testCompareTo() {
+        Set<Tuple2<Integer, String>> set = new TreeSet<>();
+
+        set.add(tuple(2, "a"));
+        set.add(tuple(1, "b"));
+        set.add(tuple(1, "a"));
+        set.add(tuple(2, "a"));
+
+        assertEquals(3, set.size());
+        assertEquals(Arrays.asList(tuple(1, "a"), tuple(1, "b"), tuple(2, "a")), new ArrayList<>(set));
+    }
+
+    public void testCompareToWithNulls() {
+        Set<Tuple2<Integer, String>> set = new TreeSet<>();
+
+        set.add(tuple(2, "a"));
+        set.add(tuple(1, "b"));
+        set.add(tuple(1, null));
+        set.add(tuple(null, "a"));
+        set.add(tuple(null, "b"));
+        set.add(tuple(null, null));
+
+        assertEquals(6, set.size());
+        assertEquals(Arrays.asList(tuple(1, "b"), tuple(1, null), tuple(2, "a"), tuple(null, "a"), tuple(null, "b"), tuple(null, null)), new ArrayList<>(set));
+    }
+
+    public void testIterable() {
+        LinkedList<Object> list = new LinkedList<>(tuple(1, "b", null));
+        for (Object o : tuple(1, "b", null)) {
+            assertEquals(list.poll(), o);
+        }
+    }
+
+    public void testFunctions() {
+        assertEquals("[1, b, null]", tuple(1, "b", null).map((v1, v2, v3) -> tuple(v1, v2, v3).toString()));
+        assertEquals("1-b", tuple(1, "b", null).map((v1, v2, v3) -> v1 + "-" + v2));
+    }
+
+    public void testMapN() {
+        assertEquals(tuple(1, "a", 2, "b"), tuple(1, null, 2, null).map2(v -> "a").map4(v -> "b"));
+    }
+
+    public void testOverlaps() {
+        assertTrue(Tuple2.overlaps(tuple(1, 3), tuple(1, 3)));
+        assertTrue(Tuple2.overlaps(tuple(1, 3), tuple(2, 3)));
+        assertTrue(Tuple2.overlaps(tuple(1, 3), tuple(2, 4)));
+        assertTrue(Tuple2.overlaps(tuple(1, 3), tuple(3, 4)));
+        assertFalse(Tuple2.overlaps(tuple(1, 3), tuple(4, 5)));
+        assertFalse(Tuple2.overlaps(tuple(1, 1), tuple(2, 2)));
+    }
+
+    public void testIntersect() {
+        assertEquals(Optional.of(tuple(2, 3)), Tuple2.intersect(tuple(1, 3), tuple(2, 4)));
+        assertEquals(Optional.of(tuple(3, 3)), Tuple2.intersect(tuple(1, 3), tuple(3, 5)));
+        assertEquals(Optional.empty(), Tuple2.intersect(tuple(1, 3), tuple(4, 5)));
+    }
+
+    public void testCollectors() {
+        assertEquals(
+                tuple(3L),
+                Stream.of(1, 2, 3)
+                        .collect(collectors(counting()))
+        );
+
+        assertEquals(
+                tuple(3L, "1, 2, 3"),
+                Stream.of(1, 2, 3)
+                        .collect(collectors(
+                                counting(),
+                                mapping(Object::toString, joining(", "))
+                        ))
+        );
+
+        assertEquals(
+                tuple(3L, "1, 2, 3", 2.0),
+                Stream.of(1, 2, 3)
+                        .collect(collectors(
+                                counting(),
+                                mapping(Object::toString, joining(", ")),
+                                averagingInt(Integer::intValue)
+                        ))
+        );
+    }
+
+    public void testLimit() {
+        assertEquals(
+                tuple(),
+                tuple(1, "A", 2, "B").limit0()
+        );
+        assertEquals(
+                tuple(1),
+                tuple(1, "A", 2, "B").limit1()
+        );
+        assertEquals(
+                tuple(1, "A"),
+                tuple(1, "A", 2, "B").limit2()
+        );
+        assertEquals(
+                tuple(1, "A", 2),
+                tuple(1, "A", 2, "B").limit3()
+        );
+        assertEquals(
+                tuple(1, "A", 2, "B"),
+                tuple(1, "A", 2, "B").limit4()
+        );
+    }
+
+    public void testSkip() {
+        assertEquals(
+                tuple(),
+                tuple(1, "A", 2, "B").skip4()
+        );
+        assertEquals(
+                tuple("B"),
+                tuple(1, "A", 2, "B").skip3()
+        );
+        assertEquals(
+                tuple(2, "B"),
+                tuple(1, "A", 2, "B").skip2()
+        );
+        assertEquals(
+                tuple("A", 2, "B"),
+                tuple(1, "A", 2, "B").skip1()
+        );
+        assertEquals(
+                tuple(1, "A", 2, "B"),
+                tuple(1, "A", 2, "B").skip0()
+        );
+    }
+
+    public void testSplit() {
+        assertEquals(
+                tuple(
+                        tuple(),
+                        tuple(1, "A", 2, "B")
+                ),
+                tuple(1, "A", 2, "B").split0()
+        );
+        assertEquals(
+                tuple(
+                        tuple(1),
+                        tuple("A", 2, "B")
+                ),
+                tuple(1, "A", 2, "B").split1()
+        );
+        assertEquals(
+                tuple(
+                        tuple(1, "A"),
+                        new Tuple2<>(2, "B")
+                ),
+                tuple(1, "A", 2, "B").split2()
+        );
+        assertEquals(
+                tuple(
+                        tuple(1, "A", 2),
+                        tuple("B")
+                ),
+                tuple(1, "A", 2, "B").split3()
+        );
+        assertEquals(
+                tuple(
+                        tuple(1, "A", 2, "B"),
+                        tuple()
+                ),
+                tuple(1, "A", 2, "B").split4()
+        );
+    }
+
+    int result;
+    public void testConsumers() {
+        Consumer0 c0 = () -> { result = 1; };
+        Runnable r = c0.toRunnable();
+        Consumer0 c0a = Consumer0.from(r);
+
+        result = 0;
+        c0.accept();
+        assertEquals(1, result);
+
+        result = 0;
+        c0.accept(Tuple.tuple());
+        assertEquals(1, result);
+
+        result = 0;
+        r.run();
+        assertEquals(1, result);
+
+        result = 0;
+        c0a.accept();
+        assertEquals(1, result);
+
+        Consumer1<Integer> c1 = i -> { result = i; };
+        Consumer<Integer> c1a = c1.toConsumer();
+        Consumer1<Integer> c1b = Consumer1.from(c1a);
+
+        result = 0;
+        c1.accept(1);
+        assertEquals(1, result);
+
+        result = 0;
+        c1.accept(Tuple.tuple(1));
+        assertEquals(1, result);
+
+        result = 0;
+        c1a.accept(1);
+        assertEquals(1, result);
+
+        result = 0;
+        c1b.accept(1);
+        assertEquals(1, result);
+
+        Consumer2<Integer, Integer> c2 = (i, j) -> { result = i + j; };
+        BiConsumer<Integer, Integer> c2a = c2.toBiConsumer();
+        Consumer2<Integer, Integer> c2b = Consumer2.from(c2a);
+
+        result = 0;
+        c2.accept(1, 2);
+        assertEquals(3, result);
+
+        result = 0;
+        c2.accept(Tuple.tuple(1, 2));
+        assertEquals(3, result);
+
+        result = 0;
+        c2a.accept(1, 2);
+        assertEquals(3, result);
+
+        result = 0;
+        c2b.accept(1, 2);
+        assertEquals(3, result);
+    }
+
 }


[8/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
GROOVY-8874: Refine tuples to support functional programming better(closes #821)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/3ac1abcd
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/3ac1abcd
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/3ac1abcd

Branch: refs/heads/master
Commit: 3ac1abcd0b586f531272bb06b93c8307df357d64
Parents: f07dbeb
Author: Daniel Sun <su...@apache.org>
Authored: Tue Nov 13 00:43:03 2018 +0800
Committer: Daniel Sun <su...@apache.org>
Committed: Tue Nov 13 00:43:03 2018 +0800

----------------------------------------------------------------------
 src/main/groovy/groovy/lang/Tuple.java          | 1412 +++++++++++++++++-
 src/main/groovy/groovy/lang/Tuple0.java         |  188 +++
 src/main/groovy/groovy/lang/Tuple1.java         |  203 ++-
 src/main/groovy/groovy/lang/Tuple10.java        |  510 +++++++
 src/main/groovy/groovy/lang/Tuple11.java        |  537 +++++++
 src/main/groovy/groovy/lang/Tuple12.java        |  565 +++++++
 src/main/groovy/groovy/lang/Tuple13.java        |  592 ++++++++
 src/main/groovy/groovy/lang/Tuple14.java        |  618 ++++++++
 src/main/groovy/groovy/lang/Tuple15.java        |  644 ++++++++
 src/main/groovy/groovy/lang/Tuple16.java        |  665 +++++++++
 src/main/groovy/groovy/lang/Tuple2.java         |  271 +++-
 src/main/groovy/groovy/lang/Tuple3.java         |  275 +++-
 src/main/groovy/groovy/lang/Tuple4.java         |  309 +++-
 src/main/groovy/groovy/lang/Tuple5.java         |  343 ++++-
 src/main/groovy/groovy/lang/Tuple6.java         |  377 ++++-
 src/main/groovy/groovy/lang/Tuple7.java         |  413 ++++-
 src/main/groovy/groovy/lang/Tuple8.java         |  447 +++++-
 src/main/groovy/groovy/lang/Tuple9.java         |  481 +++++-
 .../groovy/groovy/util/function/Consumer0.java  |   64 +
 .../groovy/groovy/util/function/Consumer1.java  |   75 +
 .../groovy/groovy/util/function/Consumer10.java |  194 +++
 .../groovy/groovy/util/function/Consumer11.java |  209 +++
 .../groovy/groovy/util/function/Consumer12.java |  224 +++
 .../groovy/groovy/util/function/Consumer13.java |  239 +++
 .../groovy/groovy/util/function/Consumer14.java |  254 ++++
 .../groovy/groovy/util/function/Consumer15.java |  269 ++++
 .../groovy/groovy/util/function/Consumer16.java |  284 ++++
 .../groovy/groovy/util/function/Consumer2.java  |   90 ++
 .../groovy/groovy/util/function/Consumer3.java  |   89 ++
 .../groovy/groovy/util/function/Consumer4.java  |  104 ++
 .../groovy/groovy/util/function/Consumer5.java  |  119 ++
 .../groovy/groovy/util/function/Consumer6.java  |  134 ++
 .../groovy/groovy/util/function/Consumer7.java  |  149 ++
 .../groovy/groovy/util/function/Consumer8.java  |  164 ++
 .../groovy/groovy/util/function/Consumer9.java  |  179 +++
 .../groovy/groovy/util/function/Function0.java  |   69 +
 .../groovy/groovy/util/function/Function1.java  |   75 +
 .../groovy/groovy/util/function/Function10.java |  195 +++
 .../groovy/groovy/util/function/Function11.java |  210 +++
 .../groovy/groovy/util/function/Function12.java |  225 +++
 .../groovy/groovy/util/function/Function13.java |  240 +++
 .../groovy/groovy/util/function/Function14.java |  255 ++++
 .../groovy/groovy/util/function/Function15.java |  270 ++++
 .../groovy/groovy/util/function/Function16.java |  285 ++++
 .../groovy/groovy/util/function/Function2.java  |   91 ++
 .../groovy/groovy/util/function/Function3.java  |   90 ++
 .../groovy/groovy/util/function/Function4.java  |  105 ++
 .../groovy/groovy/util/function/Function5.java  |  120 ++
 .../groovy/groovy/util/function/Function6.java  |  135 ++
 .../groovy/groovy/util/function/Function7.java  |  150 ++
 .../groovy/groovy/util/function/Function8.java  |  165 ++
 .../groovy/groovy/util/function/Function9.java  |  180 +++
 src/test/groovy/lang/TupleTest.java             |  304 +++-
 53 files changed, 14504 insertions(+), 350 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple.java b/src/main/groovy/groovy/lang/Tuple.java
index 8a1a6e7..1ccd5bd 100644
--- a/src/main/groovy/groovy/lang/Tuple.java
+++ b/src/main/groovy/groovy/lang/Tuple.java
@@ -18,19 +18,56 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Consumer0;
+import groovy.util.function.Consumer1;
+import groovy.util.function.Consumer10;
+import groovy.util.function.Consumer11;
+import groovy.util.function.Consumer12;
+import groovy.util.function.Consumer13;
+import groovy.util.function.Consumer14;
+import groovy.util.function.Consumer15;
+import groovy.util.function.Consumer16;
+import groovy.util.function.Consumer2;
+import groovy.util.function.Consumer3;
+import groovy.util.function.Consumer4;
+import groovy.util.function.Consumer5;
+import groovy.util.function.Consumer6;
+import groovy.util.function.Consumer7;
+import groovy.util.function.Consumer8;
+import groovy.util.function.Consumer9;
+import groovy.util.function.Function0;
+import groovy.util.function.Function1;
+import groovy.util.function.Function10;
+import groovy.util.function.Function11;
+import groovy.util.function.Function12;
+import groovy.util.function.Function13;
+import groovy.util.function.Function14;
+import groovy.util.function.Function15;
+import groovy.util.function.Function16;
+import groovy.util.function.Function2;
+import groovy.util.function.Function3;
+import groovy.util.function.Function4;
+import groovy.util.function.Function5;
+import groovy.util.function.Function6;
+import groovy.util.function.Function7;
+import groovy.util.function.Function8;
+import groovy.util.function.Function9;
 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
 
 import java.io.Serializable;
 import java.util.AbstractList;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.stream.Collector;
 
 /**
  * Represents a list of Objects.
- * 
+ *
  * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
  */
-public class Tuple<E> extends AbstractList<E> implements Serializable {
+public class Tuple<E> extends AbstractList<E> implements Serializable, Cloneable, Comparable<Tuple<E>> {
     private static final long serialVersionUID = -6707770506387821031L;
     private final E[] contents;
 
@@ -40,6 +77,10 @@ public class Tuple<E> extends AbstractList<E> implements Serializable {
         this.contents = contents;
     }
 
+    public Tuple(Tuple<E> tuple) {
+        this.contents = tuple.contents;
+    }
+
     @Override
     public E get(int index) {
         return contents[index];
@@ -50,6 +91,29 @@ public class Tuple<E> extends AbstractList<E> implements Serializable {
         return contents.length;
     }
 
+    @Override
+    public E[] toArray() {
+        return contents;
+    }
+
+    /**
+     * The degree of this tuple
+     */
+    public final int degree() {
+        return this.size();
+    }
+
+    public final <K> Map<K, ?> toMap(Function1<? super Integer, ? extends K> keyMapper) {
+        Object[] array = toArray();
+        Map<K, Object> result = new LinkedHashMap<>();
+
+        for (int i = 0, n = array.length; i < n; i++) {
+            result.put(keyMapper.apply(i), array[i]);
+        }
+
+        return result;
+    }
+
     @SuppressWarnings("unchecked")
     @Override
     public List<E> subList(int fromIndex, int toIndex) {
@@ -83,4 +147,1348 @@ public class Tuple<E> extends AbstractList<E> implements Serializable {
     public int hashCode() {
         return Objects.hash(contents);
     }
+
+    @Override
+    public int compareTo(Tuple<E> other) {
+        int thisSize = this.size();
+        int otherSize = other.size();
+
+        for (int i = 0, n = Math.min(thisSize, otherSize); i < n; i++) {
+            int result = compare(this.get(i), other.get(i));
+            if (result != 0) {
+                return result;
+            }
+        }
+
+        return Integer.compare(thisSize, otherSize);
+    }
+
+    @Override
+    public Tuple<E> clone() {
+        return new Tuple<>(this);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> int compare(T t1, T t2) {
+        return t1 == null && t2 == null
+                ? 0
+                : t1 == null
+                ? 1
+                : t2 == null
+                ? -1
+                : ((Comparable<T>) t1).compareTo(t2);
+    }
+
+
+    /**
+     * Construct a tuple of degree 0.
+     */
+    public static Tuple0 tuple() {
+        return new Tuple0();
+    }
+
+    /**
+     * Construct a tuple of degree 1.
+     */
+    public static <T1> Tuple1<T1> tuple(T1 v1) {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Construct a tuple of degree 2.
+     */
+    public static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2) {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Construct a tuple of degree 3.
+     */
+    public static <T1, T2, T3> Tuple3<T1, T2, T3> tuple(T1 v1, T2 v2, T3 v3) {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Construct a tuple of degree 4.
+     */
+    public static <T1, T2, T3, T4> Tuple4<T1, T2, T3, T4> tuple(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Construct a tuple of degree 5.
+     */
+    public static <T1, T2, T3, T4, T5> Tuple5<T1, T2, T3, T4, T5> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Construct a tuple of degree 6.
+     */
+    public static <T1, T2, T3, T4, T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Construct a tuple of degree 7.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Construct a tuple of degree 8.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Construct a tuple of degree 9.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Construct a tuple of degree 10.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Construct a tuple of degree 11.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Construct a tuple of degree 12.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Construct a tuple of degree 13.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Construct a tuple of degree 14.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Construct a tuple of degree 15.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Construct a tuple of degree 16.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+
+    /**
+     * Construct a tuple function of degree 0.
+     */
+    public static <R> Function1<Tuple0, R> function(Function0<R> function) {
+        return t -> function.get();
+    }
+
+    /**
+     * Construct a tuple function of degree 1.
+     */
+    public static <T1, R> Function1<Tuple1<T1>, R> function(Function1<T1, R> function) {
+        return t -> function.apply(t.v1());
+    }
+
+    /**
+     * Construct a tuple function of degree 2.
+     */
+    public static <T1, T2, R> Function1<Tuple2<T1, T2>, R> function(Function2<T1, T2, R> function) {
+        return t -> function.apply(t.v1(), t.v2());
+    }
+
+    /**
+     * Construct a tuple function of degree 3.
+     */
+    public static <T1, T2, T3, R> Function1<Tuple3<T1, T2, T3>, R> function(Function3<T1, T2, T3, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3());
+    }
+
+    /**
+     * Construct a tuple function of degree 4.
+     */
+    public static <T1, T2, T3, T4, R> Function1<Tuple4<T1, T2, T3, T4>, R> function(Function4<T1, T2, T3, T4, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4());
+    }
+
+    /**
+     * Construct a tuple function of degree 5.
+     */
+    public static <T1, T2, T3, T4, T5, R> Function1<Tuple5<T1, T2, T3, T4, T5>, R> function(Function5<T1, T2, T3, T4, T5, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5());
+    }
+
+    /**
+     * Construct a tuple function of degree 6.
+     */
+    public static <T1, T2, T3, T4, T5, T6, R> Function1<Tuple6<T1, T2, T3, T4, T5, T6>, R> function(Function6<T1, T2, T3, T4, T5, T6, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6());
+    }
+
+    /**
+     * Construct a tuple function of degree 7.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, R> Function1<Tuple7<T1, T2, T3, T4, T5, T6, T7>, R> function(Function7<T1, T2, T3, T4, T5, T6, T7, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7());
+    }
+
+    /**
+     * Construct a tuple function of degree 8.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, R> Function1<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, R> function(Function8<T1, T2, T3, T4, T5, T6, T7, T8, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8());
+    }
+
+    /**
+     * Construct a tuple function of degree 9.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> Function1<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, R> function(Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9());
+    }
+
+    /**
+     * Construct a tuple function of degree 10.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> Function1<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, R> function(Function10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10());
+    }
+
+    /**
+     * Construct a tuple function of degree 11.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> Function1<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, R> function(Function11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11());
+    }
+
+    /**
+     * Construct a tuple function of degree 12.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> Function1<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>, R> function(Function12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12());
+    }
+
+    /**
+     * Construct a tuple function of degree 13.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> Function1<Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>, R> function(Function13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13());
+    }
+
+    /**
+     * Construct a tuple function of degree 14.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> Function1<Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>, R> function(Function14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13(), t.v14());
+    }
+
+    /**
+     * Construct a tuple function of degree 15.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> Function1<Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>, R> function(Function15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13(), t.v14(), t.v15());
+    }
+
+    /**
+     * Construct a tuple function of degree 16.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> Function1<Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>, R> function(Function16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> function) {
+        return t -> function.apply(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13(), t.v14(), t.v15(), t.v16());
+    }
+
+
+    /**
+     * Construct a tuple consumer of degree 0.
+     */
+    public static Consumer1<Tuple0> consumer(Consumer0 consumer) {
+        return t -> consumer.run();
+    }
+
+    /**
+     * Construct a tuple consumer of degree 1.
+     */
+    public static <T1> Consumer1<Tuple1<T1>> consumer(Consumer1<T1> consumer) {
+        return t -> consumer.accept(t.v1());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 2.
+     */
+    public static <T1, T2> Consumer1<Tuple2<T1, T2>> consumer(Consumer2<T1, T2> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 3.
+     */
+    public static <T1, T2, T3> Consumer1<Tuple3<T1, T2, T3>> consumer(Consumer3<T1, T2, T3> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 4.
+     */
+    public static <T1, T2, T3, T4> Consumer1<Tuple4<T1, T2, T3, T4>> consumer(Consumer4<T1, T2, T3, T4> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 5.
+     */
+    public static <T1, T2, T3, T4, T5> Consumer1<Tuple5<T1, T2, T3, T4, T5>> consumer(Consumer5<T1, T2, T3, T4, T5> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 6.
+     */
+    public static <T1, T2, T3, T4, T5, T6> Consumer1<Tuple6<T1, T2, T3, T4, T5, T6>> consumer(Consumer6<T1, T2, T3, T4, T5, T6> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 7.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7> Consumer1<Tuple7<T1, T2, T3, T4, T5, T6, T7>> consumer(Consumer7<T1, T2, T3, T4, T5, T6, T7> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 8.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8> Consumer1<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>> consumer(Consumer8<T1, T2, T3, T4, T5, T6, T7, T8> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 9.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9> Consumer1<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>> consumer(Consumer9<T1, T2, T3, T4, T5, T6, T7, T8, T9> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 10.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Consumer1<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>> consumer(Consumer10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 11.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Consumer1<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> consumer(Consumer11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 12.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Consumer1<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> consumer(Consumer12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 13.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Consumer1<Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> consumer(Consumer13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 14.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Consumer1<Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> consumer(Consumer14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13(), t.v14());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 15.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Consumer1<Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> consumer(Consumer15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13(), t.v14(), t.v15());
+    }
+
+    /**
+     * Construct a tuple consumer of degree 16.
+     */
+    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Consumer1<Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> consumer(Consumer16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> consumer) {
+        return t -> consumer.accept(t.v1(), t.v2(), t.v3(), t.v4(), t.v5(), t.v6(), t.v7(), t.v8(), t.v9(), t.v10(), t.v11(), t.v12(), t.v13(), t.v14(), t.v15(), t.v16());
+    }
+
+    /**
+     * Construct a tuple collector of degree 1.
+     */
+    public static <T, A1, D1> Collector<T, Tuple1<A1>, Tuple1<D1>> collectors(
+            Collector<? super T, A1, D1> collector1
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 2.
+     */
+    public static <T, A1, A2, D1, D2> Collector<T, Tuple2<A1, A2>, Tuple2<D1, D2>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 3.
+     */
+    public static <T, A1, A2, A3, D1, D2, D3> Collector<T, Tuple3<A1, A2, A3>, Tuple3<D1, D2, D3>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 4.
+     */
+    public static <T, A1, A2, A3, A4, D1, D2, D3, D4> Collector<T, Tuple4<A1, A2, A3, A4>, Tuple4<D1, D2, D3, D4>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 5.
+     */
+    public static <T, A1, A2, A3, A4, A5, D1, D2, D3, D4, D5> Collector<T, Tuple5<A1, A2, A3, A4, A5>, Tuple5<D1, D2, D3, D4, D5>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 6.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, D1, D2, D3, D4, D5, D6> Collector<T, Tuple6<A1, A2, A3, A4, A5, A6>, Tuple6<D1, D2, D3, D4, D5, D6>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 7.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, D1, D2, D3, D4, D5, D6, D7> Collector<T, Tuple7<A1, A2, A3, A4, A5, A6, A7>, Tuple7<D1, D2, D3, D4, D5, D6, D7>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 8.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, D1, D2, D3, D4, D5, D6, D7, D8> Collector<T, Tuple8<A1, A2, A3, A4, A5, A6, A7, A8>, Tuple8<D1, D2, D3, D4, D5, D6, D7, D8>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 9.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, D1, D2, D3, D4, D5, D6, D7, D8, D9> Collector<T, Tuple9<A1, A2, A3, A4, A5, A6, A7, A8, A9>, Tuple9<D1, D2, D3, D4, D5, D6, D7, D8, D9>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 10.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10> Collector<T, Tuple10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>, Tuple10<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 11.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11> Collector<T, Tuple11<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>, Tuple11<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+            , Collector<? super T, A11, D11> collector11
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                        , collector11.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                    collector11.accumulator().accept(a.v11(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                        , collector11.combiner().apply(a1.v11(), a2.v11())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                        , collector11.finisher().apply(a.v11())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 12.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12> Collector<T, Tuple12<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>, Tuple12<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+            , Collector<? super T, A11, D11> collector11
+            , Collector<? super T, A12, D12> collector12
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                        , collector11.supplier().get()
+                        , collector12.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                    collector11.accumulator().accept(a.v11(), t);
+                    collector12.accumulator().accept(a.v12(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                        , collector11.combiner().apply(a1.v11(), a2.v11())
+                        , collector12.combiner().apply(a1.v12(), a2.v12())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                        , collector11.finisher().apply(a.v11())
+                        , collector12.finisher().apply(a.v12())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 13.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13> Collector<T, Tuple13<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>, Tuple13<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+            , Collector<? super T, A11, D11> collector11
+            , Collector<? super T, A12, D12> collector12
+            , Collector<? super T, A13, D13> collector13
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                        , collector11.supplier().get()
+                        , collector12.supplier().get()
+                        , collector13.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                    collector11.accumulator().accept(a.v11(), t);
+                    collector12.accumulator().accept(a.v12(), t);
+                    collector13.accumulator().accept(a.v13(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                        , collector11.combiner().apply(a1.v11(), a2.v11())
+                        , collector12.combiner().apply(a1.v12(), a2.v12())
+                        , collector13.combiner().apply(a1.v13(), a2.v13())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                        , collector11.finisher().apply(a.v11())
+                        , collector12.finisher().apply(a.v12())
+                        , collector13.finisher().apply(a.v13())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 14.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14> Collector<T, Tuple14<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>, Tuple14<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+            , Collector<? super T, A11, D11> collector11
+            , Collector<? super T, A12, D12> collector12
+            , Collector<? super T, A13, D13> collector13
+            , Collector<? super T, A14, D14> collector14
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                        , collector11.supplier().get()
+                        , collector12.supplier().get()
+                        , collector13.supplier().get()
+                        , collector14.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                    collector11.accumulator().accept(a.v11(), t);
+                    collector12.accumulator().accept(a.v12(), t);
+                    collector13.accumulator().accept(a.v13(), t);
+                    collector14.accumulator().accept(a.v14(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                        , collector11.combiner().apply(a1.v11(), a2.v11())
+                        , collector12.combiner().apply(a1.v12(), a2.v12())
+                        , collector13.combiner().apply(a1.v13(), a2.v13())
+                        , collector14.combiner().apply(a1.v14(), a2.v14())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                        , collector11.finisher().apply(a.v11())
+                        , collector12.finisher().apply(a.v12())
+                        , collector13.finisher().apply(a.v13())
+                        , collector14.finisher().apply(a.v14())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 15.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15> Collector<T, Tuple15<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>, Tuple15<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+            , Collector<? super T, A11, D11> collector11
+            , Collector<? super T, A12, D12> collector12
+            , Collector<? super T, A13, D13> collector13
+            , Collector<? super T, A14, D14> collector14
+            , Collector<? super T, A15, D15> collector15
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                        , collector11.supplier().get()
+                        , collector12.supplier().get()
+                        , collector13.supplier().get()
+                        , collector14.supplier().get()
+                        , collector15.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                    collector11.accumulator().accept(a.v11(), t);
+                    collector12.accumulator().accept(a.v12(), t);
+                    collector13.accumulator().accept(a.v13(), t);
+                    collector14.accumulator().accept(a.v14(), t);
+                    collector15.accumulator().accept(a.v15(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                        , collector11.combiner().apply(a1.v11(), a2.v11())
+                        , collector12.combiner().apply(a1.v12(), a2.v12())
+                        , collector13.combiner().apply(a1.v13(), a2.v13())
+                        , collector14.combiner().apply(a1.v14(), a2.v14())
+                        , collector15.combiner().apply(a1.v15(), a2.v15())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                        , collector11.finisher().apply(a.v11())
+                        , collector12.finisher().apply(a.v12())
+                        , collector13.finisher().apply(a.v13())
+                        , collector14.finisher().apply(a.v14())
+                        , collector15.finisher().apply(a.v15())
+                )
+        );
+    }
+
+    /**
+     * Construct a tuple collector of degree 16.
+     */
+    public static <T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16> Collector<T, Tuple16<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16>, Tuple16<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16>> collectors(
+            Collector<? super T, A1, D1> collector1
+            , Collector<? super T, A2, D2> collector2
+            , Collector<? super T, A3, D3> collector3
+            , Collector<? super T, A4, D4> collector4
+            , Collector<? super T, A5, D5> collector5
+            , Collector<? super T, A6, D6> collector6
+            , Collector<? super T, A7, D7> collector7
+            , Collector<? super T, A8, D8> collector8
+            , Collector<? super T, A9, D9> collector9
+            , Collector<? super T, A10, D10> collector10
+            , Collector<? super T, A11, D11> collector11
+            , Collector<? super T, A12, D12> collector12
+            , Collector<? super T, A13, D13> collector13
+            , Collector<? super T, A14, D14> collector14
+            , Collector<? super T, A15, D15> collector15
+            , Collector<? super T, A16, D16> collector16
+    ) {
+        return Collector.of(
+                () -> tuple(
+                        collector1.supplier().get()
+                        , collector2.supplier().get()
+                        , collector3.supplier().get()
+                        , collector4.supplier().get()
+                        , collector5.supplier().get()
+                        , collector6.supplier().get()
+                        , collector7.supplier().get()
+                        , collector8.supplier().get()
+                        , collector9.supplier().get()
+                        , collector10.supplier().get()
+                        , collector11.supplier().get()
+                        , collector12.supplier().get()
+                        , collector13.supplier().get()
+                        , collector14.supplier().get()
+                        , collector15.supplier().get()
+                        , collector16.supplier().get()
+                ),
+                (a, t) -> {
+                    collector1.accumulator().accept(a.v1(), t);
+                    collector2.accumulator().accept(a.v2(), t);
+                    collector3.accumulator().accept(a.v3(), t);
+                    collector4.accumulator().accept(a.v4(), t);
+                    collector5.accumulator().accept(a.v5(), t);
+                    collector6.accumulator().accept(a.v6(), t);
+                    collector7.accumulator().accept(a.v7(), t);
+                    collector8.accumulator().accept(a.v8(), t);
+                    collector9.accumulator().accept(a.v9(), t);
+                    collector10.accumulator().accept(a.v10(), t);
+                    collector11.accumulator().accept(a.v11(), t);
+                    collector12.accumulator().accept(a.v12(), t);
+                    collector13.accumulator().accept(a.v13(), t);
+                    collector14.accumulator().accept(a.v14(), t);
+                    collector15.accumulator().accept(a.v15(), t);
+                    collector16.accumulator().accept(a.v16(), t);
+                },
+                (a1, a2) -> tuple(
+                        collector1.combiner().apply(a1.v1(), a2.v1())
+                        , collector2.combiner().apply(a1.v2(), a2.v2())
+                        , collector3.combiner().apply(a1.v3(), a2.v3())
+                        , collector4.combiner().apply(a1.v4(), a2.v4())
+                        , collector5.combiner().apply(a1.v5(), a2.v5())
+                        , collector6.combiner().apply(a1.v6(), a2.v6())
+                        , collector7.combiner().apply(a1.v7(), a2.v7())
+                        , collector8.combiner().apply(a1.v8(), a2.v8())
+                        , collector9.combiner().apply(a1.v9(), a2.v9())
+                        , collector10.combiner().apply(a1.v10(), a2.v10())
+                        , collector11.combiner().apply(a1.v11(), a2.v11())
+                        , collector12.combiner().apply(a1.v12(), a2.v12())
+                        , collector13.combiner().apply(a1.v13(), a2.v13())
+                        , collector14.combiner().apply(a1.v14(), a2.v14())
+                        , collector15.combiner().apply(a1.v15(), a2.v15())
+                        , collector16.combiner().apply(a1.v16(), a2.v16())
+                ),
+                a -> tuple(
+                        collector1.finisher().apply(a.v1())
+                        , collector2.finisher().apply(a.v2())
+                        , collector3.finisher().apply(a.v3())
+                        , collector4.finisher().apply(a.v4())
+                        , collector5.finisher().apply(a.v5())
+                        , collector6.finisher().apply(a.v6())
+                        , collector7.finisher().apply(a.v7())
+                        , collector8.finisher().apply(a.v8())
+                        , collector9.finisher().apply(a.v9())
+                        , collector10.finisher().apply(a.v10())
+                        , collector11.finisher().apply(a.v11())
+                        , collector12.finisher().apply(a.v12())
+                        , collector13.finisher().apply(a.v13())
+                        , collector14.finisher().apply(a.v14())
+                        , collector15.finisher().apply(a.v15())
+                        , collector16.finisher().apply(a.v16())
+                )
+        );
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple0.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple0.java b/src/main/groovy/groovy/lang/Tuple0.java
new file mode 100644
index 0000000..eaffc25
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple0.java
@@ -0,0 +1,188 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.lang;
+
+import groovy.util.function.Function0;
+
+/**
+ * Represents a list of 0 typed Object.
+ *
+ * @since 3.0.0
+ */
+public class Tuple0 extends Tuple {
+    private static final long serialVersionUID = -3791115121904072346L;
+
+    public Tuple0() {
+    }
+
+    public Tuple0(Tuple0 tuple) {
+    }
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T1> Tuple1<T1> concat(T1 value) {
+        return new Tuple1<>(value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1> Tuple1<T1> concat(Tuple1<T1> tuple) {
+        return new Tuple1<>(tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2> Tuple2<T1, T2> concat(Tuple2<T1, T2> tuple) {
+        return new Tuple2<>(tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3> Tuple3<T1, T2, T3> concat(Tuple3<T1, T2, T3> tuple) {
+        return new Tuple3<>(tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4> Tuple4<T1, T2, T3, T4> concat(Tuple4<T1, T2, T3, T4> tuple) {
+        return new Tuple4<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5> Tuple5<T1, T2, T3, T4, T5> concat(Tuple5<T1, T2, T3, T4, T5> tuple) {
+        return new Tuple5<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(Tuple6<T1, T2, T3, T4, T5, T6> tuple) {
+        return new Tuple6<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple7<T1, T2, T3, T4, T5, T6, T7> tuple) {
+        return new Tuple7<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> tuple) {
+        return new Tuple8<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple) {
+        return new Tuple9<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13(), tuple.v14());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13(), tuple.v14(), tuple.v15());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13(), tuple.v14(), tuple.v15(), tuple.v16());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 0.
+     */
+    public final Tuple2<Tuple0, Tuple0> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple0 skip0() {
+        return this;
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function0<? extends R> function) {
+        return function.apply();
+    }
+
+    @Override
+    public Tuple0 clone() {
+        return new Tuple0(this);
+    }
+}


[7/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple1.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple1.java b/src/main/groovy/groovy/lang/Tuple1.java
index 9b8d6bd..1e84013 100644
--- a/src/main/groovy/groovy/lang/Tuple1.java
+++ b/src/main/groovy/groovy/lang/Tuple1.java
@@ -18,6 +18,8 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Function1;
+
 /**
  * Represents a list of 1 typed Object.
  *
@@ -25,30 +27,197 @@ package groovy.lang;
  */
 public class Tuple1<T1> extends Tuple {
     private static final long serialVersionUID = -4647790147461409603L;
-    private final T1 first;
+    private final T1 v1;
 
-    public Tuple1(T1 first) {
-        super(first);
+    public Tuple1(T1 t1) {
+        super(t1);
 
-        this.first = first;
+        this.v1 = t1;
     }
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+    public Tuple1(Tuple1<T1> tuple) {
+        this(tuple.v1);
     }
 
-    @Override
-    public int size() {
-        return 1;
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
     }
 
-    public T1 getFirst() {
-        return first;
+    public T1 v1() {
+        return v1;
+    }
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T2> Tuple2<T1, T2> concat(T2 value) {
+        return new Tuple2<>(v1, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2> Tuple2<T1, T2> concat(Tuple1<T2> tuple) {
+        return new Tuple2<>(v1, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3> Tuple3<T1, T2, T3> concat(Tuple2<T2, T3> tuple) {
+        return new Tuple3<>(v1, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4> Tuple4<T1, T2, T3, T4> concat(Tuple3<T2, T3, T4> tuple) {
+        return new Tuple4<>(v1, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5> Tuple5<T1, T2, T3, T4, T5> concat(Tuple4<T2, T3, T4, T5> tuple) {
+        return new Tuple5<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(Tuple5<T2, T3, T4, T5, T6> tuple) {
+        return new Tuple6<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple6<T2, T3, T4, T5, T6, T7> tuple) {
+        return new Tuple7<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple7<T2, T3, T4, T5, T6, T7, T8> tuple) {
+        return new Tuple8<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple8<T2, T3, T4, T5, T6, T7, T8, T9> tuple) {
+        return new Tuple9<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple9<T2, T3, T4, T5, T6, T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13(), tuple.v14());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13(), tuple.v14(), tuple.v15());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 1.
+     */
+    public final Tuple2<Tuple0, Tuple1<T1>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 0.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple0> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple1<T1> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple0 skip1() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function1<? super T1, ? extends R> function) {
+        return function.apply(v1);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple1<U1> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple1<>(function.apply(v1));
+    }
+
+    @Override
+    public Tuple1<T1> clone() {
+        return new Tuple1<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple10.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple10.java b/src/main/groovy/groovy/lang/Tuple10.java
new file mode 100644
index 0000000..6d3ca62
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple10.java
@@ -0,0 +1,510 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function10;
+
+/**
+ * Represents a list of 10 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> extends Tuple {
+    private static final long serialVersionUID = 7824474731525795360L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+
+    public Tuple10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+    }
+
+    public Tuple10(Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(T11 value) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple1<T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple2<T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple3<T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple4<T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple5<T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple6<T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 10.
+     */
+    public final Tuple2<Tuple0, Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 9.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple9<T2, T3, T4, T5, T6, T7, T8, T9, T10>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 8.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple8<T3, T4, T5, T6, T7, T8, T9, T10>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 7.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple7<T4, T5, T6, T7, T8, T9, T10>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 6.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple6<T5, T6, T7, T8, T9, T10>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 5.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple5<T6, T7, T8, T9, T10>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 4.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple4<T7, T8, T9, T10>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 3.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple3<T8, T9, T10>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 2.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple2<T9, T10>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 1.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple1<T10>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 0.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple0> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple9<T2, T3, T4, T5, T6, T7, T8, T9, T10> skip1() {
+        return new Tuple9<>(v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple8<T3, T4, T5, T6, T7, T8, T9, T10> skip2() {
+        return new Tuple8<>(v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple7<T4, T5, T6, T7, T8, T9, T10> skip3() {
+        return new Tuple7<>(v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple6<T5, T6, T7, T8, T9, T10> skip4() {
+        return new Tuple6<>(v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple5<T6, T7, T8, T9, T10> skip5() {
+        return new Tuple5<>(v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple4<T7, T8, T9, T10> skip6() {
+        return new Tuple4<>(v7, v8, v9, v10);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple3<T8, T9, T10> skip7() {
+        return new Tuple3<>(v8, v9, v10);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple2<T9, T10> skip8() {
+        return new Tuple2<>(v9, v10);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple1<T10> skip9() {
+        return new Tuple1<>(v10);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple0 skip10() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function10<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple10<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple10<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple10<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple10<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple10<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple10<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple10<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple10<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple10<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple10<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple10<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple10<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple10<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10));
+    }
+
+    @Override
+    public Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> clone() {
+        return new Tuple10<>(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple11.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple11.java b/src/main/groovy/groovy/lang/Tuple11.java
new file mode 100644
index 0000000..9b2bab1
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple11.java
@@ -0,0 +1,537 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function11;
+
+/**
+ * Represents a list of 10 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> extends Tuple {
+    private static final long serialVersionUID = -8882524414681687282L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+    private final T11 v11;
+
+    public Tuple11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+        this.v11 = v11;
+    }
+
+    public Tuple11(Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+    public T11 v11() {
+        return v11;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(T12 value) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple1<T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple2<T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple3<T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple4<T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple5<T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 11.
+     */
+    public final Tuple2<Tuple0, Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 10.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 9.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple9<T3, T4, T5, T6, T7, T8, T9, T10, T11>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 8.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple8<T4, T5, T6, T7, T8, T9, T10, T11>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 7.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple7<T5, T6, T7, T8, T9, T10, T11>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 6.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple6<T6, T7, T8, T9, T10, T11>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 5.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple5<T7, T8, T9, T10, T11>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 4.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple4<T8, T9, T10, T11>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 3.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple3<T9, T10, T11>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 2.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple2<T10, T11>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 1.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple1<T11>> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 11 and 0.
+     */
+    public final Tuple2<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Tuple0> split11() {
+        return new Tuple2<>(limit11(), skip11());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Limit this tuple to degree 11.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> limit11() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> skip1() {
+        return new Tuple10<>(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple9<T3, T4, T5, T6, T7, T8, T9, T10, T11> skip2() {
+        return new Tuple9<>(v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple8<T4, T5, T6, T7, T8, T9, T10, T11> skip3() {
+        return new Tuple8<>(v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple7<T5, T6, T7, T8, T9, T10, T11> skip4() {
+        return new Tuple7<>(v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple6<T6, T7, T8, T9, T10, T11> skip5() {
+        return new Tuple6<>(v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple5<T7, T8, T9, T10, T11> skip6() {
+        return new Tuple5<>(v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple4<T8, T9, T10, T11> skip7() {
+        return new Tuple4<>(v8, v9, v10, v11);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple3<T9, T10, T11> skip8() {
+        return new Tuple3<>(v9, v10, v11);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple2<T10, T11> skip9() {
+        return new Tuple2<>(v10, v11);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple1<T11> skip10() {
+        return new Tuple1<>(v11);
+    }
+
+    /**
+     * Skip 11 degrees from this tuple.
+     */
+    public final Tuple0 skip11() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function11<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? super T11, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple11<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple11<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple11<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10, T11> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple11<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple11<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10, T11> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple11<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple11<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10, T11> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple11<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple11<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10, T11> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple11<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple11<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10, T11> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple11<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10, T11> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple11<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10, T11> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10, v11);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10, T11> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10, v11);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10, T11> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10), v11);
+    }
+
+    /**
+     * Apply attribute 11 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, U11> map11(Function1<? super T11, ? extends U11> function) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, function.apply(v11));
+    }
+
+    @Override
+    public Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> clone() {
+        return new Tuple11<>(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple12.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple12.java b/src/main/groovy/groovy/lang/Tuple12.java
new file mode 100644
index 0000000..64fd51f
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple12.java
@@ -0,0 +1,565 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function12;
+
+/**
+ * Represents a list of 12 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> extends Tuple {
+    private static final long serialVersionUID = 8297587976812329899L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+    private final T11 v11;
+    private final T12 v12;
+
+
+    public Tuple12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+        this.v11 = v11;
+        this.v12 = v12;
+    }
+
+    public Tuple12(Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11, tuple.v12);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+    public T11 v11() {
+        return v11;
+    }
+
+    public T12 v12() {
+        return v12;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(T13 value) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple1<T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple2<T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple3<T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple4<T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 12.
+     */
+    public final Tuple2<Tuple0, Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 11.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 10.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 9.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple9<T4, T5, T6, T7, T8, T9, T10, T11, T12>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 8.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple8<T5, T6, T7, T8, T9, T10, T11, T12>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 7.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple7<T6, T7, T8, T9, T10, T11, T12>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 6.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple6<T7, T8, T9, T10, T11, T12>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 5.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple5<T8, T9, T10, T11, T12>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 4.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple4<T9, T10, T11, T12>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 3.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple3<T10, T11, T12>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 2.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple2<T11, T12>> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 11 and 1.
+     */
+    public final Tuple2<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Tuple1<T12>> split11() {
+        return new Tuple2<>(limit11(), skip11());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 12 and 0.
+     */
+    public final Tuple2<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>, Tuple0> split12() {
+        return new Tuple2<>(limit12(), skip12());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Limit this tuple to degree 11.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> limit11() {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Limit this tuple to degree 12.
+     */
+    public final Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> limit12() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> skip1() {
+        return new Tuple11<>(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> skip2() {
+        return new Tuple10<>(v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple9<T4, T5, T6, T7, T8, T9, T10, T11, T12> skip3() {
+        return new Tuple9<>(v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple8<T5, T6, T7, T8, T9, T10, T11, T12> skip4() {
+        return new Tuple8<>(v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple7<T6, T7, T8, T9, T10, T11, T12> skip5() {
+        return new Tuple7<>(v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple6<T7, T8, T9, T10, T11, T12> skip6() {
+        return new Tuple6<>(v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple5<T8, T9, T10, T11, T12> skip7() {
+        return new Tuple5<>(v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple4<T9, T10, T11, T12> skip8() {
+        return new Tuple4<>(v9, v10, v11, v12);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple3<T10, T11, T12> skip9() {
+        return new Tuple3<>(v10, v11, v12);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple2<T11, T12> skip10() {
+        return new Tuple2<>(v11, v12);
+    }
+
+    /**
+     * Skip 11 degrees from this tuple.
+     */
+    public final Tuple1<T12> skip11() {
+        return new Tuple1<>(v12);
+    }
+
+    /**
+     * Skip 12 degrees from this tuple.
+     */
+    public final Tuple0 skip12() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function12<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? super T11, ? super T12, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple12<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple12<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple12<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple12<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple12<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10, T11, T12> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple12<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple12<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10, T11, T12> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple12<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple12<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10, T11, T12> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple12<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple12<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10, T11, T12> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple12<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10, T11, T12> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple12<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10, T11, T12> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10, T11, T12> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10, v11, v12);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10, T11, T12> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10), v11, v12);
+    }
+
+    /**
+     * Apply attribute 11 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U11> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, U11, T12> map11(Function1<? super T11, ? extends U11> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, function.apply(v11), v12);
+    }
+
+    /**
+     * Apply attribute 12 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, U12> map12(Function1<? super T12, ? extends U12> function) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, function.apply(v12));
+    }
+
+    @Override
+    public Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> clone() {
+        return new Tuple12<>(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple13.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple13.java b/src/main/groovy/groovy/lang/Tuple13.java
new file mode 100644
index 0000000..e996a59
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple13.java
@@ -0,0 +1,592 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function13;
+
+/**
+ * Represents a list of 13 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> extends Tuple {
+    private static final long serialVersionUID = -3709443502209750114L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+    private final T11 v11;
+    private final T12 v12;
+    private final T13 v13;
+
+
+    public Tuple13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+        this.v11 = v11;
+        this.v12 = v12;
+        this.v13 = v13;
+    }
+
+    public Tuple13(Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11, tuple.v12, tuple.v13);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+    public T11 v11() {
+        return v11;
+    }
+
+    public T12 v12() {
+        return v12;
+    }
+
+    public T13 v13() {
+        return v13;
+    }
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(T14 value) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple1<T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple2<T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple3<T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 13.
+     */
+    public final Tuple2<Tuple0, Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 12.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 11.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 10.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 9.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple9<T5, T6, T7, T8, T9, T10, T11, T12, T13>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 8.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple8<T6, T7, T8, T9, T10, T11, T12, T13>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 7.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple7<T7, T8, T9, T10, T11, T12, T13>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 6.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple6<T8, T9, T10, T11, T12, T13>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 5.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple5<T9, T10, T11, T12, T13>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 4.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple4<T10, T11, T12, T13>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 3.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple3<T11, T12, T13>> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 11 and 2.
+     */
+    public final Tuple2<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Tuple2<T12, T13>> split11() {
+        return new Tuple2<>(limit11(), skip11());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 12 and 1.
+     */
+    public final Tuple2<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>, Tuple1<T13>> split12() {
+        return new Tuple2<>(limit12(), skip12());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 13 and 0.
+     */
+    public final Tuple2<Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>, Tuple0> split13() {
+        return new Tuple2<>(limit13(), skip13());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Limit this tuple to degree 11.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> limit11() {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Limit this tuple to degree 12.
+     */
+    public final Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> limit12() {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Limit this tuple to degree 13.
+     */
+    public final Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> limit13() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> skip1() {
+        return new Tuple12<>(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> skip2() {
+        return new Tuple11<>(v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> skip3() {
+        return new Tuple10<>(v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple9<T5, T6, T7, T8, T9, T10, T11, T12, T13> skip4() {
+        return new Tuple9<>(v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple8<T6, T7, T8, T9, T10, T11, T12, T13> skip5() {
+        return new Tuple8<>(v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple7<T7, T8, T9, T10, T11, T12, T13> skip6() {
+        return new Tuple7<>(v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple6<T8, T9, T10, T11, T12, T13> skip7() {
+        return new Tuple6<>(v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple5<T9, T10, T11, T12, T13> skip8() {
+        return new Tuple5<>(v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple4<T10, T11, T12, T13> skip9() {
+        return new Tuple4<>(v10, v11, v12, v13);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple3<T11, T12, T13> skip10() {
+        return new Tuple3<>(v11, v12, v13);
+    }
+
+    /**
+     * Skip 11 degrees from this tuple.
+     */
+    public final Tuple2<T12, T13> skip11() {
+        return new Tuple2<>(v12, v13);
+    }
+
+    /**
+     * Skip 12 degrees from this tuple.
+     */
+    public final Tuple1<T13> skip12() {
+        return new Tuple1<>(v13);
+    }
+
+    /**
+     * Skip 13 degrees from this tuple.
+     */
+    public final Tuple0 skip13() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function13<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? super T11, ? super T12, ? super T13, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple13<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple13<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple13<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple13<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple13<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple13<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple13<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10, T11, T12, T13> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple13<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple13<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10, T11, T12, T13> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple13<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple13<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10, T11, T12, T13> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple13<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10, T11, T12, T13> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple13<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10, T11, T12, T13> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10, T11, T12, T13> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10, v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10, T11, T12, T13> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10), v11, v12, v13);
+    }
+
+    /**
+     * Apply attribute 11 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U11> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, U11, T12, T13> map11(Function1<? super T11, ? extends U11> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, function.apply(v11), v12, v13);
+    }
+
+    /**
+     * Apply attribute 12 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U12> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, U12, T13> map12(Function1<? super T12, ? extends U12> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, function.apply(v12), v13);
+    }
+
+    /**
+     * Apply attribute 13 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, U13> map13(Function1<? super T13, ? extends U13> function) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, function.apply(v13));
+    }
+
+
+    @Override
+    public Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> clone() {
+        return new Tuple13<>(this);
+    }
+}


[5/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple4.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple4.java b/src/main/groovy/groovy/lang/Tuple4.java
index 04f414e..30793a2 100644
--- a/src/main/groovy/groovy/lang/Tuple4.java
+++ b/src/main/groovy/groovy/lang/Tuple4.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function4;
+
 /**
  * Represents a list of 4 typed Objects.
  *
@@ -26,54 +29,294 @@ package groovy.lang;
  */
 public class Tuple4<T1, T2, T3, T4> extends Tuple {
     private static final long serialVersionUID = -7788878731471377207L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
-    private final T4 fourth;
-
-    public Tuple4(T1 first, T2 second, T3 third, T4 fourth) {
-        super(first, second, third, fourth);
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
 
-        this.first = first;
-        this.second = second;
-        this.third = third;
-        this.fourth = fourth;
-    }
+    public Tuple4(T1 v1, T2 v2, T3 v3, T4 v4) {
+        super(v1, v2, v3, v4);
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            case 3:
-                return fourth;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
     }
 
-    @Override
-    public int size() {
-        return 4;
+    public Tuple4(Tuple4<T1, T2, T3, T4> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
     }
 
+    @Deprecated
     public T4 getFourth() {
-        return fourth;
+        return v4;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T5> Tuple5<T1, T2, T3, T4, T5> concat(T5 value) {
+        return new Tuple5<>(v1, v2, v3, v4, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5> Tuple5<T1, T2, T3, T4, T5> concat(Tuple1<T5> tuple) {
+        return new Tuple5<>(v1, v2, v3, v4, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(Tuple2<T5, T6> tuple) {
+        return new Tuple6<>(v1, v2, v3, v4, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple3<T5, T6, T7> tuple) {
+        return new Tuple7<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple4<T5, T6, T7, T8> tuple) {
+        return new Tuple8<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple5<T5, T6, T7, T8, T9> tuple) {
+        return new Tuple9<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple6<T5, T6, T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple7<T5, T6, T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple8<T5, T6, T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple9<T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 4.
+     */
+    public final Tuple2<Tuple0, Tuple4<T1, T2, T3, T4>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 3.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple3<T2, T3, T4>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 2.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple2<T3, T4>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 1.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple1<T4>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 0.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple0> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple4<T1, T2, T3, T4> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple3<T2, T3, T4> skip1() {
+        return new Tuple3<>(v2, v3, v4);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple2<T3, T4> skip2() {
+        return new Tuple2<>(v3, v4);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple1<T4> skip3() {
+        return new Tuple1<>(v4);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple0 skip4() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function4<? super T1, ? super T2, ? super T3, ? super T4, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple4<U1, T2, T3, T4> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple4<>(function.apply(v1), v2, v3, v4);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple4<T1, U2, T3, T4> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple4<>(v1, function.apply(v2), v3, v4);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple4<T1, T2, U3, T4> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple4<>(v1, v2, function.apply(v3), v4);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple4<T1, T2, T3, U4> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple4<>(v1, v2, v3, function.apply(v4));
+    }
+
+    @Override
+    public Tuple4<T1, T2, T3, T4> clone() {
+        return new Tuple4<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple5.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple5.java b/src/main/groovy/groovy/lang/Tuple5.java
index ee9c802..a1dc209 100644
--- a/src/main/groovy/groovy/lang/Tuple5.java
+++ b/src/main/groovy/groovy/lang/Tuple5.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function5;
+
 /**
  * Represents a list of 5 typed Objects.
  *
@@ -26,62 +29,326 @@ package groovy.lang;
  */
 public class Tuple5<T1, T2, T3, T4, T5> extends Tuple {
     private static final long serialVersionUID = 6722094358774027115L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
-    private final T4 fourth;
-    private final T5 fifth;
-
-    public Tuple5(T1 first, T2 second, T3 third, T4 fourth, T5 fifth) {
-        super(first, second, third, fourth, fifth);
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
 
-        this.first = first;
-        this.second = second;
-        this.third = third;
-        this.fourth = fourth;
-        this.fifth = fifth;
-    }
+    public Tuple5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        super(v1, v2, v3, v4, v5);
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            case 3:
-                return fourth;
-            case 4:
-                return fifth;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
     }
 
-    @Override
-    public int size() {
-        return 5;
+    public Tuple5(Tuple5<T1, T2, T3, T4, T5> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
     }
 
+    @Deprecated
     public T4 getFourth() {
-        return fourth;
+        return v4;
     }
 
+    @Deprecated
     public T5 getFifth() {
-        return fifth;
+        return v5;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(T6 value) {
+        return new Tuple6<>(v1, v2, v3, v4, v5, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(Tuple1<T6> tuple) {
+        return new Tuple6<>(v1, v2, v3, v4, v5, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple2<T6, T7> tuple) {
+        return new Tuple7<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple3<T6, T7, T8> tuple) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple4<T6, T7, T8, T9> tuple) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple5<T6, T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple6<T6, T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple7<T6, T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple8<T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple9<T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 5.
+     */
+    public final Tuple2<Tuple0, Tuple5<T1, T2, T3, T4, T5>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 4.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple4<T2, T3, T4, T5>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 3.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple3<T3, T4, T5>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 2.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple2<T4, T5>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 1.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple1<T5>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 0.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple0> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple4<T2, T3, T4, T5> skip1() {
+        return new Tuple4<>(v2, v3, v4, v5);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple3<T3, T4, T5> skip2() {
+        return new Tuple3<>(v3, v4, v5);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple2<T4, T5> skip3() {
+        return new Tuple2<>(v4, v5);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple1<T5> skip4() {
+        return new Tuple1<>(v5);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple0 skip5() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function5<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple5<U1, T2, T3, T4, T5> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple5<>(function.apply(v1), v2, v3, v4, v5);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple5<T1, U2, T3, T4, T5> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple5<>(v1, function.apply(v2), v3, v4, v5);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple5<T1, T2, U3, T4, T5> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple5<>(v1, v2, function.apply(v3), v4, v5);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple5<T1, T2, T3, U4, T5> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple5<>(v1, v2, v3, function.apply(v4), v5);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple5<T1, T2, T3, T4, U5> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple5<>(v1, v2, v3, v4, function.apply(v5));
+    }
+
+    @Override
+    public Tuple5<T1, T2, T3, T4, T5> clone() {
+        return new Tuple5<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple6.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple6.java b/src/main/groovy/groovy/lang/Tuple6.java
index 76d12ca..1f65777 100644
--- a/src/main/groovy/groovy/lang/Tuple6.java
+++ b/src/main/groovy/groovy/lang/Tuple6.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function6;
+
 /**
  * Represents a list of 6 typed Objects.
  *
@@ -26,70 +29,358 @@ package groovy.lang;
  */
 public class Tuple6<T1, T2, T3, T4, T5, T6> extends Tuple {
     private static final long serialVersionUID = -7848588473093102288L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
-    private final T4 fourth;
-    private final T5 fifth;
-    private final T6 sixth;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
 
-    public Tuple6(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth) {
-        super(first, second, third, fourth, fifth, sixth);
+    public Tuple6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        super(v1, v2, v3, v4, v5, v6);
 
-        this.first = first;
-        this.second = second;
-        this.third = third;
-        this.fourth = fourth;
-        this.fifth = fifth;
-        this.sixth = sixth;
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
     }
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            case 3:
-                return fourth;
-            case 4:
-                return fifth;
-            case 5:
-                return sixth;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
-    }
-
-    @Override
-    public int size() {
-        return 6;
+    public Tuple6(Tuple6<T1, T2, T3, T4, T5, T6> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
     }
 
+    @Deprecated
     public T4 getFourth() {
-        return fourth;
+        return v4;
     }
 
+    @Deprecated
     public T5 getFifth() {
-        return fifth;
+        return v5;
     }
 
+    @Deprecated
     public T6 getSixth() {
-        return sixth;
+        return v6;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(T7 value) {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple1<T7> tuple) {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple2<T7, T8> tuple) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple3<T7, T8, T9> tuple) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple4<T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple5<T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple6<T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple7<T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple8<T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple9<T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 6.
+     */
+    public final Tuple2<Tuple0, Tuple6<T1, T2, T3, T4, T5, T6>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 5.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple5<T2, T3, T4, T5, T6>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 4.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple4<T3, T4, T5, T6>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 3.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple3<T4, T5, T6>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 2.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple2<T5, T6>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 1.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple1<T6>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 0.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple0> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple5<T2, T3, T4, T5, T6> skip1() {
+        return new Tuple5<>(v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple4<T3, T4, T5, T6> skip2() {
+        return new Tuple4<>(v3, v4, v5, v6);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple3<T4, T5, T6> skip3() {
+        return new Tuple3<>(v4, v5, v6);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple2<T5, T6> skip4() {
+        return new Tuple2<>(v5, v6);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple1<T6> skip5() {
+        return new Tuple1<>(v6);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple0 skip6() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function6<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple6<U1, T2, T3, T4, T5, T6> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple6<>(function.apply(v1), v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple6<T1, U2, T3, T4, T5, T6> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple6<>(v1, function.apply(v2), v3, v4, v5, v6);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple6<T1, T2, U3, T4, T5, T6> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple6<>(v1, v2, function.apply(v3), v4, v5, v6);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple6<T1, T2, T3, U4, T5, T6> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple6<>(v1, v2, v3, function.apply(v4), v5, v6);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple6<T1, T2, T3, T4, U5, T6> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple6<>(v1, v2, v3, v4, function.apply(v5), v6);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple6<T1, T2, T3, T4, T5, U6> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple6<>(v1, v2, v3, v4, v5, function.apply(v6));
+    }
+
+    @Override
+    public Tuple6<T1, T2, T3, T4, T5, T6> clone() {
+        return new Tuple6<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple7.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple7.java b/src/main/groovy/groovy/lang/Tuple7.java
index 05046e7..c92f45f 100644
--- a/src/main/groovy/groovy/lang/Tuple7.java
+++ b/src/main/groovy/groovy/lang/Tuple7.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function7;
+
 /**
  * Represents a list of 7 typed Objects.
  *
@@ -26,78 +29,390 @@ package groovy.lang;
  */
 public class Tuple7<T1, T2, T3, T4, T5, T6, T7> extends Tuple {
     private static final long serialVersionUID = 4226144828786865766L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
-    private final T4 fourth;
-    private final T5 fifth;
-    private final T6 sixth;
-    private final T7 seventh;
-
-    public Tuple7(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh) {
-        super(first, second, third, fourth, fifth, sixth, seventh);
-
-        this.first = first;
-        this.second = second;
-        this.third = third;
-        this.fourth = fourth;
-        this.fifth = fifth;
-        this.sixth = sixth;
-        this.seventh = seventh;
-    }
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            case 3:
-                return fourth;
-            case 4:
-                return fifth;
-            case 5:
-                return sixth;
-            case 6:
-                return seventh;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+    public Tuple7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        super(v1, v2, v3, v4, v5, v6, v7);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
     }
 
-    @Override
-    public int size() {
-        return 7;
+    public Tuple7(Tuple7<T1, T2, T3, T4, T5, T6, T7> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
     }
 
+    @Deprecated
     public T4 getFourth() {
-        return fourth;
+        return v4;
     }
 
+    @Deprecated
     public T5 getFifth() {
-        return fifth;
+        return v5;
     }
 
+    @Deprecated
     public T6 getSixth() {
-        return sixth;
+        return v6;
     }
 
+    @Deprecated
     public T7 getSeventh() {
-        return seventh;
+        return v7;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(T8 value) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple1<T8> tuple) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple2<T8, T9> tuple) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple3<T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple4<T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple5<T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple6<T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple7<T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple8<T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple9<T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 7.
+     */
+    public final Tuple2<Tuple0, Tuple7<T1, T2, T3, T4, T5, T6, T7>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 6.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple6<T2, T3, T4, T5, T6, T7>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 5.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple5<T3, T4, T5, T6, T7>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 4.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple4<T4, T5, T6, T7>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 3.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple3<T5, T6, T7>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 2.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple2<T6, T7>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 1.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple1<T7>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 0.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple0> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple6<T2, T3, T4, T5, T6, T7> skip1() {
+        return new Tuple6<>(v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple5<T3, T4, T5, T6, T7> skip2() {
+        return new Tuple5<>(v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple4<T4, T5, T6, T7> skip3() {
+        return new Tuple4<>(v4, v5, v6, v7);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple3<T5, T6, T7> skip4() {
+        return new Tuple3<>(v5, v6, v7);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple2<T6, T7> skip5() {
+        return new Tuple2<>(v6, v7);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple1<T7> skip6() {
+        return new Tuple1<>(v7);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple0 skip7() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function7<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple7<U1, T2, T3, T4, T5, T6, T7> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple7<>(function.apply(v1), v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple7<T1, U2, T3, T4, T5, T6, T7> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple7<>(v1, function.apply(v2), v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple7<T1, T2, U3, T4, T5, T6, T7> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple7<>(v1, v2, function.apply(v3), v4, v5, v6, v7);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple7<T1, T2, T3, U4, T5, T6, T7> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple7<>(v1, v2, v3, function.apply(v4), v5, v6, v7);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple7<T1, T2, T3, T4, U5, T6, T7> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple7<>(v1, v2, v3, v4, function.apply(v5), v6, v7);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple7<T1, T2, T3, T4, T5, U6, T7> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple7<>(v1, v2, v3, v4, v5, function.apply(v6), v7);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple7<T1, T2, T3, T4, T5, T6, U7> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, function.apply(v7));
+    }
+
+    @Override
+    public Tuple7<T1, T2, T3, T4, T5, T6, T7> clone() {
+        return new Tuple7<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple8.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple8.java b/src/main/groovy/groovy/lang/Tuple8.java
index 1f38ca9..09d7cc8 100644
--- a/src/main/groovy/groovy/lang/Tuple8.java
+++ b/src/main/groovy/groovy/lang/Tuple8.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function8;
+
 /**
  * Represents a list of 8 typed Objects.
  *
@@ -26,86 +29,422 @@ package groovy.lang;
  */
 public class Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> extends Tuple {
     private static final long serialVersionUID = -8895822084644138566L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
-    private final T4 fourth;
-    private final T5 fifth;
-    private final T6 sixth;
-    private final T7 seventh;
-    private final T8 eighth;
-
-    public Tuple8(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh, T8 eighth) {
-        super(first, second, third, fourth, fifth, sixth, seventh, eighth);
-
-        this.first = first;
-        this.second = second;
-        this.third = third;
-        this.fourth = fourth;
-        this.fifth = fifth;
-        this.sixth = sixth;
-        this.seventh = seventh;
-        this.eighth = eighth;
-    }
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            case 3:
-                return fourth;
-            case 4:
-                return fifth;
-            case 5:
-                return sixth;
-            case 6:
-                return seventh;
-            case 7:
-                return eighth;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+    public Tuple8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
     }
 
-    @Override
-    public int size() {
-        return 8;
+    public Tuple8(Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
     }
 
+    @Deprecated
     public T4 getFourth() {
-        return fourth;
+        return v4;
     }
 
+    @Deprecated
     public T5 getFifth() {
-        return fifth;
+        return v5;
     }
 
+    @Deprecated
     public T6 getSixth() {
-        return sixth;
+        return v6;
     }
 
+    @Deprecated
     public T7 getSeventh() {
-        return seventh;
+        return v7;
     }
 
+    @Deprecated
     public T8 getEighth() {
-        return eighth;
+        return v8;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(T9 value) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple1<T9> tuple) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple2<T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple3<T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple4<T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple5<T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple6<T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple7<T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple8<T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 8.
+     */
+    public final Tuple2<Tuple0, Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 7.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple7<T2, T3, T4, T5, T6, T7, T8>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 6.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple6<T3, T4, T5, T6, T7, T8>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 5.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple5<T4, T5, T6, T7, T8>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 4.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple4<T5, T6, T7, T8>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 3.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple3<T6, T7, T8>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 2.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple2<T7, T8>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 1.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple1<T8>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 0.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple0> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple7<T2, T3, T4, T5, T6, T7, T8> skip1() {
+        return new Tuple7<>(v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple6<T3, T4, T5, T6, T7, T8> skip2() {
+        return new Tuple6<>(v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple5<T4, T5, T6, T7, T8> skip3() {
+        return new Tuple5<>(v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple4<T5, T6, T7, T8> skip4() {
+        return new Tuple4<>(v5, v6, v7, v8);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple3<T6, T7, T8> skip5() {
+        return new Tuple3<>(v6, v7, v8);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple2<T7, T8> skip6() {
+        return new Tuple2<>(v7, v8);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple1<T8> skip7() {
+        return new Tuple1<>(v8);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple0 skip8() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function8<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple8<U1, T2, T3, T4, T5, T6, T7, T8> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple8<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple8<T1, U2, T3, T4, T5, T6, T7, T8> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple8<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple8<T1, T2, U3, T4, T5, T6, T7, T8> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple8<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple8<T1, T2, T3, U4, T5, T6, T7, T8> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple8<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple8<T1, T2, T3, T4, U5, T6, T7, T8> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple8<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple8<T1, T2, T3, T4, T5, U6, T7, T8> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple8<T1, T2, T3, T4, T5, T6, U7, T8> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple8<T1, T2, T3, T4, T5, T6, T7, U8> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8));
+    }
+
+    @Override
+    public Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> clone() {
+        return new Tuple8<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple9.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple9.java b/src/main/groovy/groovy/lang/Tuple9.java
index 3189c10..9879b8f 100644
--- a/src/main/groovy/groovy/lang/Tuple9.java
+++ b/src/main/groovy/groovy/lang/Tuple9.java
@@ -20,6 +20,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function9;
+
 /**
  * Represents a list of 9 typed Objects.
  *
@@ -27,94 +30,454 @@ package groovy.lang;
  */
 public class Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends Tuple {
     private static final long serialVersionUID = -5181196675351911769L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
-    private final T4 fourth;
-    private final T5 fifth;
-    private final T6 sixth;
-    private final T7 seventh;
-    private final T8 eighth;
-    private final T9 ninth;
-
-    public Tuple9(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh, T8 eighth, T9 ninth) {
-        super(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth);
-
-        this.first = first;
-        this.second = second;
-        this.third = third;
-        this.fourth = fourth;
-        this.fifth = fifth;
-        this.sixth = sixth;
-        this.seventh = seventh;
-        this.eighth = eighth;
-        this.ninth = ninth;
-    }
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            case 3:
-                return fourth;
-            case 4:
-                return fifth;
-            case 5:
-                return sixth;
-            case 6:
-                return seventh;
-            case 7:
-                return eighth;
-            case 8:
-                return ninth;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+    public Tuple9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
     }
 
-    @Override
-    public int size() {
-        return 9;
+    public Tuple9(Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
     }
 
+    @Deprecated
     public T4 getFourth() {
-        return fourth;
+        return v4;
     }
 
+    @Deprecated
     public T5 getFifth() {
-        return fifth;
+        return v5;
     }
 
+    @Deprecated
     public T6 getSixth() {
-        return sixth;
+        return v6;
     }
 
+    @Deprecated
     public T7 getSeventh() {
-        return seventh;
+        return v7;
     }
 
+    @Deprecated
     public T8 getEighth() {
-        return eighth;
+        return v8;
     }
 
+    @Deprecated
     public T9 getNinth() {
-        return ninth;
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(T10 value) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple1<T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple2<T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple3<T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple4<T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple5<T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple6<T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple7<T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 9.
+     */
+    public final Tuple2<Tuple0, Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 8.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple8<T2, T3, T4, T5, T6, T7, T8, T9>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 7.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple7<T3, T4, T5, T6, T7, T8, T9>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 6.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple6<T4, T5, T6, T7, T8, T9>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 5.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple5<T5, T6, T7, T8, T9>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 4.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple4<T6, T7, T8, T9>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 3.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple3<T7, T8, T9>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 2.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple2<T8, T9>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 1.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple1<T9>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 0.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple0> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple8<T2, T3, T4, T5, T6, T7, T8, T9> skip1() {
+        return new Tuple8<>(v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple7<T3, T4, T5, T6, T7, T8, T9> skip2() {
+        return new Tuple7<>(v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple6<T4, T5, T6, T7, T8, T9> skip3() {
+        return new Tuple6<>(v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple5<T5, T6, T7, T8, T9> skip4() {
+        return new Tuple5<>(v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple4<T6, T7, T8, T9> skip5() {
+        return new Tuple4<>(v6, v7, v8, v9);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple3<T7, T8, T9> skip6() {
+        return new Tuple3<>(v7, v8, v9);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple2<T8, T9> skip7() {
+        return new Tuple2<>(v8, v9);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple1<T9> skip8() {
+        return new Tuple1<>(v9);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple0 skip9() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function9<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple9<U1, T2, T3, T4, T5, T6, T7, T8, T9> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple9<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple9<T1, U2, T3, T4, T5, T6, T7, T8, T9> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple9<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple9<T1, T2, U3, T4, T5, T6, T7, T8, T9> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple9<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple9<T1, T2, T3, U4, T5, T6, T7, T8, T9> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple9<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple9<T1, T2, T3, T4, U5, T6, T7, T8, T9> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple9<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple9<T1, T2, T3, T4, T5, U6, T7, T8, T9> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple9<T1, T2, T3, T4, T5, T6, U7, T8, T9> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple9<T1, T2, T3, T4, T5, T6, T7, U8, T9> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, U9> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9));
+    }
+
+    @Override
+    public Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> clone() {
+        return new Tuple9<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer0.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer0.java b/src/main/groovy/groovy/util/function/Consumer0.java
new file mode 100644
index 0000000..b146e9f
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer0.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple0;
+
+
+/**
+ * A consumer with 0 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer0 extends Runnable {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple0 args) {
+        accept();
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept();
+
+    @Override
+    default void run() {
+        accept();
+    }
+
+    /**
+     * Convert this consumer to a {@link Runnable}.
+     */
+    default Runnable toRunnable() {
+        return this::accept;
+    }
+
+    /**
+     * Convert to this consumer from a {@link Runnable}.
+     */
+    static Consumer0 from(Runnable runnable) {
+        return runnable::run;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer1.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer1.java b/src/main/groovy/groovy/util/function/Consumer1.java
new file mode 100644
index 0000000..c19441f
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer1.java
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+
+import java.util.function.Consumer;
+
+/**
+ * A consumer with 1 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer1<T1> extends Consumer<T1> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple1<? extends T1> args) {
+        accept(args.v1());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    @Override
+    void accept(T1 v1);
+
+    /**
+     * Convert this consumer to a {@link Consumer}.
+     */
+    default Consumer<T1> toConsumer() {
+        return this::accept;
+    }
+
+    /**
+     * Convert to this consumer from a {@link Consumer}.
+     */
+    static <T1> Consumer1<T1> from(Consumer<? super T1> consumer) {
+        return consumer::accept;
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1) {
+        return () -> accept(v1);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple1<? extends T1> args) {
+        return () -> accept(args.v1());
+    }
+}


[4/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer10.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer10.java b/src/main/groovy/groovy/util/function/Consumer10.java
new file mode 100644
index 0000000..8e49f45
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer10.java
@@ -0,0 +1,194 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 10 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T2, T3, T4, T5, T6, T7, T8, T9, T10> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T3, T4, T5, T6, T7, T8, T9, T10> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T4, T5, T6, T7, T8, T9, T10> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T5, T6, T7, T8, T9, T10> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T6, T7, T8, T9, T10> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T7, T8, T9, T10> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T8, T9, T10> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T9, T10> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T10> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T2, T3, T4, T5, T6, T7, T8, T9, T10> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T3, T4, T5, T6, T7, T8, T9, T10> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T4, T5, T6, T7, T8, T9, T10> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T5, T6, T7, T8, T9, T10> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T6, T7, T8, T9, T10> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T7, T8, T9, T10> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T8, T9, T10> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T9, T10> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T10> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer11.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer11.java b/src/main/groovy/groovy/util/function/Consumer11.java
new file mode 100644
index 0000000..374e91a
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer11.java
@@ -0,0 +1,209 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 11 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T3, T4, T5, T6, T7, T8, T9, T10, T11> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T4, T5, T6, T7, T8, T9, T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T5, T6, T7, T8, T9, T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T6, T7, T8, T9, T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T7, T8, T9, T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T8, T9, T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T9, T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T10, T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T11> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T3, T4, T5, T6, T7, T8, T9, T10, T11> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T4, T5, T6, T7, T8, T9, T10, T11> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T5, T6, T7, T8, T9, T10, T11> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T6, T7, T8, T9, T10, T11> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T7, T8, T9, T10, T11> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T8, T9, T10, T11> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T9, T10, T11> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T10, T11> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T11> acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer12.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer12.java b/src/main/groovy/groovy/util/function/Consumer12.java
new file mode 100644
index 0000000..dfc5185
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer12.java
@@ -0,0 +1,224 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 12 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T4, T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T6, T7, T8, T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T7, T8, T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T8, T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T9, T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T10, T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T11, T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T12> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T4, T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T5, T6, T7, T8, T9, T10, T11, T12> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T6, T7, T8, T9, T10, T11, T12> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T7, T8, T9, T10, T11, T12> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T8, T9, T10, T11, T12> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T9, T10, T11, T12> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T10, T11, T12> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T11, T12> acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T12> acceptPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer13.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer13.java b/src/main/groovy/groovy/util/function/Consumer13.java
new file mode 100644
index 0000000..02069d6
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer13.java
@@ -0,0 +1,239 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 13 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T7, T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T8, T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T9, T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T10, T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T11, T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T12, T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T13> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T5, T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T6, T7, T8, T9, T10, T11, T12, T13> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T7, T8, T9, T10, T11, T12, T13> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T8, T9, T10, T11, T12, T13> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T9, T10, T11, T12, T13> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T10, T11, T12, T13> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T11, T12, T13> acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T12, T13> acceptPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T13> acceptPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer14.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer14.java b/src/main/groovy/groovy/util/function/Consumer14.java
new file mode 100644
index 0000000..dd34caf
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer14.java
@@ -0,0 +1,254 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 14 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T8, T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T9, T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T10, T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T11, T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T12, T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T13, T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13, v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T14> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return (v14) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T6, T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T7, T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T8, T9, T10, T11, T12, T13, T14> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T9, T10, T11, T12, T13, T14> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T10, T11, T12, T13, T14> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T11, T12, T13, T14> acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T12, T13, T14> acceptPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T13, T14> acceptPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13, v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13, v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T14> acceptPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return (v14) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), v14);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer15.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer15.java b/src/main/groovy/groovy/util/function/Consumer15.java
new file mode 100644
index 0000000..56c15aa
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer15.java
@@ -0,0 +1,269 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple15;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 15 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple15<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T9, T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T10, T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T11, T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T12, T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T13, T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13, v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T14, T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return (v14, v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T15> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return (v15) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T7, T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T8, T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T9, T10, T11, T12, T13, T14, T15> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T10, T11, T12, T13, T14, T15> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T11, T12, T13, T14, T15> acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T12, T13, T14, T15> acceptPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T13, T14, T15> acceptPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13, v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13, v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T14, T15> acceptPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return (v14, v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), v14, v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T15> acceptPartially(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return (v15) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), v15);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple15<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer16.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer16.java b/src/main/groovy/groovy/util/function/Consumer16.java
new file mode 100644
index 0000000..5aa0575
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer16.java
@@ -0,0 +1,284 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple15;
+import groovy.lang.Tuple16;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 16 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple16<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15, ? extends T16> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15(), args.v16());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T10, T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T11, T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T12, T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T13, T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13, v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T14, T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return (v14, v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T15, T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return (v15, v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T16> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+        return (v16) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer9<T8, T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T9, T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T10, T11, T12, T13, T14, T15, T16> acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T11, T12, T13, T14, T15, T16> acceptPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T12, T13, T14, T15, T16> acceptPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T13, T14, T15, T16> acceptPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13, v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13, v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T14, T15, T16> acceptPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return (v14, v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), v14, v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T15, T16> acceptPartially(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return (v15, v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), v15, v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T16> acceptPartially(Tuple15<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15> args) {
+        return (v16) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15(), v16);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple16<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15, ? extends T16> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15(), args.v16());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer2.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer2.java b/src/main/groovy/groovy/util/function/Consumer2.java
new file mode 100644
index 0000000..e548957
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer2.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+
+import java.util.function.BiConsumer;
+
+/**
+ * A consumer with 2 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer2<T1, T2> extends BiConsumer<T1, T2> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple2<? extends T1, ? extends T2> args) {
+        accept(args.v1(), args.v2());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    @Override
+    void accept(T1 v1, T2 v2);
+
+    /**
+     * Convert this consumer to a {@link BiConsumer}.
+     */
+    default BiConsumer<T1, T2> toBiConsumer() {
+        return this::accept;
+    }
+
+    /**
+     * Convert to this consumer to a {@link BiConsumer}.
+     */
+    static <T1, T2> Consumer2<T1, T2> from(BiConsumer<? super T1, ? super T2> consumer) {
+        return consumer::accept;
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T2> acceptPartially(T1 v1) {
+        return (v2) -> accept(v1, v2);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2) {
+        return () -> accept(v1, v2);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T2> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2) -> accept(args.v1(), v2);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return () -> accept(args.v1(), args.v2());
+    }
+}


[3/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer3.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer3.java b/src/main/groovy/groovy/util/function/Consumer3.java
new file mode 100644
index 0000000..f5ac7e2
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer3.java
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+
+
+/**
+ * A consumer with 3 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer3<T1, T2, T3> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        accept(args.v1(), args.v2(), args.v3());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T2, T3> acceptPartially(T1 v1) {
+        return (v2, v3) -> accept(v1, v2, v3);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T3> acceptPartially(T1 v1, T2 v2) {
+        return (v3) -> accept(v1, v2, v3);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return () -> accept(v1, v2, v3);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T2, T3> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3) -> accept(args.v1(), v2, v3);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T3> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3) -> accept(args.v1(), args.v2(), v3);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer4.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer4.java b/src/main/groovy/groovy/util/function/Consumer4.java
new file mode 100644
index 0000000..97f7252
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer4.java
@@ -0,0 +1,104 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+
+
+/**
+ * A consumer with 4 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer4<T1, T2, T3, T4> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T2, T3, T4> acceptPartially(T1 v1) {
+        return (v2, v3, v4) -> accept(v1, v2, v3, v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T3, T4> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4) -> accept(v1, v2, v3, v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T4> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4) -> accept(v1, v2, v3, v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return () -> accept(v1, v2, v3, v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T2, T3, T4> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4) -> accept(args.v1(), v2, v3, v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T3, T4> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4) -> accept(args.v1(), args.v2(), v3, v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T4> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4) -> accept(args.v1(), args.v2(), args.v3(), v4);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer5.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer5.java b/src/main/groovy/groovy/util/function/Consumer5.java
new file mode 100644
index 0000000..99d76a7
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer5.java
@@ -0,0 +1,119 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+
+
+/**
+ * A consumer with 5 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer5<T1, T2, T3, T4, T5> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T2, T3, T4, T5> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5) -> accept(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T3, T4, T5> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5) -> accept(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T4, T5> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5) -> accept(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T5> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5) -> accept(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return () -> accept(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T2, T3, T4, T5> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5) -> accept(args.v1(), v2, v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T3, T4, T5> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5) -> accept(args.v1(), args.v2(), v3, v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T4, T5> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5) -> accept(args.v1(), args.v2(), args.v3(), v4, v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T5> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer6.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer6.java b/src/main/groovy/groovy/util/function/Consumer6.java
new file mode 100644
index 0000000..6f55b57
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer6.java
@@ -0,0 +1,134 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+
+
+/**
+ * A consumer with 6 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer6<T1, T2, T3, T4, T5, T6> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T2, T3, T4, T5, T6> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6) -> accept(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T3, T4, T5, T6> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6) -> accept(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T4, T5, T6> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6) -> accept(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T5, T6> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6) -> accept(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T6> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6) -> accept(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return () -> accept(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T2, T3, T4, T5, T6> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6) -> accept(args.v1(), v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T3, T4, T5, T6> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6) -> accept(args.v1(), args.v2(), v3, v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T4, T5, T6> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T5, T6> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T6> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer7.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer7.java b/src/main/groovy/groovy/util/function/Consumer7.java
new file mode 100644
index 0000000..f7f022e
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer7.java
@@ -0,0 +1,149 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+
+
+/**
+ * A consumer with 7 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer7<T1, T2, T3, T4, T5, T6, T7> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T2, T3, T4, T5, T6, T7> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7) -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T3, T4, T5, T6, T7> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7) -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T4, T5, T6, T7> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7) -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T5, T6, T7> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7) -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T6, T7> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7) -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T7> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7) -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T2, T3, T4, T5, T6, T7> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7) -> accept(args.v1(), v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T3, T4, T5, T6, T7> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T4, T5, T6, T7> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T5, T6, T7> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T6, T7> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T7> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer8.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer8.java b/src/main/groovy/groovy/util/function/Consumer8.java
new file mode 100644
index 0000000..e39f69c
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer8.java
@@ -0,0 +1,164 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+
+
+/**
+ * A consumer with 8 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer8<T1, T2, T3, T4, T5, T6, T7, T8> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T2, T3, T4, T5, T6, T7, T8> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T3, T4, T5, T6, T7, T8> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T4, T5, T6, T7, T8> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T5, T6, T7, T8> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T6, T7, T8> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T7, T8> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T8> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8) -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T2, T3, T4, T5, T6, T7, T8> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T3, T4, T5, T6, T7, T8> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T4, T5, T6, T7, T8> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T5, T6, T7, T8> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T6, T7, T8> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T7, T8> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T8> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer9.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Consumer9.java b/src/main/groovy/groovy/util/function/Consumer9.java
new file mode 100644
index 0000000..ebea668
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer9.java
@@ -0,0 +1,179 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 9 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer9<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default void accept(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9());
+    }
+
+    /**
+     * Performs this operation on the given argument.
+     */
+    void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9);
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T2, T3, T4, T5, T6, T7, T8, T9> acceptPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T3, T4, T5, T6, T7, T8, T9> acceptPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T4, T5, T6, T7, T8, T9> acceptPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T5, T6, T7, T8, T9> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T6, T7, T8, T9> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T7, T8, T9> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T8, T9> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T9> acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer8<T2, T3, T4, T5, T6, T7, T8, T9> acceptPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9) -> accept(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer7<T3, T4, T5, T6, T7, T8, T9> acceptPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9) -> accept(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer6<T4, T5, T6, T7, T8, T9> acceptPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9) -> accept(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer5<T5, T6, T7, T8, T9> acceptPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer4<T6, T7, T8, T9> acceptPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer3<T7, T8, T9> acceptPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer2<T8, T9> acceptPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer1<T9> acceptPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9) -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9);
+    }
+
+    /**
+     * Let this consumer partially accept the arguments.
+     */
+    default Consumer0 acceptPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return () -> accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function0.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function0.java b/src/main/groovy/groovy/util/function/Function0.java
new file mode 100644
index 0000000..4a2a219
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function0.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple0;
+
+import java.util.function.Supplier;
+
+/**
+ * A function with 0 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function0<R> extends Supplier<R> {
+
+    /**
+     * Apply this function to the arguments.
+     */
+    default R apply() {
+        return get();
+    }
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple0 args) {
+        return get();
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    @Override
+    R get();
+
+    /**
+     * Convert this function to a {@link Supplier}
+     */
+    default Supplier<R> toSupplier() {
+        return this::apply;
+    }
+
+    /**
+     * Convert to this function from a {@link Supplier}
+     */
+    static <R> Function0<R> from(Supplier<R> supplier) {
+        return supplier::get;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function1.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function1.java b/src/main/groovy/groovy/util/function/Function1.java
new file mode 100644
index 0000000..e1cc245
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function1.java
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+
+import java.util.function.Function;
+
+/**
+ * A function with 1 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function1<T1, R> extends Function<T1, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple1<? extends T1> args) {
+        return apply(args.v1());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    @Override
+    R apply(T1 v1);
+
+    /**
+     * Convert this function to a {@link Function}.
+     */
+    default Function<T1, R> toFunction() {
+        return this::apply;
+    }
+
+    /**
+     * Convert to this function from a {@link Function}.
+     */
+    static <T1, R> Function1<T1, R> from(Function<? super T1, ? extends R> function) {
+        return function::apply;
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1) {
+        return () -> apply(v1);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple1<? extends T1> args) {
+        return () -> apply(args.v1());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function10.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function10.java b/src/main/groovy/groovy/util/function/Function10.java
new file mode 100644
index 0000000..d05a0a8
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function10.java
@@ -0,0 +1,195 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 10 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T2, T3, T4, T5, T6, T7, T8, T9, T10, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T3, T4, T5, T6, T7, T8, T9, T10, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T4, T5, T6, T7, T8, T9, T10, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T5, T6, T7, T8, T9, T10, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T6, T7, T8, T9, T10, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T7, T8, T9, T10, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T8, T9, T10, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T9, T10, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T10, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T2, T3, T4, T5, T6, T7, T8, T9, T10, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T3, T4, T5, T6, T7, T8, T9, T10, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T4, T5, T6, T7, T8, T9, T10, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T5, T6, T7, T8, T9, T10, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T6, T7, T8, T9, T10, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T7, T8, T9, T10, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T8, T9, T10, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T9, T10, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T10, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function11.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function11.java b/src/main/groovy/groovy/util/function/Function11.java
new file mode 100644
index 0000000..38d5286
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function11.java
@@ -0,0 +1,210 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 11 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T3, T4, T5, T6, T7, T8, T9, T10, T11, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T4, T5, T6, T7, T8, T9, T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T5, T6, T7, T8, T9, T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T6, T7, T8, T9, T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T7, T8, T9, T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T8, T9, T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T9, T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T10, T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T11, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T3, T4, T5, T6, T7, T8, T9, T10, T11, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T4, T5, T6, T7, T8, T9, T10, T11, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T5, T6, T7, T8, T9, T10, T11, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T6, T7, T8, T9, T10, T11, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T7, T8, T9, T10, T11, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T8, T9, T10, T11, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T9, T10, T11, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T10, T11, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T11, R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function12.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function12.java b/src/main/groovy/groovy/util/function/Function12.java
new file mode 100644
index 0000000..b7bae15
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function12.java
@@ -0,0 +1,225 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 12 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T4, T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T6, T7, T8, T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T7, T8, T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T8, T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T9, T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T10, T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T11, T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T12, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T4, T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T5, T6, T7, T8, T9, T10, T11, T12, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T6, T7, T8, T9, T10, T11, T12, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T7, T8, T9, T10, T11, T12, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T8, T9, T10, T11, T12, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T9, T10, T11, T12, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T10, T11, T12, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T11, T12, R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T12, R> applyPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function13.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function13.java b/src/main/groovy/groovy/util/function/Function13.java
new file mode 100644
index 0000000..fdadc58
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function13.java
@@ -0,0 +1,240 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 13 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T7, T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T8, T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T9, T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T10, T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T11, T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T12, T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T13, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T5, T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T6, T7, T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T7, T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T8, T9, T10, T11, T12, T13, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T9, T10, T11, T12, T13, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T10, T11, T12, T13, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T11, T12, T13, R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T12, T13, R> applyPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T13, R> applyPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13());
+    }
+
+}


[6/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple14.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple14.java b/src/main/groovy/groovy/lang/Tuple14.java
new file mode 100644
index 0000000..12dee86
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple14.java
@@ -0,0 +1,618 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function14;
+
+/**
+ * Represents a list of 14 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> extends Tuple {
+    private static final long serialVersionUID = -8866382365396941648L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+    private final T11 v11;
+    private final T12 v12;
+    private final T13 v13;
+    private final T14 v14;
+
+    public Tuple14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+        this.v11 = v11;
+        this.v12 = v12;
+        this.v13 = v13;
+        this.v14 = v14;
+    }
+
+    public Tuple14(Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11, tuple.v12, tuple.v13, tuple.v14);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+    public T11 v11() {
+        return v11;
+    }
+
+    public T12 v12() {
+        return v12;
+    }
+
+    public T13 v13() {
+        return v13;
+    }
+
+    public T14 v14() {
+        return v14;
+    }
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(T15 value) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple1<T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple2<T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 14.
+     */
+    public final Tuple2<Tuple0, Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 13.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 12.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 11.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 10.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 9.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple9<T6, T7, T8, T9, T10, T11, T12, T13, T14>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 8.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple8<T7, T8, T9, T10, T11, T12, T13, T14>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 7.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple7<T8, T9, T10, T11, T12, T13, T14>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 6.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple6<T9, T10, T11, T12, T13, T14>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 5.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple5<T10, T11, T12, T13, T14>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 4.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple4<T11, T12, T13, T14>> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 11 and 3.
+     */
+    public final Tuple2<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Tuple3<T12, T13, T14>> split11() {
+        return new Tuple2<>(limit11(), skip11());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 12 and 2.
+     */
+    public final Tuple2<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>, Tuple2<T13, T14>> split12() {
+        return new Tuple2<>(limit12(), skip12());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 13 and 1.
+     */
+    public final Tuple2<Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>, Tuple1<T14>> split13() {
+        return new Tuple2<>(limit13(), skip13());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 14 and 0.
+     */
+    public final Tuple2<Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>, Tuple0> split14() {
+        return new Tuple2<>(limit14(), skip14());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Limit this tuple to degree 11.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> limit11() {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Limit this tuple to degree 12.
+     */
+    public final Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> limit12() {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Limit this tuple to degree 13.
+     */
+    public final Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> limit13() {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Limit this tuple to degree 14.
+     */
+    public final Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> limit14() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> skip1() {
+        return new Tuple13<>(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> skip2() {
+        return new Tuple12<>(v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> skip3() {
+        return new Tuple11<>(v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> skip4() {
+        return new Tuple10<>(v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple9<T6, T7, T8, T9, T10, T11, T12, T13, T14> skip5() {
+        return new Tuple9<>(v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple8<T7, T8, T9, T10, T11, T12, T13, T14> skip6() {
+        return new Tuple8<>(v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple7<T8, T9, T10, T11, T12, T13, T14> skip7() {
+        return new Tuple7<>(v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple6<T9, T10, T11, T12, T13, T14> skip8() {
+        return new Tuple6<>(v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple5<T10, T11, T12, T13, T14> skip9() {
+        return new Tuple5<>(v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple4<T11, T12, T13, T14> skip10() {
+        return new Tuple4<>(v11, v12, v13, v14);
+    }
+
+    /**
+     * Skip 11 degrees from this tuple.
+     */
+    public final Tuple3<T12, T13, T14> skip11() {
+        return new Tuple3<>(v12, v13, v14);
+    }
+
+    /**
+     * Skip 12 degrees from this tuple.
+     */
+    public final Tuple2<T13, T14> skip12() {
+        return new Tuple2<>(v13, v14);
+    }
+
+    /**
+     * Skip 13 degrees from this tuple.
+     */
+    public final Tuple1<T14> skip13() {
+        return new Tuple1<>(v14);
+    }
+
+    /**
+     * Skip 14 degrees from this tuple.
+     */
+    public final Tuple0 skip14() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function14<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? super T11, ? super T12, ? super T13, ? super T14, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple14<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple14<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple14<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple14<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple14<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple14<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple14<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple14<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple14<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10, T11, T12, T13, T14> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple14<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple14<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10, T11, T12, T13, T14> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple14<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10, T11, T12, T13, T14> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple14<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10, T11, T12, T13, T14> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10, T11, T12, T13, T14> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10, T11, T12, T13, T14> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10), v11, v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 11 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U11> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, U11, T12, T13, T14> map11(Function1<? super T11, ? extends U11> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, function.apply(v11), v12, v13, v14);
+    }
+
+    /**
+     * Apply attribute 12 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U12> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, U12, T13, T14> map12(Function1<? super T12, ? extends U12> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, function.apply(v12), v13, v14);
+    }
+
+    /**
+     * Apply attribute 13 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U13> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, U13, T14> map13(Function1<? super T13, ? extends U13> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, function.apply(v13), v14);
+    }
+
+    /**
+     * Apply attribute 14 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, U14> map14(Function1<? super T14, ? extends U14> function) {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, function.apply(v14));
+    }
+
+
+    @Override
+    public Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> clone() {
+        return new Tuple14<>(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple15.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple15.java b/src/main/groovy/groovy/lang/Tuple15.java
new file mode 100644
index 0000000..062d801
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple15.java
@@ -0,0 +1,644 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function15;
+
+/**
+ * Represents a list of 15 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> extends Tuple {
+    private static final long serialVersionUID = -8866382365396941648L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+    private final T11 v11;
+    private final T12 v12;
+    private final T13 v13;
+    private final T14 v14;
+    private final T15 v15;
+
+    public Tuple15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+        this.v11 = v11;
+        this.v12 = v12;
+        this.v13 = v13;
+        this.v14 = v14;
+        this.v15 = v15;
+    }
+
+    public Tuple15(Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11, tuple.v12, tuple.v13, tuple.v14, tuple.v15);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+    public T11 v11() {
+        return v11;
+    }
+
+    public T12 v12() {
+        return v12;
+    }
+
+    public T13 v13() {
+        return v13;
+    }
+
+    public T14 v14() {
+        return v14;
+    }
+
+    public T15 v15() {
+        return v15;
+    }
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(T16 value) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple1<T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, tuple.v1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 15.
+     */
+    public final Tuple2<Tuple0, Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 14.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 13.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 12.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 11.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 10.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 9.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple9<T7, T8, T9, T10, T11, T12, T13, T14, T15>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 8.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple8<T8, T9, T10, T11, T12, T13, T14, T15>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 7.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple7<T9, T10, T11, T12, T13, T14, T15>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 6.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple6<T10, T11, T12, T13, T14, T15>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 5.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple5<T11, T12, T13, T14, T15>> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 11 and 4.
+     */
+    public final Tuple2<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Tuple4<T12, T13, T14, T15>> split11() {
+        return new Tuple2<>(limit11(), skip11());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 12 and 3.
+     */
+    public final Tuple2<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>, Tuple3<T13, T14, T15>> split12() {
+        return new Tuple2<>(limit12(), skip12());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 13 and 2.
+     */
+    public final Tuple2<Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>, Tuple2<T14, T15>> split13() {
+        return new Tuple2<>(limit13(), skip13());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 14 and 1.
+     */
+    public final Tuple2<Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>, Tuple1<T15>> split14() {
+        return new Tuple2<>(limit14(), skip14());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 15 and 0.
+     */
+    public final Tuple2<Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>, Tuple0> split15() {
+        return new Tuple2<>(limit15(), skip15());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Limit this tuple to degree 11.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> limit11() {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Limit this tuple to degree 12.
+     */
+    public final Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> limit12() {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Limit this tuple to degree 13.
+     */
+    public final Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> limit13() {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Limit this tuple to degree 14.
+     */
+    public final Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> limit14() {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Limit this tuple to degree 15.
+     */
+    public final Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> limit15() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> skip1() {
+        return new Tuple14<>(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> skip2() {
+        return new Tuple13<>(v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> skip3() {
+        return new Tuple12<>(v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> skip4() {
+        return new Tuple11<>(v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> skip5() {
+        return new Tuple10<>(v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple9<T7, T8, T9, T10, T11, T12, T13, T14, T15> skip6() {
+        return new Tuple9<>(v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple8<T8, T9, T10, T11, T12, T13, T14, T15> skip7() {
+        return new Tuple8<>(v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple7<T9, T10, T11, T12, T13, T14, T15> skip8() {
+        return new Tuple7<>(v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple6<T10, T11, T12, T13, T14, T15> skip9() {
+        return new Tuple6<>(v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple5<T11, T12, T13, T14, T15> skip10() {
+        return new Tuple5<>(v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 11 degrees from this tuple.
+     */
+    public final Tuple4<T12, T13, T14, T15> skip11() {
+        return new Tuple4<>(v12, v13, v14, v15);
+    }
+
+    /**
+     * Skip 12 degrees from this tuple.
+     */
+    public final Tuple3<T13, T14, T15> skip12() {
+        return new Tuple3<>(v13, v14, v15);
+    }
+
+    /**
+     * Skip 13 degrees from this tuple.
+     */
+    public final Tuple2<T14, T15> skip13() {
+        return new Tuple2<>(v14, v15);
+    }
+
+    /**
+     * Skip 14 degrees from this tuple.
+     */
+    public final Tuple1<T15> skip14() {
+        return new Tuple1<>(v15);
+    }
+
+    /**
+     * Skip 15 degrees from this tuple.
+     */
+    public final Tuple0 skip15() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function15<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? super T11, ? super T12, ? super T13, ? super T14, ? super T15, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple15<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple15<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple15<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple15<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple15<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple15<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple15<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple15<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple15<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple15<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple15<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10, T11, T12, T13, T14, T15> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple15<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10, T11, T12, T13, T14, T15> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple15<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10, T11, T12, T13, T14, T15> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10, T11, T12, T13, T14, T15> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10, T11, T12, T13, T14, T15> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10), v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 11 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U11> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, U11, T12, T13, T14, T15> map11(Function1<? super T11, ? extends U11> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, function.apply(v11), v12, v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 12 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U12> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, U12, T13, T14, T15> map12(Function1<? super T12, ? extends U12> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, function.apply(v12), v13, v14, v15);
+    }
+
+    /**
+     * Apply attribute 13 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U13> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, U13, T14, T15> map13(Function1<? super T13, ? extends U13> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, function.apply(v13), v14, v15);
+    }
+
+    /**
+     * Apply attribute 14 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U14> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, U14, T15> map14(Function1<? super T14, ? extends U14> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, function.apply(v14), v15);
+    }
+
+    /**
+     * Apply attribute 15 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, U15> map15(Function1<? super T15, ? extends U15> function) {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, function.apply(v15));
+    }
+
+    @Override
+    public Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> clone() {
+        return new Tuple15<>(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple16.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple16.java b/src/main/groovy/groovy/lang/Tuple16.java
new file mode 100644
index 0000000..08267b2
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple16.java
@@ -0,0 +1,665 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function16;
+
+/**
+ * Represents a list of 16 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> extends Tuple {
+    private static final long serialVersionUID = -8866382365396941648L;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
+    private final T4 v4;
+    private final T5 v5;
+    private final T6 v6;
+    private final T7 v7;
+    private final T8 v8;
+    private final T9 v9;
+    private final T10 v10;
+    private final T11 v11;
+    private final T12 v12;
+    private final T13 v13;
+    private final T14 v14;
+    private final T15 v15;
+    private final T16 v16;
+
+    public Tuple16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) {
+        super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
+        this.v4 = v4;
+        this.v5 = v5;
+        this.v6 = v6;
+        this.v7 = v7;
+        this.v8 = v8;
+        this.v9 = v9;
+        this.v10 = v10;
+        this.v11 = v11;
+        this.v12 = v12;
+        this.v13 = v13;
+        this.v14 = v14;
+        this.v15 = v15;
+        this.v16 = v16;
+    }
+
+    public Tuple16(Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11, tuple.v12, tuple.v13, tuple.v14, tuple.v15, tuple.v16);
+    }
+
+    @Deprecated
+    public T1 getFirst() {
+        return v1;
+    }
+
+    @Deprecated
+    public T2 getSecond() {
+        return v2;
+    }
+
+    @Deprecated
+    public T3 getThird() {
+        return v3;
+    }
+
+    @Deprecated
+    public T4 getFourth() {
+        return v4;
+    }
+
+    @Deprecated
+    public T5 getFifth() {
+        return v5;
+    }
+
+    @Deprecated
+    public T6 getSixth() {
+        return v6;
+    }
+
+    @Deprecated
+    public T7 getSeventh() {
+        return v7;
+    }
+
+    @Deprecated
+    public T8 getEighth() {
+        return v8;
+    }
+
+    @Deprecated
+    public T9 getNinth() {
+        return v9;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    public T4 v4() {
+        return v4;
+    }
+
+    public T5 v5() {
+        return v5;
+    }
+
+    public T6 v6() {
+        return v6;
+    }
+
+    public T7 v7() {
+        return v7;
+    }
+
+    public T8 v8() {
+        return v8;
+    }
+
+    public T9 v9() {
+        return v9;
+    }
+
+    public T10 v10() {
+        return v10;
+    }
+
+    public T11 v11() {
+        return v11;
+    }
+
+    public T12 v12() {
+        return v12;
+    }
+
+    public T13 v13() {
+        return v13;
+    }
+
+    public T14 v14() {
+        return v14;
+    }
+
+    public T15 v15() {
+        return v15;
+    }
+
+    public T16 v16() {
+        return v16;
+    }
+
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 16.
+     */
+    public final Tuple2<Tuple0, Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 15.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 14.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 13.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 4 and 12.
+     */
+    public final Tuple2<Tuple4<T1, T2, T3, T4>, Tuple12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split4() {
+        return new Tuple2<>(limit4(), skip4());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 5 and 11.
+     */
+    public final Tuple2<Tuple5<T1, T2, T3, T4, T5>, Tuple11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split5() {
+        return new Tuple2<>(limit5(), skip5());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 6 and 10.
+     */
+    public final Tuple2<Tuple6<T1, T2, T3, T4, T5, T6>, Tuple10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> split6() {
+        return new Tuple2<>(limit6(), skip6());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 7 and 9.
+     */
+    public final Tuple2<Tuple7<T1, T2, T3, T4, T5, T6, T7>, Tuple9<T8, T9, T10, T11, T12, T13, T14, T15, T16>> split7() {
+        return new Tuple2<>(limit7(), skip7());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 8 and 8.
+     */
+    public final Tuple2<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>, Tuple8<T9, T10, T11, T12, T13, T14, T15, T16>> split8() {
+        return new Tuple2<>(limit8(), skip8());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 9 and 7.
+     */
+    public final Tuple2<Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Tuple7<T10, T11, T12, T13, T14, T15, T16>> split9() {
+        return new Tuple2<>(limit9(), skip9());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 10 and 6.
+     */
+    public final Tuple2<Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Tuple6<T11, T12, T13, T14, T15, T16>> split10() {
+        return new Tuple2<>(limit10(), skip10());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 11 and 5.
+     */
+    public final Tuple2<Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Tuple5<T12, T13, T14, T15, T16>> split11() {
+        return new Tuple2<>(limit11(), skip11());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 12 and 4.
+     */
+    public final Tuple2<Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>, Tuple4<T13, T14, T15, T16>> split12() {
+        return new Tuple2<>(limit12(), skip12());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 13 and 3.
+     */
+    public final Tuple2<Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>, Tuple3<T14, T15, T16>> split13() {
+        return new Tuple2<>(limit13(), skip13());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 14 and 2.
+     */
+    public final Tuple2<Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>, Tuple2<T15, T16>> split14() {
+        return new Tuple2<>(limit14(), skip14());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 15 and 1.
+     */
+    public final Tuple2<Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>, Tuple1<T16>> split15() {
+        return new Tuple2<>(limit15(), skip15());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 16 and 0.
+     */
+    public final Tuple2<Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>, Tuple0> split16() {
+        return new Tuple2<>(limit16(), skip16());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return new Tuple3<>(v1, v2, v3);
+    }
+
+    /**
+     * Limit this tuple to degree 4.
+     */
+    public final Tuple4<T1, T2, T3, T4> limit4() {
+        return new Tuple4<>(v1, v2, v3, v4);
+    }
+
+    /**
+     * Limit this tuple to degree 5.
+     */
+    public final Tuple5<T1, T2, T3, T4, T5> limit5() {
+        return new Tuple5<>(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Limit this tuple to degree 6.
+     */
+    public final Tuple6<T1, T2, T3, T4, T5, T6> limit6() {
+        return new Tuple6<>(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Limit this tuple to degree 7.
+     */
+    public final Tuple7<T1, T2, T3, T4, T5, T6, T7> limit7() {
+        return new Tuple7<>(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Limit this tuple to degree 8.
+     */
+    public final Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> limit8() {
+        return new Tuple8<>(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Limit this tuple to degree 9.
+     */
+    public final Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> limit9() {
+        return new Tuple9<>(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Limit this tuple to degree 10.
+     */
+    public final Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> limit10() {
+        return new Tuple10<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+    }
+
+    /**
+     * Limit this tuple to degree 11.
+     */
+    public final Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> limit11() {
+        return new Tuple11<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+    }
+
+    /**
+     * Limit this tuple to degree 12.
+     */
+    public final Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> limit12() {
+        return new Tuple12<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+    }
+
+    /**
+     * Limit this tuple to degree 13.
+     */
+    public final Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> limit13() {
+        return new Tuple13<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+    }
+
+    /**
+     * Limit this tuple to degree 14.
+     */
+    public final Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> limit14() {
+        return new Tuple14<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Limit this tuple to degree 15.
+     */
+    public final Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> limit15() {
+        return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Limit this tuple to degree 16.
+     */
+    public final Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> limit16() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip1() {
+        return new Tuple15<>(v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip2() {
+        return new Tuple14<>(v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip3() {
+        return new Tuple13<>(v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 4 degrees from this tuple.
+     */
+    public final Tuple12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip4() {
+        return new Tuple12<>(v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 5 degrees from this tuple.
+     */
+    public final Tuple11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip5() {
+        return new Tuple11<>(v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 6 degrees from this tuple.
+     */
+    public final Tuple10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> skip6() {
+        return new Tuple10<>(v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 7 degrees from this tuple.
+     */
+    public final Tuple9<T8, T9, T10, T11, T12, T13, T14, T15, T16> skip7() {
+        return new Tuple9<>(v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 8 degrees from this tuple.
+     */
+    public final Tuple8<T9, T10, T11, T12, T13, T14, T15, T16> skip8() {
+        return new Tuple8<>(v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 9 degrees from this tuple.
+     */
+    public final Tuple7<T10, T11, T12, T13, T14, T15, T16> skip9() {
+        return new Tuple7<>(v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 10 degrees from this tuple.
+     */
+    public final Tuple6<T11, T12, T13, T14, T15, T16> skip10() {
+        return new Tuple6<>(v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 11 degrees from this tuple.
+     */
+    public final Tuple5<T12, T13, T14, T15, T16> skip11() {
+        return new Tuple5<>(v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 12 degrees from this tuple.
+     */
+    public final Tuple4<T13, T14, T15, T16> skip12() {
+        return new Tuple4<>(v13, v14, v15, v16);
+    }
+
+    /**
+     * Skip 13 degrees from this tuple.
+     */
+    public final Tuple3<T14, T15, T16> skip13() {
+        return new Tuple3<>(v14, v15, v16);
+    }
+
+    /**
+     * Skip 14 degrees from this tuple.
+     */
+    public final Tuple2<T15, T16> skip14() {
+        return new Tuple2<>(v15, v16);
+    }
+
+    /**
+     * Skip 15 degrees from this tuple.
+     */
+    public final Tuple1<T16> skip15() {
+        return new Tuple1<>(v16);
+    }
+
+    /**
+     * Skip 16 degrees from this tuple.
+     */
+    public final Tuple0 skip16() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function16<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? super T10, ? super T11, ? super T12, ? super T13, ? super T14, ? super T15, ? super T16, ? extends R> function) {
+        return function.apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple16<U1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple16<>(function.apply(v1), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple16<T1, U2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple16<>(v1, function.apply(v2), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple16<T1, T2, U3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple16<>(v1, v2, function.apply(v3), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 4 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U4> Tuple16<T1, T2, T3, U4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map4(Function1<? super T4, ? extends U4> function) {
+        return new Tuple16<>(v1, v2, v3, function.apply(v4), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 5 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U5> Tuple16<T1, T2, T3, T4, U5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map5(Function1<? super T5, ? extends U5> function) {
+        return new Tuple16<>(v1, v2, v3, v4, function.apply(v5), v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 6 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U6> Tuple16<T1, T2, T3, T4, T5, U6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map6(Function1<? super T6, ? extends U6> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, function.apply(v6), v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 7 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U7> Tuple16<T1, T2, T3, T4, T5, T6, U7, T8, T9, T10, T11, T12, T13, T14, T15, T16> map7(Function1<? super T7, ? extends U7> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, function.apply(v7), v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 8 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U8> Tuple16<T1, T2, T3, T4, T5, T6, T7, U8, T9, T10, T11, T12, T13, T14, T15, T16> map8(Function1<? super T8, ? extends U8> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, function.apply(v8), v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 9 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U9> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, U9, T10, T11, T12, T13, T14, T15, T16> map9(Function1<? super T9, ? extends U9> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, function.apply(v9), v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 10 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U10> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, U10, T11, T12, T13, T14, T15, T16> map10(Function1<? super T10, ? extends U10> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, function.apply(v10), v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 11 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U11> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, U11, T12, T13, T14, T15, T16> map11(Function1<? super T11, ? extends U11> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, function.apply(v11), v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 12 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U12> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, U12, T13, T14, T15, T16> map12(Function1<? super T12, ? extends U12> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, function.apply(v12), v13, v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 13 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U13> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, U13, T14, T15, T16> map13(Function1<? super T13, ? extends U13> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, function.apply(v13), v14, v15, v16);
+    }
+
+    /**
+     * Apply attribute 14 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U14> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, U14, T15, T16> map14(Function1<? super T14, ? extends U14> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, function.apply(v14), v15, v16);
+    }
+
+    /**
+     * Apply attribute 15 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U15> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, U15, T16> map15(Function1<? super T15, ? extends U15> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, function.apply(v15), v16);
+    }
+
+    /**
+     * Apply attribute 16 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, U16> map16(Function1<? super T16, ? extends U16> function) {
+        return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, function.apply(v16));
+    }
+
+    @Override
+    public Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> clone() {
+        return new Tuple16<>(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple2.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple2.java b/src/main/groovy/groovy/lang/Tuple2.java
index b096aee..3214c6b 100644
--- a/src/main/groovy/groovy/lang/Tuple2.java
+++ b/src/main/groovy/groovy/lang/Tuple2.java
@@ -18,43 +18,268 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function2;
+
+import java.util.Optional;
+
 /**
  * Represents a list of 2 typed Objects.
  */
 public class Tuple2<T1, T2> extends Tuple {
     private static final long serialVersionUID = 9006144674906325597L;
-    private final T1 first;
-    private final T2 second;
+    private final T1 v1;
+    private final T2 v2;
 
-    public Tuple2(T1 first, T2 second) {
-        super(first, second);
+    public Tuple2(T1 v1, T2 v2) {
+        super(v1, v2);
 
-        this.first = first;
-        this.second = second;
-    }
-
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
+        this.v1 = v1;
+        this.v2 = v2;
     }
 
-    @Override
-    public int size() {
-        return 2;
+    public Tuple2(Tuple2<T1, T2> tuple) {
+        this(tuple.v1, tuple.v2);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T3> Tuple3<T1, T2, T3> concat(T3 value) {
+        return new Tuple3<>(v1, v2, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3> Tuple3<T1, T2, T3> concat(Tuple1<T3> tuple) {
+        return new Tuple3<>(v1, v2, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4> Tuple4<T1, T2, T3, T4> concat(Tuple2<T3, T4> tuple) {
+        return new Tuple4<>(v1, v2, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5> Tuple5<T1, T2, T3, T4, T5> concat(Tuple3<T3, T4, T5> tuple) {
+        return new Tuple5<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(Tuple4<T3, T4, T5, T6> tuple) {
+        return new Tuple6<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple5<T3, T4, T5, T6, T7> tuple) {
+        return new Tuple7<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple6<T3, T4, T5, T6, T7, T8> tuple) {
+        return new Tuple8<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple7<T3, T4, T5, T6, T7, T8, T9> tuple) {
+        return new Tuple9<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple8<T3, T4, T5, T6, T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple9<T3, T4, T5, T6, T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple10<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple11<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13(), tuple.v14());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 2.
+     */
+    public final Tuple2<Tuple0, Tuple2<T1, T2>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 1.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple1<T2>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 0.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple0> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple2<T1, T2> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple1<T2> skip1() {
+        return new Tuple1<>(v2);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple0 skip2() {
+        return new Tuple0();
+    }
+
+    /**
+     * Get a tuple with the two attributes swapped.
+     */
+    public final Tuple2<T2, T1> swap() {
+        return new Tuple2<>(v2, v1);
+    }
+
+    /**
+     * Whether two ranges represented by tuples overlap.
+     */
+    public static final <T extends Comparable<? super T>> boolean overlaps(Tuple2<T, T> left, Tuple2<T, T> right) {
+        return left.v1.compareTo(right.v2) <= 0
+                && left.v2.compareTo(right.v1) >= 0;
+    }
+
+    /**
+     * The intersection of two ranges represented by tuples
+     */
+    public static final <T extends Comparable<? super T>> Optional<Tuple2<T, T>> intersect(Tuple2<T, T> left, Tuple2<T, T> right) {
+        if (overlaps(left, right))
+            return Optional.of(new Tuple2<>(
+                    left.v1.compareTo(right.v1) >= 0 ? left.v1 : right.v1,
+                    left.v2.compareTo(right.v2) <= 0 ? left.v2 : right.v2
+            ));
+        else
+            return Optional.empty();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function2<? super T1, ? super T2, ? extends R> function) {
+        return function.apply(v1, v2);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple2<U1, T2> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple2<>(function.apply(v1), v2);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple2<T1, U2> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple2<>(v1, function.apply(v2));
+    }
+
+    @Override
+    public Tuple2<T1, T2> clone() {
+        return new Tuple2<>(this);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple3.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Tuple3.java b/src/main/groovy/groovy/lang/Tuple3.java
index b5fe7d9..ff5dbc9 100644
--- a/src/main/groovy/groovy/lang/Tuple3.java
+++ b/src/main/groovy/groovy/lang/Tuple3.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function3;
+
 /**
  * Represents a list of 3 typed Objects.
  *
@@ -26,46 +29,262 @@ package groovy.lang;
  */
 public class Tuple3<T1, T2, T3> extends Tuple {
     private static final long serialVersionUID = 8469774237154310687L;
-    private final T1 first;
-    private final T2 second;
-    private final T3 third;
+    private final T1 v1;
+    private final T2 v2;
+    private final T3 v3;
 
-    public Tuple3(T1 first, T2 second, T3 third) {
-        super(first, second, third);
+    public Tuple3(T1 v1, T2 v2, T3 v3) {
+        super(v1, v2, v3);
 
-        this.first = first;
-        this.second = second;
-        this.third = third;
+        this.v1 = v1;
+        this.v2 = v2;
+        this.v3 = v3;
     }
 
-    @Override
-    public Object get(int index) {
-        switch (index) {
-            case 0:
-                return first;
-            case 1:
-                return second;
-            case 2:
-                return third;
-            default:
-                throw new IndexOutOfBoundsException("index: " + index);
-        }
-    }
-
-    @Override
-    public int size() {
-        return 3;
+    public Tuple3(Tuple3<T1, T2, T3> tuple) {
+        this(tuple.v1, tuple.v2, tuple.v3);
     }
 
+    @Deprecated
     public T1 getFirst() {
-        return first;
+        return v1;
     }
 
+    @Deprecated
     public T2 getSecond() {
-        return second;
+        return v2;
     }
 
+    @Deprecated
     public T3 getThird() {
-        return third;
+        return v3;
+    }
+
+    public T1 v1() {
+        return v1;
+    }
+
+    public T2 v2() {
+        return v2;
+    }
+
+    public T3 v3() {
+        return v3;
+    }
+
+    /**
+     * Concatenate a value to this tuple.
+     */
+    public final <T4> Tuple4<T1, T2, T3, T4> concat(T4 value) {
+        return new Tuple4<>(v1, v2, v3, value);
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4> Tuple4<T1, T2, T3, T4> concat(Tuple1<T4> tuple) {
+        return new Tuple4<>(v1, v2, v3, tuple.v1());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5> Tuple5<T1, T2, T3, T4, T5> concat(Tuple2<T4, T5> tuple) {
+        return new Tuple5<>(v1, v2, v3, tuple.v1(), tuple.v2());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> concat(Tuple3<T4, T5, T6> tuple) {
+        return new Tuple6<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> concat(Tuple4<T4, T5, T6, T7> tuple) {
+        return new Tuple7<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> concat(Tuple5<T4, T5, T6, T7, T8> tuple) {
+        return new Tuple8<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> concat(Tuple6<T4, T5, T6, T7, T8, T9> tuple) {
+        return new Tuple9<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10> Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> concat(Tuple7<T4, T5, T6, T7, T8, T9, T10> tuple) {
+        return new Tuple10<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10, T11> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> concat(Tuple8<T4, T5, T6, T7, T8, T9, T10, T11> tuple) {
+        return new Tuple11<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10, T11, T12> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> concat(Tuple9<T4, T5, T6, T7, T8, T9, T10, T11, T12> tuple) {
+        return new Tuple12<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> concat(Tuple10<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> tuple) {
+        return new Tuple13<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> concat(Tuple11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> tuple) {
+        return new Tuple14<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> concat(Tuple12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> tuple) {
+        return new Tuple15<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12());
+    }
+
+    /**
+     * Concatenate a tuple to this tuple.
+     */
+    public final <T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> concat(Tuple13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> tuple) {
+        return new Tuple16<>(v1, v2, v3, tuple.v1(), tuple.v2(), tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 0 and 3.
+     */
+    public final Tuple2<Tuple0, Tuple3<T1, T2, T3>> split0() {
+        return new Tuple2<>(limit0(), skip0());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 1 and 2.
+     */
+    public final Tuple2<Tuple1<T1>, Tuple2<T2, T3>> split1() {
+        return new Tuple2<>(limit1(), skip1());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 2 and 1.
+     */
+    public final Tuple2<Tuple2<T1, T2>, Tuple1<T3>> split2() {
+        return new Tuple2<>(limit2(), skip2());
+    }
+
+    /**
+     * Split this tuple into two tuples of degree 3 and 0.
+     */
+    public final Tuple2<Tuple3<T1, T2, T3>, Tuple0> split3() {
+        return new Tuple2<>(limit3(), skip3());
+    }
+
+    /**
+     * Limit this tuple to degree 0.
+     */
+    public final Tuple0 limit0() {
+        return new Tuple0();
+    }
+
+    /**
+     * Limit this tuple to degree 1.
+     */
+    public final Tuple1<T1> limit1() {
+        return new Tuple1<>(v1);
+    }
+
+    /**
+     * Limit this tuple to degree 2.
+     */
+    public final Tuple2<T1, T2> limit2() {
+        return new Tuple2<>(v1, v2);
+    }
+
+    /**
+     * Limit this tuple to degree 3.
+     */
+    public final Tuple3<T1, T2, T3> limit3() {
+        return this;
+    }
+
+    /**
+     * Skip 0 degrees from this tuple.
+     */
+    public final Tuple3<T1, T2, T3> skip0() {
+        return this;
+    }
+
+    /**
+     * Skip 1 degrees from this tuple.
+     */
+    public final Tuple2<T2, T3> skip1() {
+        return new Tuple2<>(v2, v3);
+    }
+
+    /**
+     * Skip 2 degrees from this tuple.
+     */
+    public final Tuple1<T3> skip2() {
+        return new Tuple1<>(v3);
+    }
+
+    /**
+     * Skip 3 degrees from this tuple.
+     */
+    public final Tuple0 skip3() {
+        return new Tuple0();
+    }
+
+    /**
+     * Apply this tuple as arguments to a function.
+     */
+    public final <R> R map(Function3<? super T1, ? super T2, ? super T3, ? extends R> function) {
+        return function.apply(v1, v2, v3);
+    }
+
+    /**
+     * Apply attribute 1 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U1> Tuple3<U1, T2, T3> map1(Function1<? super T1, ? extends U1> function) {
+        return new Tuple3<>(function.apply(v1), v2, v3);
+    }
+
+    /**
+     * Apply attribute 2 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U2> Tuple3<T1, U2, T3> map2(Function1<? super T2, ? extends U2> function) {
+        return new Tuple3<>(v1, function.apply(v2), v3);
+    }
+
+    /**
+     * Apply attribute 3 as argument to a function and return a new tuple with the substituted argument.
+     */
+    public final <U3> Tuple3<T1, T2, U3> map3(Function1<? super T3, ? extends U3> function) {
+        return new Tuple3<>(v1, v2, function.apply(v3));
+    }
+
+
+    @Override
+    public Tuple3<T1, T2, T3> clone() {
+        return new Tuple3<>(this);
     }
 }


[2/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function14.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function14.java b/src/main/groovy/groovy/util/function/Function14.java
new file mode 100644
index 0000000..72c7d77
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function14.java
@@ -0,0 +1,255 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 14 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T8, T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T9, T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T10, T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T11, T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T12, T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T13, T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T14, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return (v14) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T6, T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T7, T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T8, T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T9, T10, T11, T12, T13, T14, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T10, T11, T12, T13, T14, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T11, T12, T13, T14, R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T12, T13, T14, R> applyPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T13, T14, R> applyPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13, v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13, v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T14, R> applyPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return (v14) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), v14);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function15.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function15.java b/src/main/groovy/groovy/util/function/Function15.java
new file mode 100644
index 0000000..1265ff3
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function15.java
@@ -0,0 +1,270 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple15;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 15 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple15<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T9, T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T10, T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T11, T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T12, T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T13, T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13, v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T14, T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return (v14, v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T15, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return (v15) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function13<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T7, T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T8, T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T9, T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T10, T11, T12, T13, T14, T15, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T11, T12, T13, T14, T15, R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T12, T13, T14, T15, R> applyPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T13, T14, T15, R> applyPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13, v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13, v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T14, T15, R> applyPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return (v14, v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), v14, v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T15, R> applyPartially(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return (v15) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), v15);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple15<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function16.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function16.java b/src/main/groovy/groovy/util/function/Function16.java
new file mode 100644
index 0000000..27e6f31
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function16.java
@@ -0,0 +1,285 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple15;
+import groovy.lang.Tuple16;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 16 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple16<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15, ? extends T16> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15(), args.v16());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9, v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T10, T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return (v10, v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T11, T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+        return (v11, v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T12, T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) {
+        return (v12, v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T13, T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) {
+        return (v13, v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T14, T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) {
+        return (v14, v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T15, T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+        return (v15, v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T16, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+        return (v16) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function14<T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function13<T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function12<T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function11<T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function10<T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function9<T8, T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T9, T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9, v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9, v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T10, T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return (v10, v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), v10, v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T11, T12, T13, T14, T15, T16, R> applyPartially(Tuple10<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10> args) {
+        return (v11, v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), v11, v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T12, T13, T14, T15, T16, R> applyPartially(Tuple11<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11> args) {
+        return (v12, v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), v12, v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T13, T14, T15, T16, R> applyPartially(Tuple12<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12> args) {
+        return (v13, v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), v13, v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T14, T15, T16, R> applyPartially(Tuple13<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13> args) {
+        return (v14, v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), v14, v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T15, T16, R> applyPartially(Tuple14<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14> args) {
+        return (v15, v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), v15, v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T16, R> applyPartially(Tuple15<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15> args) {
+        return (v16) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15(), v16);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple16<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9, ? extends T10, ? extends T11, ? extends T12, ? extends T13, ? extends T14, ? extends T15, ? extends T16> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), args.v13(), args.v14(), args.v15(), args.v16());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function2.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function2.java b/src/main/groovy/groovy/util/function/Function2.java
new file mode 100644
index 0000000..20216c8
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function2.java
@@ -0,0 +1,91 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+
+import java.util.function.BiFunction;
+
+/**
+ * A function with 2 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function2<T1, T2, R> extends BiFunction<T1, T2, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple2<? extends T1, ? extends T2> args) {
+        return apply(args.v1(), args.v2());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    @Override
+    R apply(T1 v1, T2 v2);
+
+    /**
+     * Convert this function to a {@link BiFunction}.
+     */
+    default BiFunction<T1, T2, R> toBiFunction() {
+        return this::apply;
+    }
+
+    /**
+     * Convert to this function from a {@link BiFunction}.
+     */
+    static <T1, T2, R> Function2<T1, T2, R> from(BiFunction<? super T1, ? super T2, ? extends R> function) {
+        return function::apply;
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T2, R> applyPartially(T1 v1) {
+        return (v2) -> apply(v1, v2);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2) {
+        return () -> apply(v1, v2);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T2, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2) -> apply(args.v1(), v2);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return () -> apply(args.v1(), args.v2());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function3.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function3.java b/src/main/groovy/groovy/util/function/Function3.java
new file mode 100644
index 0000000..eed1a3e
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function3.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+
+
+/**
+ * A function with 3 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function3<T1, T2, T3, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return apply(args.v1(), args.v2(), args.v3());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T2, T3, R> applyPartially(T1 v1) {
+        return (v2, v3) -> apply(v1, v2, v3);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T3, R> applyPartially(T1 v1, T2 v2) {
+        return (v3) -> apply(v1, v2, v3);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return () -> apply(v1, v2, v3);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T2, T3, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3) -> apply(args.v1(), v2, v3);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T3, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3) -> apply(args.v1(), args.v2(), v3);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function4.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function4.java b/src/main/groovy/groovy/util/function/Function4.java
new file mode 100644
index 0000000..f496a82
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function4.java
@@ -0,0 +1,105 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+
+
+/**
+ * A function with 4 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function4<T1, T2, T3, T4, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T2, T3, T4, R> applyPartially(T1 v1) {
+        return (v2, v3, v4) -> apply(v1, v2, v3, v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T3, T4, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4) -> apply(v1, v2, v3, v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T4, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4) -> apply(v1, v2, v3, v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return () -> apply(v1, v2, v3, v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T2, T3, T4, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4) -> apply(args.v1(), v2, v3, v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T3, T4, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4) -> apply(args.v1(), args.v2(), v3, v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T4, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4) -> apply(args.v1(), args.v2(), args.v3(), v4);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function5.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function5.java b/src/main/groovy/groovy/util/function/Function5.java
new file mode 100644
index 0000000..d2d545e
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function5.java
@@ -0,0 +1,120 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+
+
+/**
+ * A function with 5 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function5<T1, T2, T3, T4, T5, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T2, T3, T4, T5, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5) -> apply(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T3, T4, T5, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5) -> apply(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T4, T5, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5) -> apply(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T5, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5) -> apply(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return () -> apply(v1, v2, v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T2, T3, T4, T5, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5) -> apply(args.v1(), v2, v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T3, T4, T5, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5) -> apply(args.v1(), args.v2(), v3, v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T4, T5, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5) -> apply(args.v1(), args.v2(), args.v3(), v4, v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T5, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function6.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function6.java b/src/main/groovy/groovy/util/function/Function6.java
new file mode 100644
index 0000000..21bb27c
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function6.java
@@ -0,0 +1,135 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+
+
+/**
+ * A function with 6 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function6<T1, T2, T3, T4, T5, T6, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T2, T3, T4, T5, T6, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6) -> apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T3, T4, T5, T6, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6) -> apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T4, T5, T6, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6) -> apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T5, T6, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6) -> apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T6, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6) -> apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return () -> apply(v1, v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T2, T3, T4, T5, T6, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6) -> apply(args.v1(), v2, v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T3, T4, T5, T6, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6) -> apply(args.v1(), args.v2(), v3, v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T4, T5, T6, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T5, T6, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T6, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function7.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function7.java b/src/main/groovy/groovy/util/function/Function7.java
new file mode 100644
index 0000000..f1e4917
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function7.java
@@ -0,0 +1,150 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+
+
+/**
+ * A function with 7 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function7<T1, T2, T3, T4, T5, T6, T7, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T2, T3, T4, T5, T6, T7, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7) -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T3, T4, T5, T6, T7, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7) -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T4, T5, T6, T7, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7) -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T5, T6, T7, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7) -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T6, T7, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7) -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T7, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7) -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T2, T3, T4, T5, T6, T7, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7) -> apply(args.v1(), v2, v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T3, T4, T5, T6, T7, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T4, T5, T6, T7, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T5, T6, T7, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T6, T7, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T7, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function8.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function8.java b/src/main/groovy/groovy/util/function/Function8.java
new file mode 100644
index 0000000..5729d84
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function8.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+
+
+/**
+ * A function with 8 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function8<T1, T2, T3, T4, T5, T6, T7, T8, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T2, T3, T4, T5, T6, T7, T8, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T3, T4, T5, T6, T7, T8, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T4, T5, T6, T7, T8, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T5, T6, T7, T8, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T6, T7, T8, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T7, T8, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T8, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8) -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T2, T3, T4, T5, T6, T7, T8, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T3, T4, T5, T6, T7, T8, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T4, T5, T6, T7, T8, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T5, T6, T7, T8, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T6, T7, T8, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T7, T8, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T8, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function9.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/function/Function9.java b/src/main/groovy/groovy/util/function/Function9.java
new file mode 100644
index 0000000..a82be5e
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function9.java
@@ -0,0 +1,180 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 9 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> {
+
+    /**
+     * Apply this function to the arguments.
+     *
+     * @param args The arguments as a tuple.
+     */
+    default R apply(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9());
+    }
+
+    /**
+     * Apply this function to the arguments.
+     */
+    R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9);
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T2, T3, T4, T5, T6, T7, T8, T9, R> applyPartially(T1 v1) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T3, T4, T5, T6, T7, T8, T9, R> applyPartially(T1 v1, T2 v2) {
+        return (v3, v4, v5, v6, v7, v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T4, T5, T6, T7, T8, T9, R> applyPartially(T1 v1, T2 v2, T3 v3) {
+        return (v4, v5, v6, v7, v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T5, T6, T7, T8, T9, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+        return (v5, v6, v7, v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T6, T7, T8, T9, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+        return (v6, v7, v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T7, T8, T9, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+        return (v7, v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T8, T9, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+        return (v8, v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T9, R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+        return (v9) -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+        return () -> apply(v1, v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function8<T2, T3, T4, T5, T6, T7, T8, T9, R> applyPartially(Tuple1<? extends T1> args) {
+        return (v2, v3, v4, v5, v6, v7, v8, v9) -> apply(args.v1(), v2, v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function7<T3, T4, T5, T6, T7, T8, T9, R> applyPartially(Tuple2<? extends T1, ? extends T2> args) {
+        return (v3, v4, v5, v6, v7, v8, v9) -> apply(args.v1(), args.v2(), v3, v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function6<T4, T5, T6, T7, T8, T9, R> applyPartially(Tuple3<? extends T1, ? extends T2, ? extends T3> args) {
+        return (v4, v5, v6, v7, v8, v9) -> apply(args.v1(), args.v2(), args.v3(), v4, v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function5<T5, T6, T7, T8, T9, R> applyPartially(Tuple4<? extends T1, ? extends T2, ? extends T3, ? extends T4> args) {
+        return (v5, v6, v7, v8, v9) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), v5, v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function4<T6, T7, T8, T9, R> applyPartially(Tuple5<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5> args) {
+        return (v6, v7, v8, v9) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), v6, v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function3<T7, T8, T9, R> applyPartially(Tuple6<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6> args) {
+        return (v7, v8, v9) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), v7, v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function2<T8, T9, R> applyPartially(Tuple7<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7> args) {
+        return (v8, v9) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), v8, v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function1<T9, R> applyPartially(Tuple8<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8> args) {
+        return (v9) -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), v9);
+    }
+
+    /**
+     * Partially apply this function to the arguments.
+     */
+    default Function0<R> applyPartially(Tuple9<? extends T1, ? extends T2, ? extends T3, ? extends T4, ? extends T5, ? extends T6, ? extends T7, ? extends T8, ? extends T9> args) {
+        return () -> apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), args.v6(), args.v7(), args.v8(), args.v9());
+    }
+
+}