You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2023/05/24 15:42:12 UTC

[groovy] branch master updated (c1b1884f43 -> 521bc99698)

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


    from c1b1884f43 moving object array extensions
     new a401af9b0b moving object array extensions
     new 521bc99698 `findLastIndexOf(Object[],Closure)` right-to-left iteration

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../groovy/runtime/ArrayGroovyMethods.java         | 1727 ++++++++++++++++-
 .../groovy/runtime/DefaultGroovyMethods.java       | 1998 ++++----------------
 2 files changed, 2037 insertions(+), 1688 deletions(-)


[groovy] 02/02: `findLastIndexOf(Object[],Closure)` right-to-left iteration

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 521bc996981e6b7771be01b7f12e637b4c988f4c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed May 24 09:46:36 2023 -0500

    `findLastIndexOf(Object[],Closure)` right-to-left iteration
---
 .../groovy/runtime/ArrayGroovyMethods.java         | 53 ++++++++++++++++------
 .../groovy/runtime/DefaultGroovyMethods.java       | 14 +++---
 2 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index 5f00f328f1..d7808ab376 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -2483,7 +2483,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self      an array
      * @param condition the matching condition
-     * @return an integer that is the index of the first matched object or -1 if no match was found
+     * @return The index of the first matched object or -1 if no match was found.
      * @since 2.5.0
      */
     public static <T> int findIndexOf(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
@@ -2498,7 +2498,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self       an array
      * @param startIndex start matching from this index
      * @param condition  the matching condition
-     * @return an integer that is the index of the first matched object or -1 if no match was found
+     * @return The index of the first matched object or -1 if no match was found.
      * @since 2.5.0
      */
     public static <T> int findIndexOf(T[] self, int startIndex, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
@@ -2540,32 +2540,57 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     // findLastIndexOf
 
     /**
-     * Iterates over the elements of an array and returns the index of the last
-     * item that matches the condition specified in the closure.
+     * Returns the index of the last item that matches the specified condition.
+     * <pre class="groovyTestCase">
+     * def array = new Number[]{1, 2, 1, 2, 1}
+     * assert array.findLastIndexOf{it==1} ==  4
+     * assert array.findLastIndexOf{it==2} ==  3
+     * assert array.findLastIndexOf{it==3} == -1
+     * assert array.findLastIndexOf{it&gt;=0} ==  4
+     * assert array.findLastIndexOf{it&lt;=0} == -1
+     * def empty = new Object[0]
+     * assert empty.findLastIndexOf {true} == -1
+     * </pre>
      *
      * @param self      an array
      * @param condition the matching condition
-     * @return an integer that is the index of the last matched object or -1 if no match was found
+     * @return The index of the last matched object or -1 if no match was found.
      * @since 2.5.0
      */
     public static <T> int findLastIndexOf(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
-        return DefaultGroovyMethods.findLastIndexOf(new ArrayIterator<>(self), 0, condition);
+        return findLastIndexOf(self, 0, condition);
     }
 
     /**
-     * Iterates over the elements of an array, starting from a specified index,
-     * and returns the index of the last item that matches the condition
-     * specified in the closure.
+     * Returns the index of the last item that matches the specified condition
+     * that is at or beyond the given index.
+     * <pre class="groovyTestCase">
+     * def array = new Number[]{3, 1, 2, 1, 2, 1}
+     * assert array.findLastIndexOf(1,{it==0}) == -1
+     * assert array.findLastIndexOf(1,{it==1}) ==  5
+     * assert array.findLastIndexOf(1,{it==2}) ==  4
+     * assert array.findLastIndexOf(1,{it==3}) == -1
+     * assert array.findLastIndexOf(0,{it==3}) ==  0
+     * def empty = new Object[0]
+     * assert empty.findLastIndexOf( 2,{true}) == -1
+     * assert empty.findLastIndexOf(-2,{true}) == -1
+     * </pre>
      *
      * @param self       an array
-     * @param startIndex start matching from this index
+     * @param lowerBound the minimum index
      * @param condition  the matching condition
-     * @return an integer that is the index of the last matched object or -1 if no match was found
+     * @return The index of the last matched object or -1 if no match was found.
      * @since 2.5.0
      */
-    public static <T> int findLastIndexOf(T[] self, int startIndex, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
-        // TODO: Could this be made more efficient by using a reverse index?
-        return DefaultGroovyMethods.findLastIndexOf(new ArrayIterator<>(self), startIndex, condition);
+    public static <T> int findLastIndexOf(T[] self, int lowerBound, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+        if (lowerBound < 0) lowerBound = 0; // ensure it's non-negative
+        for (int i = self.length - 1; i >= lowerBound; i -= 1) {
+            if (bcw.call(self[i])) {
+                return i;
+            }
+        }
+        return -1;
     }
 
     //--------------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index ae42b8aab0..3e444a1362 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -96,7 +96,6 @@ import org.codehaus.groovy.runtime.typehandling.GroovyCastException;
 import org.codehaus.groovy.runtime.typehandling.NumberMath;
 import org.codehaus.groovy.tools.RootLoader;
 import org.codehaus.groovy.transform.trait.Traits;
-import org.codehaus.groovy.util.ArrayIterator;
 import org.codehaus.groovy.util.IteratorBufferedIterator;
 import org.codehaus.groovy.util.ListBufferedIterator;
 
@@ -14904,33 +14903,32 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     @Deprecated(since = "5.0.0")
     public static <T> List<Number> findIndexValues(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        return findIndexValues(self, 0, condition);
+        return ArrayGroovyMethods.findIndexValues(self, 0, condition);
     }
 
     @Deprecated(since = "5.0.0")
     public static <T> List<Number> findIndexValues(T[] self, Number startIndex, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        return findIndexValues(new ArrayIterator<>(self), startIndex, condition);
+        return ArrayGroovyMethods.findIndexValues(self, startIndex, condition);
     }
 
     @Deprecated(since = "5.0.0")
     public static <T> int findIndexOf(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        return findIndexOf(self, 0, condition);
+        return ArrayGroovyMethods.findIndexOf(self, 0, condition);
     }
 
     @Deprecated(since = "5.0.0")
     public static <T> int findIndexOf(T[] self, int startIndex, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        return findIndexOf(new ArrayIterator<>(self), startIndex, condition);
+        return ArrayGroovyMethods.findIndexOf(self, startIndex, condition);
     }
 
     @Deprecated(since = "5.0.0")
     public static <T> int findLastIndexOf(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        return findLastIndexOf(new ArrayIterator<>(self), 0, condition);
+        return ArrayGroovyMethods.findLastIndexOf(self, 0, condition);
     }
 
     @Deprecated(since = "5.0.0")
     public static <T> int findLastIndexOf(T[] self, int startIndex, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        // TODO could be made more efficient by using a reverse index
-        return findLastIndexOf(new ArrayIterator<>(self), startIndex, condition);
+        return ArrayGroovyMethods.findLastIndexOf(self, startIndex, condition);
     }
 
     @Deprecated(since = "5.0.0")


[groovy] 01/02: moving object array extensions

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit a401af9b0b7c4a8dfbdca80981acdbb0f14ade25
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed May 24 09:03:47 2023 -0500

    moving object array extensions
---
 .../groovy/runtime/ArrayGroovyMethods.java         | 1676 ++++++++++++++++-
 .../groovy/runtime/DefaultGroovyMethods.java       | 1984 ++++----------------
 2 files changed, 1993 insertions(+), 1667 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index 50b02b4b51..5f00f328f1 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -20,10 +20,12 @@ package org.codehaus.groovy.runtime;
 
 import groovy.lang.Closure;
 import groovy.lang.EmptyRange;
+import groovy.lang.GroovyRuntimeException;
 import groovy.lang.IntRange;
 import groovy.lang.MetaClass;
 import groovy.lang.ObjectRange;
 import groovy.lang.Range;
+import groovy.lang.SpreadMap;
 import groovy.transform.stc.ClosureParams;
 import groovy.transform.stc.FirstParam;
 import groovy.transform.stc.FromString;
@@ -56,19 +58,23 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
+import java.util.Random;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.function.Consumer;
 import java.util.function.DoubleConsumer;
 import java.util.function.DoubleUnaryOperator;
+import java.util.function.Function;
 import java.util.function.IntConsumer;
 import java.util.function.IntUnaryOperator;
 import java.util.function.LongConsumer;
@@ -784,18 +790,287 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return DefaultGroovyMethods.chop(new DoubleArrayIterator(self), chopSizes);
     }
 
+    /**
+     * Chops the array into pieces, returning lists with sizes corresponding to the supplied chop sizes.
+     * If the array isn't large enough, truncated (possibly empty) pieces are returned.
+     * Using a chop size of -1 will cause that piece to contain all remaining items from the array.
+     *
+     * @param self      an Array to be chopped
+     * @param chopSizes the sizes for the returned pieces
+     * @return a list of lists chopping the original array elements into pieces determined by chopSizes
+     * @see #collate(Object[], int) to chop a list into pieces of a fixed size
+     * @since 2.5.2
+     */
+    public static <T> List<List<T>> chop(T[] self, int... chopSizes) {
+        return DefaultGroovyMethods.chop(Arrays.asList(self), chopSizes);
+    }
+
     //--------------------------------------------------------------------------
     // collate
 
+    /**
+     * Collates an array.
+     *
+     * @param self          an array
+     * @param size          the length of each sub-list in the returned list
+     * @return a List containing the array values collated into sub-lists
+     * @see #collate(Iterable, int)
+     * @since 2.5.0
+     */
+    public static <T> List<List<T>> collate(T[] self, int size) {
+        return collate(self, size, true);
+    }
+
+    /**
+     * Collates an array into sub-lists.
+     *
+     * @param self          an array
+     * @param size          the length of each sub-list in the returned list
+     * @param step          the number of elements to step through for each sub-list
+     * @return a List containing the array elements collated into sub-lists
+     * @see #collate(Iterable, int, int)
+     * @since 2.5.0
+     */
+    public static <T> List<List<T>> collate(T[] self, int size, int step) {
+        return collate(self, size, step, true);
+    }
+
+    /**
+     * Collates this array into sub-lists.
+     *
+     * @param self          an array
+     * @param size          the length of each sub-list in the returned list
+     * @param keepRemainder if true, any remaining elements are returned as sub-lists.  Otherwise they are discarded
+     * @return a List containing the array elements collated into sub-lists
+     * @see #collate(Iterable, int, boolean)
+     * @since 2.5.0
+     */
+    public static <T> List<List<T>> collate(T[] self, int size, boolean keepRemainder) {
+        return collate(self, size, size, keepRemainder);
+    }
+
+    /**
+     * Collates this array into sub-lists.
+     *
+     * @param self          an array
+     * @param size          the length of each sub-list in the returned list
+     * @param step          the number of elements to step through for each sub-list
+     * @param keepRemainder if true, any remaining elements are returned as sub-lists.  Otherwise they are discarded
+     * @return a List containing the array elements collated into sub-lists
+     * @since 2.5.0
+     */
+    public static <T> List<List<T>> collate(T[] self, int size, int step, boolean keepRemainder) {
+        final List<List<T>> answer;
+        if (size <= 0) {
+            answer = new ArrayList<>(1);
+            answer.add(Arrays.asList(self));
+        } else {
+            if (step == 0) throw new IllegalArgumentException("step cannot be zero");
+            final int selfSize = self.length;
+            answer = new ArrayList<>(step < 0 ? 1 : (selfSize / step + 1));
+            for (int pos = 0; pos < selfSize && pos > -1; pos += step) {
+                if (!keepRemainder && pos > selfSize - size) {
+                    break;
+                }
+                List<T> element = new ArrayList<>(size);
+                for (int offs = pos; offs < pos + size && offs < selfSize; offs++) {
+                    element.add(self[offs]);
+                }
+                answer.add(element);
+            }
+        }
+        return answer;
+    }
+
     //--------------------------------------------------------------------------
     // collect
 
+    /**
+     * Iterates through this Array transforming each item into a new value using the
+     * <code>transform</code> closure, returning a list of transformed values.
+     *
+     * @param self      an array
+     * @param transform the closure used to transform each item of the Array
+     * @return A list of the transformed values.
+     * @since 2.5.0
+     */
+    public static <E, T> List<T> collect(E[] self, @ClosureParams(FirstParam.Component.class) Closure<T> transform) {
+        return DefaultGroovyMethods.collect(new ArrayIterator<>(self), transform);
+    }
+
+    /**
+     * Iterates through this Array transforming each item into a new value using the <code>transform</code> closure
+     * and adding it to the supplied <code>collector</code>.
+     * <pre class="groovyTestCase">
+     * Integer[] nums = [1,2,3]
+     * List<Integer> answer = []
+     * nums.collect(answer) { it * 2 }
+     * assert [2,4,6] == answer
+     * </pre>
+     *
+     * @param self      an array
+     * @param collector the Collection to which the transformed values are added
+     * @param transform the closure used to transform each item
+     * @return The collector with all transformed values added to it.
+     * @since 2.5.0
+     */
+    public static <E, T, C extends Collection<T>> C collect(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends T> transform) {
+        return DefaultGroovyMethods.collect(new ArrayIterator<>(self), collector, transform);
+    }
+
     //--------------------------------------------------------------------------
     // collectEntries
 
+    /**
+     * A variant of collectEntries using the identity closure as the transform.
+     *
+     * @param self      an array
+     * @return the collector with all transformed values added to it
+     * @see #collectEntries(Object[], Closure)
+     * @since 1.8.5
+     */
+    public static <K, V, E> Map<K, V> collectEntries(E[] self) {
+        return collectEntries(self, Closure.IDENTITY);
+    }
+
+    /**
+     * A variant of collectEntries using the identity closure as the transform.
+     *
+     * @param self      an array
+     * @param collector the Map into which the transformed entries are put
+     * @return the collector with all transformed values added to it
+     * @see #collectEntries(Object[], Map, Closure)
+     * @since 1.8.5
+     */
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector) {
+        return collectEntries(self, collector, Closure.IDENTITY);
+    }
+
+    /**
+     * Iterates through this array transforming each item using the <code>transform</code> closure
+     * and returning a map of the resulting transformed entries.
+     * <pre class="groovyTestCase">
+     * def letters = "abc"
+     * def nums = [0, 1, 2] as Integer[]
+     * // collect letters with index using list style
+     * assert nums.collectEntries { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
+     * // collect letters with index using map style
+     * assert nums.collectEntries { index {@code ->} [(index): letters[index]] } == [0:'a', 1:'b', 2:'c']
+     * </pre>
+     * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
+     * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
+     * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
+     *
+     * @param self      a Collection
+     * @param transform the closure used for transforming, which has an item from self as the parameter and
+     *                  should return a Map.Entry, a Map or a two-element list containing the resulting key and value
+     * @return a Map of the transformed entries
+     * @see #collectEntries(Iterator, Map, Closure)
+     * @since 1.7.9
+     */
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+        return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), transform);
+    }
+
+    /**
+     * Iterates through this array transforming each item using the <code>transform</code> closure
+     * and returning a map of the resulting transformed entries.
+     * <pre class="groovyTestCase">
+     * def letters = "abc"
+     * def nums = [0, 1, 2] as Integer[]
+     * // collect letters with index
+     * assert nums.collectEntries( [:] ) { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
+     * assert nums.collectEntries( [4:'d'] ) { index {@code ->}
+     *     [(index+1): letters[index]] } == [1:'a', 2:'b', 3:'c', 4:'d']
+     * </pre>
+     * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
+     * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
+     * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
+     * If your collector Map doesn't support null keys or values, you might get a runtime error, e.g. NullPointerException or IllegalArgumentException.
+     *
+     * @param self      an array
+     * @param collector the Map into which the transformed entries are put
+     * @param transform the closure used for transforming, which has an item from self as the parameter and
+     *                  should return a Map.Entry, a Map or a two-element list containing the resulting key and value
+     * @return the collector with all transformed values added to it
+     * @see #collect(Map, Collection, Closure)
+     * @since 1.7.9
+     */
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+        return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), collector, transform);
+    }
+
+    /**
+     * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
+     * <pre class="groovyTestCase">
+     * String[] languages = ['Groovy', 'Java', 'Kotlin', 'Scala']
+     * def firstLetter = s {@code ->} s[0]
+     * assert languages.collectEntries(firstLetter, String::size) == [G:6, J:4, K:6, S:5]
+     * </pre>
+     *
+     * @param self           an array
+     * @param keyTransform   a function for transforming array elements into keys
+     * @param valueTransform a function for transforming array elements into values
+     * @return a Map of the transformed entries
+     * @since 5.0.0
+     */
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
+        return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), keyTransform, valueTransform);
+    }
+
+    /**
+     * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
+     * The supplied collector map is used as the destination for transformed entries.
+     *
+     * @param self           an array
+     * @param collector      the Map into which the transformed entries are put
+     * @param keyTransform   a function for transforming array elements into keys
+     * @param valueTransform a function for transforming array elements into values
+     * @return the collector with all transformed values added to it
+     * @since 5.0.0
+     */
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
+        return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(self), collector, keyTransform, valueTransform);
+    }
+
     //--------------------------------------------------------------------------
     // collectMany
 
+    /**
+     * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
+     * <pre class="groovyTestCase">
+     * def nums = [1, 2, 3, 4, 5, 6] as Object[]
+     * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
+     * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
+     * </pre>
+     *
+     * @param self       an array
+     * @param projection a projecting Closure returning a collection of items
+     * @return A list created from the projected collections concatenated (flattened) together.
+     * @since 1.8.1
+     */
+    public static <T, E> List<T> collectMany(E[] self, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+        return collectMany(self, new ArrayList<>(), projection);
+    }
+
+    /**
+     * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
+     * <pre class="groovyTestCase">
+     * def nums = [1, 2, 3, 4, 5, 6] as Object[]
+     * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
+     * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
+     * </pre>
+     *
+     * @param self       an array
+     * @param collector  an initial collection to add the projected items to
+     * @param projection a projecting Closure returning a collection of items
+     * @return The collector with the projected collections concatenated (flattened) to it.
+     * @since 1.8.1
+     */
+    public static <T, E, C extends Collection<T>> C collectMany(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+        return DefaultGroovyMethods.collectMany(new ArrayIterable<>(self), collector, projection);
+    }
+
     //--------------------------------------------------------------------------
     // contains
 
@@ -927,6 +1202,22 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return false;
     }
 
+    /**
+     * Checks whether the array contains the given value.
+     *
+     * @param self  the array we are searching
+     * @param value the value being searched for
+     * @return true if the array contains the value
+     * @since 1.8.6
+     */
+    public static boolean contains(Object[] self, Object value) {
+        Objects.requireNonNull(self);
+        for (Object next : self) {
+            if (DefaultTypeTransformation.compareEqual(value, next)) return true;
+        }
+        return false;
+    }
+
     //--------------------------------------------------------------------------
     // count
 
@@ -1127,19 +1418,115 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see DefaultGroovyMethods#countBy(Iterator, Closure)
      * @since 1.8.0
      */
-    public static <K,E> Map<K, Integer> countBy(E[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
+    public static <K, E> Map<K, Integer> countBy(E[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
         return DefaultGroovyMethods.countBy(new ArrayIterator<>(self), closure);
     }
 
     //-------------------------------------------------------------------------
     // drop
 
+    /**
+     * Drops the given number of elements from the head of this array
+     * if they are available.
+     * <pre class="groovyTestCase">
+     * String[] strings = [ 'a', 'b', 'c' ]
+     * assert strings.drop( 0 ) == [ 'a', 'b', 'c' ] as String[]
+     * assert strings.drop( 2 ) == [ 'c' ] as String[]
+     * assert strings.drop( 5 ) == [] as String[]
+     * </pre>
+     *
+     * @param self the original array
+     * @param num  the number of elements to drop from this array
+     * @return An array consisting of all elements of this array except the
+     *         first <code>num</code> ones, or else the empty array, if this
+     *         array has less than <code>num</code> elements.
+     * @since 1.8.1
+     */
+    public static <T> T[] drop(T[] self, int num) {
+        if (self.length <= num) {
+            return createSimilarArray(self, 0);
+        }
+        if (num <= 0) {
+            T[] ret = createSimilarArray(self, self.length);
+            System.arraycopy(self, 0, ret, 0, self.length);
+            return ret;
+        }
+
+        T[] ret = createSimilarArray(self, self.length - num);
+        System.arraycopy(self, num, ret, 0, self.length - num);
+        return ret;
+    }
+
     //--------------------------------------------------------------------------
     // dropRight
 
+    /**
+     * Drops the given number of elements from the tail of this array
+     * if they are available.
+     * <pre class="groovyTestCase">
+     * String[] strings = [ 'a', 'b', 'c' ]
+     * assert strings.dropRight( 0 ) == [ 'a', 'b', 'c' ] as String[]
+     * assert strings.dropRight( 2 ) == [ 'a' ] as String[]
+     * assert strings.dropRight( 5 ) == [] as String[]
+     * </pre>
+     *
+     * @param self the original array
+     * @param num  the number of elements to drop from this array
+     * @return An array consisting of all elements of this array except the
+     *         last <code>num</code> ones, or else the empty array, if this
+     *         array has less than <code>num</code> elements.
+     * @since 2.4.0
+     */
+    public static <T> T[] dropRight(T[] self, int num) {
+        if (self.length <= num) {
+            return createSimilarArray(self, 0);
+        }
+        if (num <= 0) {
+            T[] ret = createSimilarArray(self, self.length);
+            System.arraycopy(self, 0, ret, 0, self.length);
+            return ret;
+        }
+
+        T[] ret = createSimilarArray(self, self.length - num);
+        System.arraycopy(self, 0, ret, 0, self.length - num);
+        return ret;
+    }
+
     //--------------------------------------------------------------------------
     // dropWhile
 
+    /**
+     * Create a suffix of the given array by dropping as many elements as possible from the
+     * front of the original array such that calling the given closure condition evaluates to
+     * true when passed each of the dropped elements.
+     * <pre class="groovyTestCase">
+     * def nums = [ 1, 3, 2 ] as Integer[]
+     * assert nums.dropWhile{ it {@code <=} 3 } == [ ] as Integer[]
+     * assert nums.dropWhile{ it {@code <} 3 } == [ 3, 2 ] as Integer[]
+     * assert nums.dropWhile{ it != 2 } == [ 2 ] as Integer[]
+     * assert nums.dropWhile{ it == 0 } == [ 1, 3, 2 ] as Integer[]
+     * </pre>
+     *
+     * @param self      the original array
+     * @param condition the closure that must evaluate to true to
+     *                  continue dropping elements
+     * @return The shortest suffix of the given array such that the given closure condition
+     *         evaluates to true for each element dropped from the front of the array.
+     * @since 1.8.7
+     */
+    public static <T> T[] dropWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+        int num = 0;
+        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+        while (num < self.length) {
+            if (bcw.call(self[num])) {
+                num += 1;
+            } else {
+                break;
+            }
+        }
+        return drop(self, num);
+    }
+
     //--------------------------------------------------------------------------
     // each
 
@@ -1625,7 +2012,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     // equals
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1645,7 +2032,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1665,7 +2052,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1685,7 +2072,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1705,7 +2092,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1725,7 +2112,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1745,7 +2132,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1765,7 +2152,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Compare the contents of this array to the contents of the given array.
+     * Compares the contents of this array to the contents of the given array.
      * <p>
      * Example usage:
      * <pre class="groovyTestCase">
@@ -1784,6 +2171,20 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return Arrays.equals(self, right);
     }
 
+    /**
+     * Determines if the contents of this array are equal to the
+     * contents of the given list, in the same order. This returns
+     * <code>false</code> if either collection is <code>null</code>.
+     *
+     * @param left  an array
+     * @param right the List being compared
+     * @return {@code true} if the contents of both collections are equal.
+     * @since 1.5.0
+     */
+    public static boolean equals(Object[] left, List<?> right) {
+        return DefaultGroovyMethods.equals(right, left);
+    }
+
     //--------------------------------------------------------------------------
     // every
 
@@ -2014,9 +2415,65 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // find
 
+    /**
+     * Finds the first element in the array that matches the given closure condition.
+     * Example:
+     * <pre class="groovyTestCase">
+     * def list = [1,2,3] as Integer[]
+     * assert 2 == list.find { it {@code >} 1 }
+     * assert null == list.find { it {@code >} 5 }
+     * </pre>
+     *
+     * @param self      an array
+     * @param condition a closure condition
+     * @return The first element from the array that matches the condition or null if no element matches.
+     * @since 2.0
+     */
+    public static <T> T find(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+        for (T element : self) {
+            if (bcw.call(element)) {
+                return element;
+            }
+        }
+        return null;
+    }
+
     //--------------------------------------------------------------------------
     // findAll
 
+    /**
+     * Finds the elements of the array matching the IDENTITY Closure (i.e.&#160;matching Groovy truth).
+     * <pre class="groovyTestCase">
+     * def items = [1, 2, 0, false, true, '', 'foo', [], [4, 5], null] as Object[]
+     * assert items.findAll() == [1, 2, true, 'foo', [4, 5]]
+     * </pre>
+     *
+     * @param self an array
+     * @return A list of the truthy values.
+     * @see Closure#IDENTITY
+     * @since 2.0
+     */
+    public static <T> List<T> findAll(T[] self) {
+        return findAll(self, Closure.IDENTITY);
+    }
+
+    /**
+     * Finds all elements of the array matching the given Closure condition.
+     * <pre class="groovyTestCase">
+     * def items = [1,2,3,4] as Integer[]
+     * assert [2,4] == items.findAll { it % 2 == 0 }
+     * </pre>
+     *
+     * @param self      an array
+     * @param condition a closure condition
+     * @return A list of the matching values.
+     * @since 2.0
+     */
+    public static <T> List<T> findAll(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+        return DefaultGroovyMethods.findMany(new ArrayList<>(), new ArrayIterator<>(self), condition);
+    }
+
     //--------------------------------------------------------------------------
     // findIndexOf
 
@@ -2114,9 +2571,85 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // findResult
 
+    /**
+     * Iterates through the Array stopping once the first non-null
+     * result is found and returning that result. If all results are null, null is returned.
+     *
+     * @param self an array
+     * @return The first non-null result from calling the closure, or null.
+     * @since 4.0.9
+     */
+    public static <T> T findResult(T[] self) {
+        return DefaultGroovyMethods.findResult(new ArrayIterator<>(self));
+    }
+
+    /**
+     * Iterates through the Array stopping once the first non-null
+     * result is found and returning that result. If all are null, the defaultResult is returned.
+     *
+     * @param self          an Array
+     * @param defaultResult an Object that should be returned if all elements are null
+     * @return the first non-null result from calling the closure, or the defaultValue
+     * @since 4.0.9
+     */
+    public static <T, U extends T, V extends T> T findResult(U[] self, V defaultResult) {
+        return DefaultGroovyMethods.findResult(new ArrayIterator<>(self), defaultResult);
+    }
+
+    /**
+     * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
+     * result is found and returning that result. If all results are null, null is returned.
+     *
+     * @param self      an array
+     * @param condition a closure that returns a non-null value to indicate that processing should stop and the value should be returned
+     * @return The first non-null result from calling the closure, or null.
+     * @since 2.5.0
+     */
+    public static <S, T> T findResult(S[] self, @ClosureParams(FirstParam.Component.class) Closure<T> condition) {
+        return DefaultGroovyMethods.findResult(new ArrayIterator<>(self), condition);
+    }
+
+    /**
+     * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
+     * result is found and returning that result. If all are null, the defaultResult is returned.
+     *
+     * @param self          an array
+     * @param defaultResult a value that should be returned if all closure results are null
+     * @param condition     a closure that returns a non-null value to indicate that processing should stop and the value should be returned
+     * @return The first non-null result from calling the closure, or the defaultValue.
+     * @since 2.5.0
+     */
+    public static <S, T, U extends T, V extends T> T findResult(S[] self, U defaultResult, @ClosureParams(FirstParam.Component.class) Closure<V> condition) {
+        return DefaultGroovyMethods.findResult(new ArrayIterator<>(self), defaultResult, condition);
+    }
+
     //--------------------------------------------------------------------------
     // findResults
 
+    /**
+     * Iterates through the Array collecting any non-null results.
+     *
+     * @param self an array
+     * @return The list of non-null values.
+     * @since 4.0.9
+     */
+    public static <T> Collection<T> findResults(T[] self) {
+        return DefaultGroovyMethods.findResults(new ArrayIterator<>(self));
+    }
+
+    /**
+     * Iterates through the Array transforming items using the supplied closure
+     * and collecting any non-null results.
+     *
+     * @param self               an array
+     * @param filteringTransform a closure that should return either a non-null transformed value or null for items which should be discarded
+     * @return The list of non-null transformed values.
+     * @since 2.5.0
+     */
+    public static <T, U> Collection<T> findResults(U[] self, @ClosureParams(FirstParam.Component.class) Closure<T> filteringTransform) {
+        return DefaultGroovyMethods.findResults(new ArrayIterator<>(self), filteringTransform);
+    }
+
     //--------------------------------------------------------------------------
     // first
 
@@ -2272,6 +2805,24 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return self[0];
     }
 
+    /**
+     * Returns the first item from the array.
+     * <pre class="groovyTestCase">
+     * def array = [3, 4, 2].toArray()
+     * assert array.first() == 3
+     * </pre>
+     *
+     * @param self an array
+     * @return the first item from the array
+     * @throws NoSuchElementException if the array is empty
+     * @since 1.7.3
+     */
+    public static <T> T first(T[] self) {
+        Objects.requireNonNull(self);
+        throwNoSuchElementIfEmpty(self.length, "first");
+        return self[0];
+    }
+
     //--------------------------------------------------------------------------
     // flatten
 
@@ -2411,6 +2962,19 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return toList(self);
     }
 
+    /**
+     * Flattens an array. This array and any nested arrays or
+     * collections have their contents (recursively) added to the new collection.
+     *
+     * @param self an Array to flatten
+     * @return S flattened Collection
+     * @since 1.6.0
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Object> flatten(Object[] self) {
+        return (List<Object>) DefaultGroovyMethods.flatten(Arrays.asList(self));
+    }
+
     //
 
     /**
@@ -2601,7 +3165,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     // getAt
 
     /**
-     * Support the subscript operator for a boolean array with a range giving the desired indices.
+     * Supports the subscript operator for a boolean array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * boolean[] array = [false, true, false, true, false, true]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2620,7 +3184,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a byte array with a range giving the desired indices.
+     * Supports the subscript operator for a byte array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * byte[] array = [1, 3, 5, 7, 9, 11]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2639,7 +3203,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a char array with a range giving the desired indices.
+     * Supports the subscript operator for a char array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * char[] array = 'abcdef'.chars
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2658,7 +3222,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a short array with a range giving the desired indices.
+     * Supports the subscript operator for a short array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * short[] array = [1, 3, 5, 7, 9, 11]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2677,7 +3241,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for an int array with a range giving the desired indices.
+     * Supports the subscript operator for an int array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * int[] array = [1, 3, 5, 7, 9, 11]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2696,7 +3260,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a long array with a range giving the desired indices.
+     * Supports the subscript operator for a long array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * long[] array = [1L, 3L, 5L, 7L, 9L, 11L]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2715,7 +3279,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a float array with a range giving the desired indices.
+     * Supports the subscript operator for a float array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * float[] array = [1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2734,7 +3298,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a double array with a range giving the desired indices.
+     * Supports the subscript operator for a double array with a range giving the desired indices.
      * <pre class="groovyTestCase">
      * double[] array = [1.0d, 3.0d, 5.0d, 7.0d, 9.0d, 11.0d]
      * assert array[2..&lt;2] == [] // EmptyRange
@@ -2753,7 +3317,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for an object array with a range giving the desired indices.
+     * Supports the subscript operator for an object array with a range giving the desired indices.
      *
      * @param array an Array of Objects
      * @param range a Range
@@ -2768,7 +3332,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //
 
     /**
-     * Support the subscript operator for a boolean array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a boolean array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * boolean[] array = [false, false, true, true, false]
      * assert array[2..3] == [true, true]
@@ -2789,7 +3353,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a byte array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a byte array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * byte[] array = [0, 10, 20, 30, 40]
      * assert array[2..3] == [20, 30]
@@ -2810,7 +3374,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a char array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a char array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * char[] array = 'abcdef'.chars
      * assert array[2..3] == ['c', 'd']
@@ -2831,7 +3395,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a short array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a short array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * short[] array = [0, 10, 20, 30, 40]
      * assert array[2..3] == [20, 30]
@@ -2852,7 +3416,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for an int array with an IntRange giving the desired indices.
+     * Supports the subscript operator for an int array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * int[] array = [0, 10, 20, 30, 40]
      * assert array[2..3] == [20, 30]
@@ -2873,7 +3437,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a long array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a long array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * long[] array = [0L, 10L, 20L, 30L, 40L]
      * assert array[2..3] == [20L, 30L]
@@ -2894,7 +3458,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a float array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a float array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * float[] array = [0.0f, 10.0f, 20.0f, 30.0f, 40.0f]
      * assert array[2..3] == [20.0f, 30.0f]
@@ -2915,7 +3479,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a double array with an IntRange giving the desired indices.
+     * Supports the subscript operator for a double array with an IntRange giving the desired indices.
      * <pre class="groovyTestCase">
      * double[] array = [0.0d, 10.0d, 20.0d, 30.0d, 40.0d]
      * assert array[2..3] == [20.0d, 30.0d]
@@ -2936,6 +3500,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Supports the subscript operator for an object array with an IntRange giving the desired indices.
      *
      * @param array an object array
      * @param range an IntRange
@@ -2950,7 +3515,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //
 
     /**
-     * Support the subscript operator for a boolean array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a boolean array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * boolean[] array = [false, false, true, true, false]
      * def range = new ObjectRange(2, 3)
@@ -2968,7 +3533,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a byte array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a byte array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * byte[] array = [0, 10, 20, 30, 40]
      * def range = new ObjectRange(2, 3)
@@ -2986,7 +3551,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a boolean array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a boolean array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * char[] array = 'abcdef'.chars
      * def range = new ObjectRange(2, 3)
@@ -3004,7 +3569,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a short array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a short array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * short[] array = [0, 10, 20, 30, 40]
      * def range = new ObjectRange(2, 3)
@@ -3022,7 +3587,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for an int array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for an int array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * int[] array = [0, 10, 20, 30, 40]
      * def range = new ObjectRange(2, 3)
@@ -3040,7 +3605,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a long array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a long array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * long[] array = [0L, 10L, 20L, 30L, 40L]
      * def range = new ObjectRange(2, 3)
@@ -3058,7 +3623,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a float array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a float array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * float[] array = [0.0f, 10.0f, 20.0f, 30.0f, 40.0f]
      * def range = new ObjectRange(2, 3)
@@ -3076,7 +3641,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a double array with an ObjectRange giving the desired indices.
+     * Supports the subscript operator for a double array with an ObjectRange giving the desired indices.
      * <pre class="groovyTestCase">
      * double[] array = [0.0d, 10.0d, 20.0d, 30.0d, 40.0d]
      * def range = new ObjectRange(2, 3)
@@ -3094,6 +3659,8 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Supports the subscript operator for an object array with an ObjectRange giving the desired indices.
+     *
      * @param array an Array of Objects
      * @param range an ObjectRange
      * @return a range of a list from the range's from index up to but not
@@ -3107,6 +3674,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //
 
     /**
+     * Supports the subscript operator for an object array with an EmptyRange.
      *
      * @param array an Array of Objects
      * @param range an EmptyRange
@@ -3120,7 +3688,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //
 
     /**
-     * Support the subscript operator for a boolean array
+     * Supports the subscript operator for a boolean array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * boolean[] array = [false, false, true, true, false]
@@ -3139,7 +3707,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a byte array
+     * Supports the subscript operator for a byte array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * byte[] array = [0, 2, 4, 6, 8]
@@ -3158,7 +3726,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a char array
+     * Supports the subscript operator for a char array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * char[] array = 'abcde'.chars
@@ -3177,7 +3745,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a short array
+     * Supports the subscript operator for a short array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * short[] array = [0, 2, 4, 6, 8]
@@ -3196,7 +3764,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for an int array
+     * Supports the subscript operator for an int array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * int[] array = [0, 2, 4, 6, 8]
@@ -3215,7 +3783,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a long array
+     * Supports the subscript operator for a long array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * long[] array = [0L, 2L, 4L, 6L, 8L]
@@ -3234,7 +3802,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a float array
+     * Supports the subscript operator for a float array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * float[] array = [0.0f, 2.0f, 4.0f, 6.0f, 8.0f]
@@ -3253,7 +3821,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Support the subscript operator for a double array
+     * Supports the subscript operator for a double array
      * with a (potentially nested) collection giving the desired indices.
      * <pre class="groovyTestCase">
      * double[] array = [0.0d, 2.0d, 4.0d, 6.0d, 8.0d]
@@ -3272,7 +3840,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Select a List of items from an array using a Collection to
+     * Selects a List of items from an array using a Collection to
      * identify the indices to be selected.
      *
      * @param array   an object array
@@ -3490,11 +4058,58 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // groupBy
 
-    //--------------------------------------------------------------------------
-    // head
-
     /**
-     * Returns the first item from the boolean array.
+     * Sorts all array members into groups determined by the supplied mapping closure.
+     * The closure should return the key that this item should be grouped by. The returned
+     * LinkedHashMap will have an entry for each distinct key returned from the closure,
+     * with each value being a list of items for that group.
+     * <p>
+     * Example usage:
+     * <pre class="groovyTestCase">
+     * Integer[] items = [1,2,3,4,5,6]
+     * assert [0:[2,4,6], 1:[1,3,5]] == items.groupBy { it % 2 }
+     * </pre>
+     *
+     * @param self    an array to group
+     * @param closure a closure mapping entries on keys
+     * @return A map grouped by keys.
+     * @since 2.2.0
+     */
+    public static <K, T> Map<K, List<T>> groupBy(T[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
+        return DefaultGroovyMethods.groupBy(Arrays.asList(self), closure);
+    }
+
+    /**
+     * Sorts all array members into (sub)groups determined by the supplied
+     * mapping closures as per the Iterable variant of this method.
+     *
+     * @param self     an array to group
+     * @param closures an array of closures, each mapping entries on keys
+     * @return A map grouped by keys on each criterion.
+     * @since 2.2.0
+     */
+    public static Map groupBy(Object[] self, Object... closures) {
+        return DefaultGroovyMethods.groupBy(new ArrayIterable<>(self), closures);
+    }
+
+    /**
+     * Sorts all array members into (sub)groups determined by the supplied
+     * mapping closures as per the list variant of this method.
+     *
+     * @param self     an array to group
+     * @param closures a list of closures, each mapping entries on keys
+     * @return A map grouped by keys on each criterion.
+     * @since 2.2.0
+     */
+    public static Map groupBy(Object[] self, List<Closure<?>> closures) {
+        return DefaultGroovyMethods.groupBy(new ArrayIterable<>(self), closures);
+    }
+
+    //--------------------------------------------------------------------------
+    // head
+
+    /**
+     * Returns the first item from the boolean array.
      * <pre class="groovyTestCase">
      * boolean[] array = [true, false]
      * assert array.head() == true
@@ -3645,6 +4260,22 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return self[0];
     }
 
+    /**
+     * Returns the first item from the Object array.
+     * <pre class="groovyTestCase">def array = [3, 4, 2].toArray()
+     * assert array.head() == 3</pre>
+     *
+     * @param self an array
+     * @return the first item from the Object array
+     * @throws NoSuchElementException if the array is empty
+     * @since 1.7.3
+     */
+    public static <T> T head(T[] self) {
+        Objects.requireNonNull(self);
+        throwNoSuchElementIfEmpty(self.length, "head");
+        return self[0];
+    }
+
     //--------------------------------------------------------------------------
     // indexed
 
@@ -3919,6 +4550,26 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return Arrays.copyOfRange(self, 0, self.length - 1);
     }
 
+    /**
+     * Returns the items from the Object array excluding the last item.
+     * <pre class="groovyTestCase">
+     *     String[] strings = ["a", "b", "c"]
+     *     def result = strings.init()
+     *     assert result.length == 2
+     *     assert strings.class.componentType == String
+     * </pre>
+     *
+     * @param self an array
+     * @return an array without its last element
+     * @throws UnsupportedOperationException if the array is empty
+     * @since 2.4.0
+     */
+    public static <T> T[] init(T[] self) {
+        Objects.requireNonNull(self);
+        throwNoSuchElementIfEmpty(self.length, "init");
+        return Arrays.copyOfRange(self, 0, self.length - 1);
+    }
+
     //--------------------------------------------------------------------------
     // inject
 
@@ -3934,7 +4585,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #inject(Object[], Object, Closure)
      * @since 1.8.7
      */
-    public static <E,T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
+    public static <E, T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
         return DefaultGroovyMethods.inject((Object) self, closure);
     }
 
@@ -3968,16 +4619,14 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     // iterator
 
     /**
-     * Attempts to create an Iterator for the given object by first
-     * converting it to a Collection.
+     * Returns an Iterator for the given array.
      *
      * @param self an array
      * @return an Iterator for the given Array.
-     * @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#asCollection(java.lang.Object[])
      * @since 1.6.4
      */
     public static <T> Iterator<T> iterator(final T[] self) {
-        return DefaultTypeTransformation.asCollection(self).iterator();
+        return Arrays.asList(self).iterator();
     }
 
     //--------------------------------------------------------------------------
@@ -4248,6 +4897,25 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return self[self.length - 1];
     }
 
+    /**
+     * Returns the last item from the array.
+     * <pre class="groovyTestCase">
+     * def array = [3, 4, 2].toArray()
+     * assert array.last() == 2
+     * </pre>
+     *
+     * @param self an array
+     * @return the last item from the array
+     * @throws NoSuchElementException if you try to access last() for an empty array
+     * @since 1.7.3
+     */
+    public static <T> T last(T[] self) {
+        if (self.length == 0) {
+            throw new NoSuchElementException("Cannot access last() element from an empty Array");
+        }
+        return self[self.length - 1];
+    }
+
     //--------------------------------------------------------------------------
     // max
 
@@ -5204,9 +5872,233 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // minus
 
+    /**
+     * Creates a new array composed of the elements of the first array minus the
+     * elements of the given Iterable.
+     * <pre class="groovyTestCase">
+     * Integer[] ints = [1, 2, 3, 1]
+     * List&lt;Integer> nope = [1, 3]
+     * def result = ints - nope
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{2}
+     *
+     * Integer[] none = []
+     * result = none - 123
+     * assert result !== none
+     * assert result.length == 0
+     * assert result.class == Integer[]
+     * </pre>
+     *
+     * @param self     an array
+     * @param removeMe an Iterable of elements to remove
+     * @return An array with the supplied elements removed.
+     * @since 1.5.5
+     */
+    public static <T> T[] minus(T[] self, Iterable<?> removeMe) {
+        Collection<T> temp = DefaultGroovyMethods.minus((Iterable<T>) toList(self), removeMe);
+        return temp.toArray(createSimilarArray(self, temp.size()));
+    }
+
+    /**
+     * Creates a new array composed of the elements of the first array minus the
+     * elements of the given array.
+     * <pre class="groovyTestCase">
+     * Integer[] ints = [1, 2, 3, 1]
+     * Integer[] nope = [1, 3]
+     * def result = ints - nope
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{2}
+     *
+     * Integer[] none = []
+     * result = none - 123
+     * assert result !== none
+     * assert result.length == 0
+     * assert result.class == Integer[]
+     * </pre>
+     *
+     * @param self     an array
+     * @param removeMe an array of elements to remove
+     * @return An array with the supplied elements removed.
+     * @since 1.5.5
+     */
+    public static <T> T[] minus(T[] self, Object[] removeMe) {
+        switch (removeMe.length) {
+          case 0:
+            return self.clone();
+          case 1:
+            return DefaultGroovyMethods.minus(self, removeMe[0]);
+          default:
+            Collection<T> temp = DefaultGroovyMethods.minus((Collection<T>) toList(self), Arrays.asList(removeMe));
+            return temp.toArray(createSimilarArray(self, temp.size()));
+        }
+    }
+
+    /**
+     * Creates a new array composed of the elements of the given array minus every occurrence the given object.
+     * <pre class="groovyTestCase">
+     * Integer[] ints = [1, 2, 3, 1]
+     * def result = ints - 1
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{2, 3}
+     *
+     * Integer[] none = []
+     * result = none - '1'
+     * assert result !== none
+     * assert result.length == 0
+     * assert result.class == Integer[]
+     * </pre>
+     *
+     * @param self     an array
+     * @param removeMe an element to remove from the array
+     * @return a new array with the operand removed
+     * @since 1.5.5
+     */
+    public static <T> T[] minus(T[] self, Object removeMe) {
+        int i = 0, n = self.length;
+        T[] result = createSimilarArray(self, n);
+        for (T t : self) {
+            if (!DefaultGroovyMethods.coercedEquals(t, removeMe)) {
+                result[i] = t;
+                i += 1;
+            }
+        }
+        if (i != n) {
+            result = Arrays.copyOfRange(result, 0, i);
+        }
+        return result;
+    }
+
     //--------------------------------------------------------------------------
     // plus
 
+    /**
+     * Creates an array containing elements from an original array plus those from a Collection.
+     * <pre class="groovyTestCase">
+     * Integer[] a = [1, 2, 3]
+     * def result = a + [4, 5, 6]
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
+     *
+     * Number[] c = [-1, 0.9, null]
+     * result = c + [1, 2, 3]
+     * assert result.class == Number[]
+     * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
+     *
+     * result = a + [-1, 0.9, null]
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{1, 2, 3, -1, 0, null}
+     *
+     * // improper type arguments; Date can't be coerced to Integer
+     * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + [new Date()] }
+     * </pre>
+     *
+     * @param left  the array
+     * @param right a Collection to be appended
+     * @return A new array containing left with right appended to it.
+     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+     * @since 1.8.7
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] plus(T[] left, Collection<?> right) {
+        T[] result = Arrays.copyOf(left, left.length + right.size());
+        int i = left.length;
+        Class<?> leftType = left.getClass().getComponentType();
+        for (Object t : right) {
+            result[i] = (T) DefaultTypeTransformation.castToType(t, leftType);
+            i += 1;
+        }
+        return result;
+    }
+
+    /**
+     * Creates an array containing elements from an original array plus those from an Iterable.
+     * <pre class="groovyTestCase">
+     * class AbcIterable implements Iterable<String> {
+     *     Iterator<String> iterator() { "abc".iterator() }
+     * }
+     * String[] array = ['x', 'y', 'z']
+     * def result = array + new AbcIterable()
+     * assert result.class == String[]
+     * assert result == new String[]{'x', 'y', 'z', 'a', 'b', 'c'}
+     * </pre>
+     *
+     * @param left  the array
+     * @param right an Iterable to be appended
+     * @return A new array containing elements from left with those from right appended.
+     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+     * @see #union(Object[], Iterable)
+     * @since 1.8.7
+     */
+    public static <T> T[] plus(T[] left, Iterable<?> right) {
+        return plus(left, DefaultGroovyMethods.toList(right));
+    }
+
+    /**
+     * Creates an array as a union of two arrays.
+     * <pre class="groovyTestCase">
+     * Integer[] a = [1, 2, 3]
+     * Integer[] b = [4, 5, 6]
+     * def result = a + b
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
+     *
+     * Number[] c = [-1, 0.9, null]
+     * result = c + a
+     * assert result.class == Number[]
+     * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
+     *
+     * result = a + c
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{1, 2, 3, -1, 0, null}
+     *
+     * Date[] d = [new Date()]
+     * // improper type arguments; Date can't be coerced to Integer
+     * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + d }
+     * </pre>
+     *
+     * @param left  the left Array
+     * @param right the right Array
+     * @return A new array containing right appended to left.
+     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+     * @since 1.8.7
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] plus(T[] left, Object[] right) {
+        T[] result = Arrays.copyOf(left, left.length + right.length);
+        T[] temp = (T[]) DefaultTypeTransformation.castToType(right, left.getClass());
+        System.arraycopy(temp, 0, result, left.length, temp.length);
+        return result;
+    }
+
+    /**
+     * Creates an array containing elements from an original array plus an additional appended element.
+     * <pre class="groovyTestCase">
+     * Integer[] a = [1, 2, 3]
+     * def result = a + 4
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{1, 2, 3, 4}
+     *
+     * result = a + 5.5d
+     * assert result.class == Integer[]
+     * assert result == new Integer[]{1, 2, 3, 5}
+     *
+     * // improper type arguments; Date can't be coerced to Integer
+     * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + new Date() }
+     * </pre>
+     *
+     * @param left  the array
+     * @param right the value to append
+     * @return A new array containing left with right appended to it.
+     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+     * @since 1.8.7
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] plus(T[] left, Object right) {
+        T[] result = Arrays.copyOf(left, left.length + 1);
+        result[left.length] = (T) DefaultTypeTransformation.castToType(right, left.getClass().getComponentType());
+        return result;
+    }
+
     //--------------------------------------------------------------------------
     // reverse
 
@@ -5227,7 +6119,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * boolean[] array = [false, true, true]
@@ -5271,7 +6163,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * byte[] array = 1..3
@@ -5315,7 +6207,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * char[] array = ['a', 'b', 'c']
@@ -5359,7 +6251,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * short[] array = 1..3
@@ -5403,7 +6295,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * int[] array = 1..3
@@ -5447,7 +6339,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * long[] array = 1L..3L
@@ -5491,7 +6383,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * float[] array = 1f..3f
@@ -5535,7 +6427,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
      * Otherwise, a new array containing the reversed items is produced.
      * <pre class="groovyTestCase">
      * double[] array = 1d..3d
@@ -5562,6 +6454,44 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return self;
     }
 
+    /**
+     * Creates a new array containing items which are the same as this array but in reverse order.
+     *
+     * @param self    an array
+     * @return An array containing the reversed items.
+     * @see #reverse(Object[], boolean)
+     * @since 1.5.5
+     */
+    public static <T> T[] reverse(T[] self) {
+        return reverse(self, false);
+    }
+
+    /**
+     * Reverses the items in an array. If mutate is true, the original array is modified in place and returned.
+     * Otherwise, a new array containing the reversed items is produced.
+     *
+     * <pre class="groovyTestCase">
+     * def array = new Object[] {1,2,3}
+     * def yarra = array.reverse(true)
+     * assert array == 3..1
+     * assert yarra == 3..1
+     *
+     * yarra = array.reverse(false)
+     * assert array == 3..1
+     * assert yarra == 1..3
+     * </pre>
+     *
+     * @param self   an array
+     * @param mutate {@code true} if the array itself should be reversed in place, {@code false} if a new array should be created
+     * @return An array containing the reversed items.
+     * @since 1.8.1
+     */
+    public static <T> T[] reverse(T[] self, boolean mutate) {
+        if (!mutate) self = self.clone();
+        Collections.reverse(Arrays.asList(self));
+        return self;
+    }
+
     //--------------------------------------------------------------------------
     // reverseEach
 
@@ -5742,7 +6672,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Iterate over each element of the array in the reverse order.
+     * Iterates over each element of the array in the reverse order.
      *
      * @param self    an array
      * @param closure a closure to which each item is passed
@@ -5760,14 +6690,105 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // shuffle
 
+    private static Random r;
+
+    /**
+     * Randomly reorders the elements of the specified array.
+     * <pre class="groovyTestCase">
+     * Integer[] array = [10, 5, 20]
+     * def origSize = array.size()
+     * def items = array.toList()
+     * array.shuffle()
+     * assert array.size() == origSize
+     * assert items.every{ array.contains(it) }
+     * </pre>
+     *
+     * @param self an array
+     * @since 3.0.0
+     */
+    public static <T> void shuffle(T[] self) {
+        Random rnd = r;
+        if (rnd == null)
+            r = rnd = new Random(); // harmless race.
+        shuffle(self, rnd);
+    }
+
+    /**
+     * Randomly reorders the elements of the specified array using the
+     * specified random instance as the source of randomness.
+     * <pre class="groovyTestCase">
+     * def r = new Random()
+     * Integer[] array = [10, 5, 20]
+     * def origSize = array.size()
+     * def items = array.toList()
+     * array.shuffle(r)
+     * assert array.size() == origSize
+     * assert items.every{ array.contains(it) }
+     * </pre>
+     *
+     * @param self an array
+     * @since 3.0.0
+     */
+    public static <T> void shuffle(T[] self, Random rnd) {
+        for (int i = 0; i < self.length-1; i++) {
+            int nextIndex = rnd.nextInt(self.length);
+            T tmp = self[i];
+            self[i] = self[nextIndex];
+            self[nextIndex] = tmp;
+        }
+    }
+
     //--------------------------------------------------------------------------
     // shuffled
 
+    /**
+     * Creates a new array containing the elements of the specified array but in a random order.
+     * <pre class="groovyTestCase">
+     * Integer[] orig = [10, 5, 20]
+     * def array = orig.shuffled()
+     * assert orig.size() == array.size()
+     * assert orig.every{ array.contains(it) }
+     * </pre>
+     *
+     * @param self an array
+     * @return the shuffled array
+     * @since 3.0.0
+     */
+    public static <T> T[] shuffled(T[] self) {
+        Random rnd = r;
+        if (rnd == null)
+            r = rnd = new Random(); // harmless race.
+        return shuffled(self, rnd);
+    }
+
+    /**
+     * Creates a new array containing the elements of the specified array but in a random
+     * order using the specified random instance as the source of randomness.
+     * <pre class="groovyTestCase">
+     * def r = new Random()
+     * Integer[] orig = [10, 5, 20]
+     * def array = orig.shuffled(r)
+     * assert orig.size() == array.size()
+     * assert orig.every{ array.contains(it) }
+     * </pre>
+     *
+     * @param self an array
+     * @return the shuffled array
+     * @since 3.0.0
+     */
+    public static <T> T[] shuffled(T[] self, Random rnd) {
+        T[] result = self.clone();
+        List<T> items = Arrays.asList(self);
+        Collections.shuffle(items, rnd);
+        System.arraycopy(items.toArray(), 0, result, 0, items.size());
+        return result;
+    }
+
     //--------------------------------------------------------------------------
     // size
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      * <pre class="groovyTestCase">
      * boolean[] array = [true, false, true]
      * assert array.size() == 3
@@ -5782,7 +6803,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self a byte array
      * @return the length of the array
@@ -5793,7 +6814,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self a char array
      * @return the length of the array
@@ -5804,7 +6825,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self a short array
      * @return the length of the array
@@ -5815,7 +6836,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self an int array
      * @return the length of the array
@@ -5826,7 +6847,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self a long array
      * @return the length of the array
@@ -5837,7 +6858,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self a float array
      * @return the length of the array
@@ -5848,7 +6869,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide arrays with a {@code size} method similar to collections.
+     * Provides arrays with a {@code size} method similar to collections.
      *
      * @param self a double array
      * @return the length of the array
@@ -5859,7 +6880,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Provide the standard Groovy <code>size()</code> method for an array.
+     * Provides the standard Groovy <code>size()</code> method for an array.
      *
      * @param self an object array
      * @return the length of the array
@@ -5872,9 +6893,150 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // sort
 
+    /**
+     * Modifies this array so that its elements are in sorted order.
+     * The array items are assumed to be comparable.
+     *
+     * @param self the array to be sorted
+     * @return the sorted array
+     * @since 1.5.5
+     */
+    public static <T> T[] sort(T[] self) {
+        Arrays.sort(self, new NumberAwareComparator<>());
+        return self;
+    }
+
+    /**
+     * Sorts the given array into sorted order.
+     * The array items are assumed to be comparable.
+     * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
+     * array is returned and the original array remains unchanged.
+     * <pre class="groovyTestCase">
+     * def orig = ["hello","hi","Hey"] as String[]
+     * def sorted = orig.sort(false)
+     * assert orig == ["hello","hi","Hey"] as String[]
+     * assert sorted == ["Hey","hello","hi"] as String[]
+     * orig.sort(true)
+     * assert orig == ["Hey","hello","hi"] as String[]
+     * </pre>
+     *
+     * @param self   the array to be sorted
+     * @param mutate false will always cause a new array to be created, true will mutate the array in place
+     * @return the sorted array
+     * @since 1.8.1
+     */
+    public static <T> T[] sort(T[] self, boolean mutate) {
+        T[] answer = mutate ? self : self.clone();
+        Arrays.sort(answer, new NumberAwareComparator<>());
+        return answer;
+    }
+
+    /**
+     * Sorts the given array into sorted order using the given comparator.
+     *
+     * @param self the array to be sorted
+     * @param comparator a Comparator used for the comparison
+     * @return the sorted array
+     * @since 1.5.5
+     */
+    public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
+        return sort(self, true, comparator);
+    }
+
+    /**
+     * Modifies this array so that its elements are in sorted order as determined by the given comparator.
+     * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
+     * array is returned and the original array remains unchanged.
+     * <pre class="groovyTestCase">
+     * def orig = ["hello","hi","Hey"] as String[]
+     * def sorted = orig.sort(false, String.CASE_INSENSITIVE_ORDER)
+     * assert orig == ["hello","hi","Hey"] as String[]
+     * assert sorted == ["hello","Hey","hi"] as String[]
+     * orig.sort(true, String.CASE_INSENSITIVE_ORDER)
+     * assert orig == ["hello","Hey","hi"] as String[]
+     * </pre>
+     *
+     * @param self       the array containing elements to be sorted
+     * @param mutate     false will always cause a new array to be created, true will mutate arrays in place
+     * @param comparator a Comparator used for the comparison
+     * @return a sorted array
+     * @since 1.8.1
+     */
+    public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) {
+        T[] answer = mutate ? self : self.clone();
+        Arrays.sort(answer, comparator);
+        return answer;
+    }
+
+    /**
+     * Sorts the elements from this array into a newly created array using
+     * the Closure to determine the correct ordering.
+     * <p>
+     * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
+     * its two parameters for order, returning a negative integer, zero, or a positive integer when the
+     * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
+     * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
+     * which is then used for further comparison.
+     *
+     * @param self the array containing the elements to be sorted
+     * @param closure a Closure used to determine the correct ordering
+     * @return the sorted array
+     * @since 1.5.5
+     */
+    public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        return sort(self, false, closure);
+    }
+
+    /**
+     * Modifies this array so that its elements are in sorted order using the Closure to determine the correct ordering.
+     * If mutate is false, a new array is returned and the original array remains unchanged.
+     * Otherwise, the original array is sorted in place and returned.
+     * <p>
+     * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
+     * its two parameters for order, returning a negative integer, zero, or a positive integer when the
+     * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
+     * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
+     * which is then used for further comparison.
+     * <pre class="groovyTestCase">
+     * def orig = ["hello","hi","Hey"] as String[]
+     * def sorted = orig.sort(false) { it.size() }
+     * assert orig == ["hello","hi","Hey"] as String[]
+     * assert sorted == ["hi","Hey","hello"] as String[]
+     * orig.sort(true) { it.size() }
+     * assert orig == ["hi","Hey","hello"] as String[]
+     * </pre>
+     *
+     * @param self    the array to be sorted
+     * @param mutate  false will always cause a new array to be created, true will mutate arrays in place
+     * @param closure a Closure used to determine the correct ordering
+     * @return the sorted array
+     * @since 1.8.1
+     */
+    public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        if (!mutate) self = self.clone();
+        Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
+        Arrays.sort(self, c);
+        return self;
+    }
+
     //--------------------------------------------------------------------------
     // split
 
+    /**
+     * Splits all items into two collections based on the closure condition.
+     * The first list contains all items which match the closure expression.
+     * The second list all those that don't.
+     *
+     * @param self    an Array
+     * @param closure a closure condition
+     * @return a List whose first item is the accepted values and whose second item is the rejected values
+     * @since 2.5.0
+     */
+    public static <T> Collection<Collection<T>> split(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> closure) {
+        List<T> accept = new ArrayList<>(), reject = new ArrayList<>();
+        return DefaultGroovyMethods.split(closure, accept, reject, new ArrayIterator<>(self));
+    }
+
     //--------------------------------------------------------------------------
     // sum
 
@@ -6507,17 +7669,128 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return Arrays.copyOfRange(self, 1, self.length);
     }
 
+    /**
+     * Returns the items from the array excluding the first item.
+     * <pre class="groovyTestCase">
+     * String[] strings = ["a", "b", "c"]
+     * def result = strings.tail()
+     * assert result.class.componentType == String
+     * String[] expected = ["b", "c"]
+     * assert result == expected
+     * </pre>
+     *
+     * @param self an array
+     * @return an array without its first element
+     * @throws UnsupportedOperationException if the array is empty
+     * @since 1.7.3
+     */
+    public static <T> T[] tail(T[] self) {
+        Objects.requireNonNull(self);
+        throwNoSuchElementIfEmpty(self.length, "tail");
+        return Arrays.copyOfRange(self, 1, self.length);
+    }
+
     //--------------------------------------------------------------------------
     // take
 
+    /**
+     * Returns the first <code>num</code> elements from the head of this array.
+     * <pre class="groovyTestCase">
+     * String[] strings = [ 'a', 'b', 'c' ]
+     * assert strings.take( 0 ) == [] as String[]
+     * assert strings.take( 2 ) == [ 'a', 'b' ] as String[]
+     * assert strings.take( 5 ) == [ 'a', 'b', 'c' ] as String[]
+     * </pre>
+     *
+     * @param self the original array
+     * @param num  the number of elements to take from this array
+     * @return an array consisting of the first <code>num</code> elements of this array,
+     *         or else the whole array if it has less than <code>num</code> elements.
+     * @since 1.8.1
+     */
+    public static <T> T[] take(T[] self, int num) {
+        if (self.length == 0 || num <= 0) {
+            return createSimilarArray(self, 0);
+        }
+
+        if (self.length <= num) {
+            T[] ret = createSimilarArray(self, self.length);
+            System.arraycopy(self, 0, ret, 0, self.length);
+            return ret;
+        }
+
+        T[] ret = createSimilarArray(self, num);
+        System.arraycopy(self, 0, ret, 0, num);
+        return ret;
+    }
+
     //--------------------------------------------------------------------------
     // takeRight
 
+    /**
+     * Returns the last <code>num</code> elements from the tail of this array.
+     * <pre class="groovyTestCase">
+     * String[] strings = [ 'a', 'b', 'c' ]
+     * assert strings.takeRight( 0 ) == [] as String[]
+     * assert strings.takeRight( 2 ) == [ 'b', 'c' ] as String[]
+     * assert strings.takeRight( 5 ) == [ 'a', 'b', 'c' ] as String[]
+     * </pre>
+     *
+     * @param self the original array
+     * @param num  the number of elements to take from this array
+     * @return an array consisting of the last <code>num</code> elements of this array,
+     *         or else the whole array if it has less than <code>num</code> elements.
+     * @since 2.4.0
+     */
+    public static <T> T[] takeRight(T[] self, int num) {
+        if (self.length == 0 || num <= 0) {
+            return createSimilarArray(self, 0);
+        }
+
+        if (self.length <= num) {
+            T[] ret = createSimilarArray(self, self.length);
+            System.arraycopy(self, 0, ret, 0, self.length);
+            return ret;
+        }
+
+        T[] ret = createSimilarArray(self, num);
+        System.arraycopy(self, self.length - num, ret, 0, num);
+        return ret;
+    }
+
     //--------------------------------------------------------------------------
     // takeWhile
 
-    //--------------------------------------------------------------------------
-    // toArrayString
+    /**
+     * Returns the longest prefix of this array where each element
+     * passed to the given closure evaluates to true.
+     * <pre class="groovyTestCase">
+     * def nums = [ 1, 3, 2 ] as Integer[]
+     * assert nums.takeWhile{ it {@code <} 1 } == [] as Integer[]
+     * assert nums.takeWhile{ it {@code <} 3 } == [ 1 ] as Integer[]
+     * assert nums.takeWhile{ it {@code <} 4 } == [ 1, 3, 2 ] as Integer[]
+     * </pre>
+     *
+     * @param self      the original array
+     * @param condition the closure that must evaluate to true to
+     *                  continue taking elements
+     * @return A prefix of the given array where each element passed to
+     *         the given closure evaluates to true.
+     * @since 1.8.7
+     */
+    public static <T> T[] takeWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+        int num = 0;
+        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
+        while (num < self.length) {
+            T value = self[num];
+            if (bcw.call(value)) {
+                num += 1;
+            } else {
+                break;
+            }
+        }
+        return take(self, num);
+    }
 
     //--------------------------------------------------------------------------
     // toList
@@ -6627,10 +7900,11 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Allows conversion of arrays into a mutable List.
+     * Converts this array to a List of the same size, with each element
+     * added to the list.
      *
      * @param self an object array
-     * @return A list containing the contents of this array.
+     * @return A mutable list containing the contents of this array.
      * @since 1.0
      */
     public static <T> List<T> toList(T[] self) {
@@ -6790,6 +8064,79 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // toSorted
 
+    /**
+     * Returns a sorted version of the given array using the supplied comparator.
+     *
+     * @param self the array to be sorted
+     * @return the sorted array
+     * @see #toSorted(Object[], Comparator)
+     * @since 2.4.0
+     */
+    public static <T> T[] toSorted(T[] self) {
+        return toSorted(self, new NumberAwareComparator<>());
+    }
+
+    /**
+     * Returns a sorted version of the given array using the supplied comparator to determine the resulting order.
+     * <pre class="groovyTestCase">
+     * def sumDigitsComparator = [compare: { num1, num2 {@code ->} num1.toString().toList()*.toInteger().sum() {@code <=>} num2.toString().toList()*.toInteger().sum() }] as Comparator
+     * Integer[] nums = [9, 44, 222, 7000]
+     * def result = nums.toSorted(sumDigitsComparator)
+     * assert result instanceof Integer[]
+     * assert result == [222, 7000, 44, 9]
+     * </pre>
+     *
+     * @param self the array to be sorted
+     * @param comparator a Comparator used for the comparison
+     * @return the sorted array
+     * @since 2.4.0
+     */
+    public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
+        T[] answer = self.clone();
+        Arrays.sort(answer, comparator);
+        return answer;
+    }
+
+    /**
+     * Sorts the elements from this array into a newly created array using
+     * the Closure to determine the correct ordering.
+     * <p>
+     * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
+     * its two parameters for order, returning a negative integer, zero, or a positive integer when the
+     * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
+     * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
+     * which is then used for further comparison.
+     *
+     * @param self the array containing the elements to be sorted
+     * @param closure a Closure used to determine the correct ordering
+     * @return a sorted array
+     * @see #toSorted(Object[], Comparator)
+     * @since 2.4.0
+     */
+    public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure<?> closure) {
+        return sort(self, false, closure);
+    }
+
+    //--------------------------------------------------------------------------
+    // toSpreadMap
+
+    /**
+     * Creates a spreadable map from this array.
+     * <p>
+     * @param self an object array
+     * @return a newly created SpreadMap
+     * @see groovy.lang.SpreadMap#SpreadMap(java.lang.Object[])
+     * @since 1.0
+     */
+    public static SpreadMap toSpreadMap(Object[] self) {
+        if (self == null)
+            throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because it is null.");
+        else if (self.length % 2 != 0)
+            throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because its size is not even.");
+        else
+            return new SpreadMap(self);
+    }
+
     //--------------------------------------------------------------------------
     // toString
 
@@ -6914,6 +8261,16 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return FormatHelper.toString(self);
     }
 
+    /**
+     * Returns the string representation of the given array.
+     *
+     * @param self an array
+     * @return the string representation
+     * @since 1.0
+     */
+    public static String toString(Object[] self) {
+        return FormatHelper.toArrayString(self);
+    }
 
     //--------------------------------------------------------------------------
     // toUnique
@@ -7202,20 +8559,163 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
     //--------------------------------------------------------------------------
     // union
 
+    /**
+     * Creates an object array containing elements from an original array plus those from a Collection.
+     * This is similar to {@link #plus(Object[], Collection)} but always return an Object array
+     * and so might be more applicable when adding heterogeneous arrays.
+     * <pre class="groovyTestCase">
+     * Integer[] a = [1, 2, 3]
+     * def result = a.union(['foo', 'bar'])
+     * assert result.class == Object[]
+     * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
+     * </pre>
+     *
+     * @param left  the array
+     * @param right a Collection to be appended
+     * @return A new Object array containing left with right appended to it.
+     * @since 4.0.0
+     */
+    public static Object[] union(Object[] left, Collection<?> right) {
+        Object[] result = new Object[left.length + right.size()];
+        System.arraycopy(left, 0, result, 0, left.length);
+        int i = left.length;
+        for (Object t : right) {
+            result[i] = t;
+            i += 1;
+        }
+        return result;
+    }
+
+    /**
+     * Creates an Object array containing elements from an original array plus those from an Iterable.
+     * This is similar to {@link #plus(Object[], Iterable)} but always return an Object array
+     * and so might be more applicable when adding heterogeneous arrays.
+     * <pre class="groovyTestCase">
+     * class AbcIterable implements Iterable<String> {
+     *     Iterator<String> iterator() { "abc".iterator() }
+     * }
+     * String[] array = ['x', 'y', 'z']
+     * def result = array.union(new AbcIterable())
+     * assert result.class == Object[]
+     * assert result == new Object[]{'x', 'y', 'z', 'a', 'b', 'c'}
+     * </pre>
+     *
+     * @param left  the array
+     * @param right an Iterable to be appended
+     * @return A new Object array containing elements from left with those from right appended.
+     * @since 4.0.0
+     */
+    public static Object[] union(Object[] left, Iterable<?> right) {
+        return union(left, DefaultGroovyMethods.toList(right));
+    }
+
+    /**
+     * Creates an Object array as a union of two arrays.
+     * This is similar to {@link #plus(Object[], Object[])} but always return an Object array
+     * and so might be more applicable when adding heterogeneous arrays.
+     * <pre class="groovyTestCase">
+     * Integer[] a = [1, 2, 3]
+     * String[] b = ['foo', 'bar']
+     * def result = a.union(b)
+     * assert result.class == Object[]
+     * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
+     * </pre>
+     *
+     * @param left  the left Array
+     * @param right the right Array
+     * @return A new Object array containing right appended to left.
+     * @since 4.0.0
+     */
+    public static Object[] union(Object[] left, Object[] right) {
+        Object[] result = new Object[left.length + right.length];
+        System.arraycopy(left, 0, result, 0, left.length);
+        System.arraycopy(right, 0, result, left.length, right.length);
+        return result;
+    }
+
+    /**
+     * Creates an Object array containing elements from an original array plus an additional appended element.
+     * This is similar to {@link #plus(Object[], Object)} but always return an Object array
+     * and so might be more applicable when adding heterogeneous arrays.
+     * <pre class="groovyTestCase">
+     * Integer[] a = [1, 2, 3]
+     * def result = a.union('foo')
+     * assert result.class == Object[]
+     * assert result == new Object[]{1, 2, 3, 'foo'}
+     * </pre>
+     *
+     * @param left  the array
+     * @param right the value to append
+     * @return A new Object array containing left with right appended to it.
+     * @since 4.0.0
+     */
+    public static Object[] union(Object[] left, Object right) {
+        Object[] result = new Object[left.length + 1];
+        System.arraycopy(left, 0, result, 0, left.length);
+        result[left.length] = right;
+        return result;
+    }
+
     //--------------------------------------------------------------------------
+    // withCollectedKeys
 
-    private static void throwNoSuchElementIfEmpty(final int size, final String method) {
-        if (size == 0) {
-            throw new NoSuchElementException("Cannot access " + method + "() for an empty array");
-        }
+    /**
+     * A variant of withCollectedKeys for arrays.
+     *
+     * @param values       an array
+     * @param keyTransform a function for transforming array elements into values
+     * @return the collector with all transformed values added to it
+     * @see #withCollectedKeys(Iterable, Function)
+     * @since 5.0.0
+     */
+    public static <K, V> Map<K, V> withCollectedKeys(V[] values, Function<? super V, K> keyTransform) {
+        return DefaultGroovyMethods.withCollectedKeys(new ArrayIterator<>(values), new LinkedHashMap<>(), keyTransform);
     }
 
-    private static void throwUnsupportedOperationIfEmpty(final int size, final String method) {
-        if (size == 0) {
-            throw new UnsupportedOperationException("Accessing " + method + "() is unsupported for an empty array");
-        }
+    /**
+     * A variant of withCollectedKeys for arrays.
+     *
+     * @param values       an array
+     * @param collector    the Map into which the transformed entries are put
+     * @param keyTransform a function for transforming array elements into values
+     * @return the collector with all transformed values added to it
+     * @see #withCollectedKeys(Iterable, Map, Function)
+     * @since 5.0.0
+     */
+    public static <K, V> Map<K, V> withCollectedKeys(V[] values, Map<K, V> collector, Function<? super V, K> keyTransform) {
+        return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(values), collector, keyTransform, Function.identity());
+    }
+
+    //--------------------------------------------------------------------------
+    // withCollectedValues
+
+    /**
+     * A variant of withCollectedValues for arrays.
+     *
+     * @param keys           an array
+     * @param valueTransform a function for transforming array elements into values
+     * @return A map of the transformed entries.
+     * @since 5.0.0
+     */
+    public static <K, V> Map<K, V> withCollectedValues(K[] keys, Function<? super K, V> valueTransform) {
+        return DefaultGroovyMethods.withCollectedValues(new ArrayIterator<>(keys), new LinkedHashMap<>(), valueTransform);
     }
 
+    /**
+     * A variant of withCollectedValues for arrays.
+     *
+     * @param keys           an array
+     * @param collector      the Map into which the transformed entries are put
+     * @param valueTransform a function for transforming array elements into values
+     * @return The collector with all transformed values added to it.
+     * @since 5.0.0
+     */
+    public static <K, V> Map<K, V> withCollectedValues(K[] keys, Map<K, V> collector, Function<? super K, V> valueTransform) {
+        return DefaultGroovyMethods.collectEntries(new ArrayIterator<>(keys), collector, Function.identity(), valueTransform);
+    }
+
+    //--------------------------------------------------------------------------
+
     /**
      * Implements the getAt(int) method for primitive type arrays.
      *
@@ -7271,4 +8771,16 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         }
         return answer;
     }
+
+    private static void throwNoSuchElementIfEmpty(final int size, final String method) {
+        if (size == 0) {
+            throw new NoSuchElementException("Cannot access " + method + "() for an empty array");
+        }
+    }
+
+    private static void throwUnsupportedOperationIfEmpty(final int size, final String method) {
+        if (size == 0) {
+            throw new UnsupportedOperationException("Accessing " + method + "() is unsupported for an empty array");
+        }
+    }
 }
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 82dc0202a3..ae42b8aab0 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -96,7 +96,6 @@ import org.codehaus.groovy.runtime.typehandling.GroovyCastException;
 import org.codehaus.groovy.runtime.typehandling.NumberMath;
 import org.codehaus.groovy.tools.RootLoader;
 import org.codehaus.groovy.transform.trait.Traits;
-import org.codehaus.groovy.util.ArrayIterable;
 import org.codehaus.groovy.util.ArrayIterator;
 import org.codehaus.groovy.util.IteratorBufferedIterator;
 import org.codehaus.groovy.util.ListBufferedIterator;
@@ -3025,19 +3024,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collate(self, size, true);
     }
 
-    /**
-     * Collates an array.
-     *
-     * @param self          an array
-     * @param size          the length of each sub-list in the returned list
-     * @return a List containing the array values collated into sub-lists
-     * @see #collate(Iterable, int)
-     * @since 2.5.0
-     */
-    public static <T> List<List<T>> collate(T[] self, int size) {
-        return collate(self, size, true);
-    }
-
     /**
      * Collates this iterable into sub-lists of length <code>size</code> stepping through the code <code>step</code>
      * elements for each subList.
@@ -3056,20 +3042,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collate(self, size, step, true);
     }
 
-    /**
-     * Collates an array into sub-lists.
-     *
-     * @param self          an array
-     * @param size          the length of each sub-list in the returned list
-     * @param step          the number of elements to step through for each sub-list
-     * @return a List containing the array elements collated into sub-lists
-     * @see #collate(Iterable, int, int)
-     * @since 2.5.0
-     */
-    public static <T> List<List<T>> collate(T[] self, int size, int step) {
-        return collate(self, size, step, true);
-    }
-
     /**
      * Collates this iterable into sub-lists of length <code>size</code>. Any remaining elements in
      * the iterable after the subdivision will be dropped if <code>keepRemainder</code> is false.
@@ -3088,20 +3060,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collate(self, size, size, keepRemainder);
     }
 
-    /**
-     * Collates this array into sub-lists.
-     *
-     * @param self          an array
-     * @param size          the length of each sub-list in the returned list
-     * @param keepRemainder if true, any remaining elements are returned as sub-lists.  Otherwise they are discarded
-     * @return a List containing the array elements collated into sub-lists
-     * @see #collate(Iterable, int, boolean)
-     * @since 2.5.0
-     */
-    public static <T> List<List<T>> collate(T[] self, int size, boolean keepRemainder) {
-        return collate(self, size, size, keepRemainder);
-    }
-
     /**
      * Collates this iterable into sub-lists of length <code>size</code> stepping through the code <code>step</code>
      * elements for each sub-list.  Any remaining elements in the iterable after the subdivision will be dropped if
@@ -3146,39 +3104,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return answer;
     }
 
-    /**
-     * Collates this array into sub-lists.
-     *
-     * @param self          an array
-     * @param size          the length of each sub-list in the returned list
-     * @param step          the number of elements to step through for each sub-list
-     * @param keepRemainder if true, any remaining elements are returned as sub-lists.  Otherwise they are discarded
-     * @return a List containing the array elements collated into sub-lists
-     * @since 2.5.0
-     */
-    public static <T> List<List<T>> collate(T[] self, int size, int step, boolean keepRemainder) {
-        final List<List<T>> answer;
-        if (size <= 0) {
-            answer = new ArrayList<>(1);
-            answer.add(Arrays.asList(self));
-        } else {
-            if (step == 0) throw new IllegalArgumentException("step cannot be zero");
-            final int selfSize = self.length;
-            answer = new ArrayList<>(step < 0 ? 1 : (selfSize / step + 1));
-            for (int pos = 0; pos < selfSize && pos > -1; pos += step) {
-                if (!keepRemainder && pos > selfSize - size) {
-                    break;
-                }
-                List<T> element = new ArrayList<>(size);
-                for (int offs = pos; offs < pos + size && offs < selfSize; offs++) {
-                    element.add(self[offs]);
-                }
-                answer.add(element);
-            }
-        }
-        return answer;
-    }
-
     /**
      * Iterates through this aggregate Object transforming each item into a new value using Closure.IDENTITY
      * as a transformer, basically returning a list of items copied from the original object.
@@ -3225,39 +3150,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collect(InvokerHelper.asIterator(self), collector, transform);
     }
 
-    /**
-     * Iterates through this Array transforming each item into a new value using the
-     * <code>transform</code> closure, returning a list of transformed values.
-     *
-     * @param self      an Array
-     * @param transform the closure used to transform each item of the Array
-     * @return a List of the transformed values
-     * @since 2.5.0
-     */
-    public static <E, T> List<T> collect(E[] self, @ClosureParams(FirstParam.Component.class) Closure<T> transform) {
-        return collect(new ArrayIterator<>(self), transform);
-    }
-
-    /**
-     * Iterates through this Array transforming each item into a new value using the <code>transform</code> closure
-     * and adding it to the supplied <code>collector</code>.
-     * <pre class="groovyTestCase">
-     * Integer[] nums = [1,2,3]
-     * List<Integer> answer = []
-     * nums.collect(answer) { it * 2 }
-     * assert [2,4,6] == answer
-     * </pre>
-     *
-     * @param self      an Array
-     * @param collector the Collection to which the transformed values are added
-     * @param transform the closure used to transform each item
-     * @return the collector with all transformed values added to it
-     * @since 2.5.0
-     */
-    public static <E, T, C extends Collection<T>> C collect(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends T> transform) {
-        return collect(new ArrayIterator<>(self), collector, transform);
-    }
-
     /**
      * Iterates through this Iterator transforming each item into a new value using the
      * <code>transform</code> closure, returning a list of transformed values.
@@ -3504,45 +3396,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collectMany(self, new ArrayList<>(), projection);
     }
 
-    /**
-     * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
-     * <p>
-     * <pre class="groovyTestCase">
-     * def nums = [1, 2, 3, 4, 5, 6] as Object[]
-     * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
-     * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
-     * </pre>
-     *
-     * @param self       an array
-     * @param projection a projecting Closure returning a collection of items
-     * @return a list created from the projected collections concatenated (flattened) together
-     * @see #sum(Object[], groovy.lang.Closure)
-     * @since 1.8.1
-     */
-    public static <T, E> List<T> collectMany(E[] self, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
-        return collectMany(self, new ArrayList<>(), projection);
-    }
-
-    /**
-     * Projects each item from a source array to a collection and concatenates (flattens) the resulting collections into a single list.
-     * <p>
-     * <pre class="groovyTestCase">
-     * def nums = [1, 2, 3, 4, 5, 6] as Object[]
-     * def squaresAndCubesOfEvens = nums.collectMany{ it % 2 ? [] : [it**2, it**3] }
-     * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
-     * </pre>
-     *
-     * @param self       an array
-     * @param collector  an initial collection to add the projected items to
-     * @param projection a projecting Closure returning a collection of items
-     * @return the collector with the projected collections concatenated (flattened) to it
-     * @see #sum(Object[], groovy.lang.Closure)
-     * @since 1.8.1
-     */
-    public static <T, E, C extends Collection<T>> C collectMany(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
-        return collectMany(new ArrayIterable<>(self), collector, projection);
-    }
-
     /**
      * Projects each item from a source iterator to a collection and concatenates (flattens) the resulting collections into a single list.
      * <p>
@@ -3832,39 +3685,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collectEntries(self.iterator(), new LinkedHashMap<>(), keyTransform, valueTransform);
     }
 
-    /**
-     * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
-     * The supplied collector map is used as the destination for transformed entries.
-     *
-     * @param self           an array
-     * @param collector      the Map into which the transformed entries are put
-     * @param keyTransform   a function for transforming array elements into keys
-     * @param valueTransform a function for transforming array elements into values
-     * @return the collector with all transformed values added to it
-     * @since 5.0.0
-     */
-    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
-        return collectEntries(new ArrayIterator<>(self), collector, keyTransform, valueTransform);
-    }
-
-    /**
-     * A variant of collectEntries for arrays with separate functions for transforming the keys and values.
-     * <pre class="groovyTestCase">
-     * String[] languages = ['Groovy', 'Java', 'Kotlin', 'Scala']
-     * def firstLetter = s {@code ->} s[0]
-     * assert languages.collectEntries(firstLetter, String::size) == [G:6, J:4, K:6, S:5]
-     * </pre>
-     *
-     * @param self           an array
-     * @param keyTransform   a function for transforming array elements into keys
-     * @param valueTransform a function for transforming array elements into values
-     * @return a Map of the transformed entries
-     * @since 5.0.0
-     */
-    public static <K, V, E> Map<K, V> collectEntries(E[] self, Function<? super E, K> keyTransform, Function<? super E, V> valueTransform) {
-        return collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), keyTransform, valueTransform);
-    }
-
     /**
      * A variant of collectEntries for Maps with separate functions for transforming the keys and values.
      * The supplied collector map is used as the destination for transformed entries.
@@ -3965,31 +3785,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return withCollectedValues(keys.iterator(), new LinkedHashMap<>(), valueTransform);
     }
 
-    /**
-     * A variant of withCollectedValues for arrays.
-     *
-     * @param keys           an array
-     * @param collector      the Map into which the transformed entries are put
-     * @param valueTransform a function for transforming array elements into values
-     * @return the collector with all transformed values added to it
-     * @since 5.0.0
-     */
-    public static <K, V> Map<K, V> withCollectedValues(K[] keys, Map<K, V> collector, Function<? super K, V> valueTransform) {
-        return collectEntries(new ArrayIterator<>(keys), collector, Function.identity(), valueTransform);
-    }
-
-    /**
-     * A variant of withCollectedValues for arrays.
-     *
-     * @param keys           an array
-     * @param valueTransform a function for transforming array elements into values
-     * @return a Map of the transformed entries
-     * @since 5.0.0
-     */
-    public static <K, V> Map<K, V> withCollectedValues(K[] keys, Function<? super K, V> valueTransform) {
-        return withCollectedValues(new ArrayIterator<>(keys), new LinkedHashMap<>(), valueTransform);
-    }
-
     /**
      * Transform a Maps' values leaving the keys unchanged.
      * Similar to {@link #withCollectedValues(Iterable, Map, Function)} but for Maps.
@@ -4102,33 +3897,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return withCollectedKeys(values.iterator(), new LinkedHashMap<>(), keyTransform);
     }
 
-    /**
-     * A variant of withCollectedKeys for arrays.
-     *
-     * @param values       an array
-     * @param collector    the Map into which the transformed entries are put
-     * @param keyTransform a function for transforming array elements into values
-     * @return the collector with all transformed values added to it
-     * @see #withCollectedKeys(Iterable, Map, Function)
-     * @since 5.0.0
-     */
-    public static <K, V> Map<K, V> withCollectedKeys(V[] values, Map<K, V> collector, Function<? super V, K> keyTransform) {
-        return collectEntries(new ArrayIterator<>(values), collector, keyTransform, Function.identity());
-    }
-
-    /**
-     * A variant of withCollectedKeys for arrays.
-     *
-     * @param values       an array
-     * @param keyTransform a function for transforming array elements into values
-     * @return the collector with all transformed values added to it
-     * @see #withCollectedKeys(Iterable, Function)
-     * @since 5.0.0
-     */
-    public static <K, V> Map<K, V> withCollectedKeys(V[] values, Function<? super V, K> keyTransform) {
-        return withCollectedKeys(new ArrayIterator<>(values), new LinkedHashMap<>(), keyTransform);
-    }
-
     /**
      * Transform a Maps' keys leaving the values unchanged.
      * Similar to {@link #withCollectedKeys(Iterable, Map, Function)} but for Maps.
@@ -4224,86 +3992,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return collectEntries(self.iterator(), collector);
     }
 
-    /**
-     * Iterates through this array transforming each item using the <code>transform</code> closure
-     * and returning a map of the resulting transformed entries.
-     * <pre class="groovyTestCase">
-     * def letters = "abc"
-     * def nums = [0, 1, 2] as Integer[]
-     * // collect letters with index
-     * assert nums.collectEntries( [:] ) { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
-     * assert nums.collectEntries( [4:'d'] ) { index {@code ->}
-     *     [(index+1): letters[index]] } == [1:'a', 2:'b', 3:'c', 4:'d']
-     * </pre>
-     * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
-     * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
-     * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
-     * If your collector Map doesn't support null keys or values, you might get a runtime error, e.g. NullPointerException or IllegalArgumentException.
-     *
-     * @param self      an array
-     * @param collector the Map into which the transformed entries are put
-     * @param transform the closure used for transforming, which has an item from self as the parameter and
-     *                  should return a Map.Entry, a Map or a two-element list containing the resulting key and value
-     * @return the collector with all transformed values added to it
-     * @see #collect(Map, Collection, Closure)
-     * @since 1.7.9
-     */
-    @SuppressWarnings("unchecked")
-    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
-        return collectEntries(new ArrayIterator<>(self), collector, transform);
-    }
-
-    /**
-     * A variant of collectEntries using the identity closure as the transform.
-     *
-     * @param self      an array
-     * @param collector the Map into which the transformed entries are put
-     * @return the collector with all transformed values added to it
-     * @see #collectEntries(Object[], Map, Closure)
-     * @since 1.8.5
-     */
-    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector) {
-        return collectEntries(self, collector, Closure.IDENTITY);
-    }
-
-    /**
-     * Iterates through this array transforming each item using the <code>transform</code> closure
-     * and returning a map of the resulting transformed entries.
-     * <pre class="groovyTestCase">
-     * def letters = "abc"
-     * def nums = [0, 1, 2] as Integer[]
-     * // collect letters with index using list style
-     * assert nums.collectEntries { index {@code ->} [index, letters[index]] } == [0:'a', 1:'b', 2:'c']
-     * // collect letters with index using map style
-     * assert nums.collectEntries { index {@code ->} [(index): letters[index]] } == [0:'a', 1:'b', 2:'c']
-     * </pre>
-     * Note: When using the list-style of result, the behavior is '<code>def (key, value) = listResultFromClosure</code>'.
-     * While we strongly discourage using a list of size other than 2, Groovy's normal semantics apply in this case;
-     * throwing away elements after the second one and using null for the key or value for the case of a shortened list.
-     *
-     * @param self      a Collection
-     * @param transform the closure used for transforming, which has an item from self as the parameter and
-     *                  should return a Map.Entry, a Map or a two-element list containing the resulting key and value
-     * @return a Map of the transformed entries
-     * @see #collectEntries(Iterator, Map, Closure)
-     * @since 1.7.9
-     */
-    public static <K, V, E> Map<K, V> collectEntries(E[] self, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
-        return collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), transform);
-    }
-
-    /**
-     * A variant of collectEntries using the identity closure as the transform.
-     *
-     * @param self      an array
-     * @return the collector with all transformed values added to it
-     * @see #collectEntries(Object[], Closure)
-     * @since 1.8.5
-     */
-    public static <K, V, E> Map<K, V> collectEntries(E[] self) {
-        return collectEntries(self, Closure.IDENTITY);
-    }
-
     @SuppressWarnings("unchecked")
     private static <K, V> void addEntry(Map<K, V> result, Object newEntry) {
         if (newEntry instanceof Map) {
@@ -4392,30 +4080,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return null;
     }
 
-    /**
-     * Finds the first element in the array that matches the given closure condition.
-     * Example:
-     * <pre class="groovyTestCase">
-     * def list = [1,2,3] as Integer[]
-     * assert 2 == list.find { it {@code >} 1 }
-     * assert null == list.find { it {@code >} 5 }
-     * </pre>
-     *
-     * @param self      an Array
-     * @param condition a closure condition
-     * @return the first element from the array that matches the condition or null if no element matches
-     * @since 2.0
-     */
-    public static <T> T find(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
-        for (T element : self) {
-            if (bcw.call(element)) {
-                return element;
-            }
-        }
-        return null;
-    }
-
     /**
      * Finds the first item matching the IDENTITY Closure (i.e.&#160;matching Groovy truth).
      * <p>
@@ -4672,71 +4336,19 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
-     * result is found and returning that result. If all are null, the defaultResult is returned.
+     * Returns the first non-null closure result found by passing each map entry to the closure, otherwise null is returned.
+     * If the closure takes two parameters, the entry key and value are passed.
+     * If the closure takes one parameter, the Map.Entry object is passed.
+     * <pre class="groovyTestCase">
+     * assert "Found b:3" == [a:1, b:3].findResult { if (it.value == 3) return "Found ${it.key}:${it.value}" }
+     * assert null == [a:1, b:3].findResult { if (it.value == 9) return "Found ${it.key}:${it.value}" }
+     * assert "Found a:1" == [a:1, b:3].findResult { k, v {@code ->} if (k.size() + v == 2) return "Found $k:$v" }
+     * </pre>
      *
-     * @param self          an Array
-     * @param defaultResult an Object that should be returned if all closure results are null
-     * @param condition     a closure that returns a non-null value to indicate that processing should stop and the value should be returned
-     * @return the first non-null result from calling the closure, or the defaultValue
-     * @since 2.5.0
-     */
-    public static <S, T, U extends T, V extends T> T findResult(S[] self, U defaultResult, @ClosureParams(FirstParam.Component.class) Closure<V> condition) {
-        return findResult(new ArrayIterator<>(self), defaultResult, condition);
-    }
-
-    /**
-     * Iterates through the Array stopping once the first non-null
-     * result is found and returning that result. If all are null, the defaultResult is returned.
-     *
-     * @param self          an Array
-     * @param defaultResult an Object that should be returned if all elements are null
-     * @return the first non-null result from calling the closure, or the defaultValue
-     * @since 4.0.9
-     */
-    public static <T, U extends T, V extends T> T findResult(U[] self, V defaultResult) {
-        return (T) findResult(new ArrayIterator<>(self), defaultResult, Closure.IDENTITY);
-    }
-
-    /**
-     * Iterates through the Array calling the given closure condition for each item but stopping once the first non-null
-     * result is found and returning that result. If all results are null, null is returned.
-     *
-     * @param self      an Array
-     * @param condition a closure that returns a non-null value to indicate that processing should stop and the value should be returned
-     * @return the first non-null result from calling the closure, or null
-     * @since 2.5.0
-     */
-    public static <S, T> T findResult(S[] self, @ClosureParams(FirstParam.Component.class) Closure<T> condition) {
-        return findResult(new ArrayIterator<>(self), condition);
-    }
-
-    /**
-     * Iterates through the Array stopping once the first non-null
-     * result is found and returning that result. If all results are null, null is returned.
-     *
-     * @param self      an Array
-     * @return the first non-null result from calling the closure, or null
-     * @since 4.0.9
-     */
-    public static <T> T findResult(T[] self) {
-        return (T) findResult(new ArrayIterator<>(self), Closure.IDENTITY);
-    }
-
-    /**
-     * Returns the first non-null closure result found by passing each map entry to the closure, otherwise null is returned.
-     * If the closure takes two parameters, the entry key and value are passed.
-     * If the closure takes one parameter, the Map.Entry object is passed.
-     * <pre class="groovyTestCase">
-     * assert "Found b:3" == [a:1, b:3].findResult { if (it.value == 3) return "Found ${it.key}:${it.value}" }
-     * assert null == [a:1, b:3].findResult { if (it.value == 9) return "Found ${it.key}:${it.value}" }
-     * assert "Found a:1" == [a:1, b:3].findResult { k, v {@code ->} if (k.size() + v == 2) return "Found $k:$v" }
-     * </pre>
-     *
-     * @param self      a Map
-     * @param condition a 1 or 2 arg Closure that returns a non-null value when processing should stop and a value should be returned
-     * @return the first non-null result collected by calling the closure, or null if no such result was found
-     * @since 1.7.5
+     * @param self      a Map
+     * @param condition a 1 or 2 arg Closure that returns a non-null value when processing should stop and a value should be returned
+     * @return the first non-null result collected by calling the closure, or null if no such result was found
+     * @since 1.7.5
      */
     public static <T, K, V> T findResult(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<T> condition) {
         for (Map.Entry<K, V> entry : self.entrySet()) {
@@ -4838,30 +4450,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return findResults(self, Closure.IDENTITY);
     }
 
-    /**
-     * Iterates through the Array transforming items using the supplied closure
-     * and collecting any non-null results.
-     *
-     * @param self               an Array
-     * @param filteringTransform a Closure that should return either a non-null transformed value or null for items which should be discarded
-     * @return the list of non-null transformed values
-     * @since 2.5.0
-     */
-    public static <T, U> Collection<T> findResults(U[] self, @ClosureParams(FirstParam.Component.class) Closure<T> filteringTransform) {
-        return findResults(new ArrayIterator<>(self), filteringTransform);
-    }
-
-    /**
-     * Iterates through the Array collecting any non-null results.
-     *
-     * @param self               an Array
-     * @return the list of non-null values
-     * @since 4.0.9
-     */
-    public static <T> Collection<T> findResults(T[] self) {
-        return findResults(self, Closure.IDENTITY);
-    }
-
     /**
      * Iterates through the map transforming items using the supplied closure
      * and collecting any non-null results.
@@ -4985,22 +4573,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return findMany(createSimilarCollection(self), self.iterator(), closure);
     }
 
-    /**
-     * Finds all elements of the array matching the given Closure condition.
-     * <pre class="groovyTestCase">
-     * def items = [1,2,3,4] as Integer[]
-     * assert [2,4] == items.findAll { it % 2 == 0 }
-     * </pre>
-     *
-     * @param self      an array
-     * @param condition a closure condition
-     * @return a list of matching values
-     * @since 2.0
-     */
-    public static <T> List<T> findAll(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        return findMany(new ArrayList<>(), new ArrayIterator<>(self), condition);
-    }
-
     /**
      * Finds the items matching the IDENTITY Closure (i.e.&#160;matching Groovy truth).
      * <p>
@@ -5055,24 +4627,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return findAll(self, Closure.IDENTITY);
     }
 
-    /**
-     * Finds the elements of the array matching the IDENTITY Closure (i.e.&#160;matching Groovy truth).
-     * <p>
-     * Example:
-     * <pre class="groovyTestCase">
-     * def items = [1, 2, 0, false, true, '', 'foo', [], [4, 5], null] as Object[]
-     * assert items.findAll() == [1, 2, true, 'foo', [4, 5]]
-     * </pre>
-     *
-     * @param self an array
-     * @return a List of the truthy values
-     * @see Closure#IDENTITY
-     * @since 2.0
-     */
-    public static <T> List<T> findAll(T[] self) {
-        return findAll(self, Closure.IDENTITY);
-    }
-
     /**
      * Finds all items matching the closure condition.
      *
@@ -5104,7 +4658,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return findAll(self, Closure.IDENTITY);
     }
 
-    private static <T, C extends Collection<T>> C findMany(C collector, Iterator<? extends T> iter, Closure<?> closure) {
+    static <T, C extends Collection<T>> C findMany(C collector, Iterator<? extends T> iter, Closure<?> closure) {
         BooleanClosureWrapper test = new BooleanClosureWrapper(closure);
         while (iter.hasNext()) {
             T value = iter.next();
@@ -5376,24 +4930,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return split(closure, accept, reject, iter);
     }
 
-    /**
-     * Splits all items into two collections based on the closure condition.
-     * The first list contains all items which match the closure expression.
-     * The second list all those that don't.
-     *
-     * @param self    an Array
-     * @param closure a closure condition
-     * @return a List whose first item is the accepted values and whose second item is the rejected values
-     * @since 2.5.0
-     */
-    public static <T> Collection<Collection<T>> split(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
-        List<T> accept = new ArrayList<>();
-        List<T> reject = new ArrayList<>();
-        Iterator<T> iter = new ArrayIterator<>(self);
-        return split(closure, accept, reject, iter);
-    }
-
-    private static <T> Collection<Collection<T>> split(Closure closure, Collection<T> accept, Collection<T> reject, Iterator<T> iter) {
+    static <T> Collection<Collection<T>> split(Closure closure, Collection<T> accept, Collection<T> reject, Iterator<T> iter) {
         List<Collection<T>> answer = new ArrayList<>();
         BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure);
         while (iter.hasNext()) {
@@ -5618,28 +5155,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return answer;
     }
 
-    /**
-     * Sorts all array members into groups determined by the supplied mapping closure.
-     * The closure should return the key that this item should be grouped by. The returned
-     * LinkedHashMap will have an entry for each distinct key returned from the closure,
-     * with each value being a list of items for that group.
-     * <p>
-     * Example usage:
-     * <pre class="groovyTestCase">
-     * Integer[] items = [1,2,3,4,5,6]
-     * assert [0:[2,4,6], 1:[1,3,5]] == items.groupBy { it % 2 }
-     * </pre>
-     *
-     * @param self    an array to group
-     * @param closure a closure mapping entries on keys
-     * @return a new Map grouped by keys
-     * @see #groupBy(Iterable, Closure)
-     * @since 2.2.0
-     */
-    public static <K, T> Map<K, List<T>> groupBy(T[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
-        return groupBy(Arrays.asList(self), closure);
-    }
-
     /**
      * Sorts all Iterable members into (sub)groups determined by the supplied
      * mapping closures. Each closure should return the key that this item
@@ -5690,21 +5205,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return acc;
     }
 
-    /**
-     * Sorts all array members into (sub)groups determined by the supplied
-     * mapping closures as per the Iterable variant of this method.
-     *
-     * @param self     an array to group
-     * @param closures an array of closures, each mapping entries on keys
-     * @return a new Map grouped by keys on each criterion
-     * @see #groupBy(Iterable, Object...)
-     * @see Closure#IDENTITY
-     * @since 2.2.0
-     */
-    public static Map groupBy(Object[] self, Object... closures) {
-        return groupBy(new ArrayIterable<>(self), closures);
-    }
-
     /**
      * Sorts all Iterable members into (sub)groups determined by the supplied
      * mapping closures. Each closure should return the key that this item
@@ -5743,21 +5243,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return groupBy(self, closures.toArray());
     }
 
-    /**
-     * Sorts all array members into (sub)groups determined by the supplied
-     * mapping closures as per the list variant of this method.
-     *
-     * @param self     an array to group
-     * @param closures a list of closures, each mapping entries on keys
-     * @return a new Map grouped by keys on each criterion
-     * @see Closure#IDENTITY
-     * @see #groupBy(Iterable, List)
-     * @since 2.2.0
-     */
-    public static Map groupBy(Object[] self, List<Closure> closures) {
-        return groupBy(new ArrayIterable<>(self), closures);
-    }
-
     /**
      * Sorts all collection members into groups determined by the supplied mapping
      * closure and counts the group size.  The closure should return the key that each
@@ -7823,24 +7308,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
             return new SpreadMap(self);
     }
 
-    /**
-     * Creates a spreadable map from this array.
-     * <p>
-     * @param self an object array
-     * @return a newly created SpreadMap
-     * @see groovy.lang.SpreadMap#SpreadMap(java.lang.Object[])
-     * @see #toSpreadMap(java.util.Map)
-     * @since 1.0
-     */
-    public static SpreadMap toSpreadMap(Object[] self) {
-        if (self == null)
-            throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because it is null.");
-        else if (self.length % 2 != 0)
-            throw new GroovyRuntimeException("Fail to convert Object[] to SpreadMap, because its size is not even.");
-        else
-            return new SpreadMap(self);
-    }
-
     /**
      * Creates a spreadable map from this list.
      * <p>
@@ -8360,44 +7827,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return new TreeMap<>(self);
     }
 
-    /**
-     * Modifies this array so that its elements are in sorted order.
-     * The array items are assumed to be comparable.
-     *
-     * @param self the array to be sorted
-     * @return the sorted array
-     * @since 1.5.5
-     */
-    public static <T> T[] sort(T[] self) {
-        Arrays.sort(self, new NumberAwareComparator<>());
-        return self;
-    }
-
-    /**
-     * Sorts the given array into sorted order.
-     * The array items are assumed to be comparable.
-     * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
-     * array is returned and the original array remains unchanged.
-     * <pre class="groovyTestCase">
-     * def orig = ["hello","hi","Hey"] as String[]
-     * def sorted = orig.sort(false)
-     * assert orig == ["hello","hi","Hey"] as String[]
-     * assert sorted == ["Hey","hello","hi"] as String[]
-     * orig.sort(true)
-     * assert orig == ["Hey","hello","hi"] as String[]
-     * </pre>
-     *
-     * @param self   the array to be sorted
-     * @param mutate false will always cause a new array to be created, true will mutate the array in place
-     * @return the sorted array
-     * @since 1.8.1
-     */
-    public static <T> T[] sort(T[] self, boolean mutate) {
-        T[] answer = mutate ? self : self.clone();
-        Arrays.sort(answer, new NumberAwareComparator<>());
-        return answer;
-    }
-
     /**
      * Sorts the given iterator items into a sorted iterator. The items are
      * assumed to be comparable. The original iterator will become
@@ -8452,43 +7881,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return list;
     }
 
-    /**
-     * Sorts the given array into sorted order using the given comparator.
-     *
-     * @param self the array to be sorted
-     * @param comparator a Comparator used for the comparison
-     * @return the sorted array
-     * @since 1.5.5
-     */
-    public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
-        return sort(self, true, comparator);
-    }
-
-    /**
-     * Modifies this array so that its elements are in sorted order as determined by the given comparator.
-     * If mutate is true, the array is sorted in place and returned. Otherwise, a new sorted
-     * array is returned and the original array remains unchanged.
-     * <pre class="groovyTestCase">
-     * def orig = ["hello","hi","Hey"] as String[]
-     * def sorted = orig.sort(false, String.CASE_INSENSITIVE_ORDER)
-     * assert orig == ["hello","hi","Hey"] as String[]
-     * assert sorted == ["hello","Hey","hi"] as String[]
-     * orig.sort(true, String.CASE_INSENSITIVE_ORDER)
-     * assert orig == ["hello","Hey","hi"] as String[]
-     * </pre>
-     *
-     * @param self       the array containing elements to be sorted
-     * @param mutate     false will always cause a new array to be created, true will mutate arrays in place
-     * @param comparator a Comparator used for the comparison
-     * @return a sorted array
-     * @since 1.8.1
-     */
-    public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) {
-        T[] answer = mutate ? self : self.clone();
-        Arrays.sort(answer, comparator);
-        return answer;
-    }
-
     /**
      * Sorts the given iterator items into a sorted iterator using the Closure to determine the correct ordering.
      * The original iterator will be fully processed after the method call.
@@ -8509,57 +7901,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return sort((Iterable<T>) toList(self), closure).listIterator();
     }
 
-    /**
-     * Sorts the elements from this array into a newly created array using
-     * the Closure to determine the correct ordering.
-     * <p>
-     * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
-     * its two parameters for order, returning a negative integer, zero, or a positive integer when the
-     * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
-     * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
-     * which is then used for further comparison.
-     *
-     * @param self the array containing the elements to be sorted
-     * @param closure a Closure used to determine the correct ordering
-     * @return the sorted array
-     * @since 1.5.5
-     */
-    public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return sort(self, false, closure);
-    }
-
-    /**
-     * Modifies this array so that its elements are in sorted order using the Closure to determine the correct ordering.
-     * If mutate is false, a new array is returned and the original array remains unchanged.
-     * Otherwise, the original array is sorted in place and returned.
-     * <p>
-     * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
-     * its two parameters for order, returning a negative integer, zero, or a positive integer when the
-     * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
-     * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
-     * which is then used for further comparison.
-     * <pre class="groovyTestCase">
-     * def orig = ["hello","hi","Hey"] as String[]
-     * def sorted = orig.sort(false) { it.size() }
-     * assert orig == ["hello","hi","Hey"] as String[]
-     * assert sorted == ["hi","Hey","hello"] as String[]
-     * orig.sort(true) { it.size() }
-     * assert orig == ["hi","Hey","hello"] as String[]
-     * </pre>
-     *
-     * @param self    the array to be sorted
-     * @param mutate  false will always cause a new array to be created, true will mutate arrays in place
-     * @param closure a Closure used to determine the correct ordering
-     * @return the sorted array
-     * @since 1.8.1
-     */
-    public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        if (!mutate) self = self.clone();
-        Comparator<T> c = closure.getMaximumNumberOfParameters() == 1 ? new OrderBy<>(closure) : new ClosureComparator<>(closure);
-        Arrays.sort(self, c);
-        return self;
-    }
-
     /**
      * Sorts this Iterable using the given Closure to determine the correct ordering. If the Iterable is a List,
      * it is sorted in place and returned. Otherwise, the elements are first placed
@@ -8771,59 +8112,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return toSorted(self, comparator);
     }
 
-    /**
-     * Returns a sorted version of the given array using the supplied comparator.
-     *
-     * @param self the array to be sorted
-     * @return the sorted array
-     * @see #toSorted(Object[], Comparator)
-     * @since 2.4.0
-     */
-    public static <T> T[] toSorted(T[] self) {
-        return toSorted(self, new NumberAwareComparator<>());
-    }
-
-    /**
-     * Returns a sorted version of the given array using the supplied comparator to determine the resulting order.
-     * <pre class="groovyTestCase">
-     * def sumDigitsComparator = [compare: { num1, num2 {@code ->} num1.toString().toList()*.toInteger().sum() {@code <=>} num2.toString().toList()*.toInteger().sum() }] as Comparator
-     * Integer[] nums = [9, 44, 222, 7000]
-     * def result = nums.toSorted(sumDigitsComparator)
-     * assert result instanceof Integer[]
-     * assert result == [222, 7000, 44, 9]
-     * </pre>
-     *
-     * @param self the array to be sorted
-     * @param comparator a Comparator used for the comparison
-     * @return the sorted array
-     * @since 2.4.0
-     */
-    public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
-        T[] answer = self.clone();
-        Arrays.sort(answer, comparator);
-        return answer;
-    }
-
-    /**
-     * Sorts the elements from this array into a newly created array using
-     * the Closure to determine the correct ordering.
-     * <p>
-     * If the closure has two parameters it is used like a traditional Comparator. I.e. it should compare
-     * its two parameters for order, returning a negative integer, zero, or a positive integer when the
-     * first parameter is less than, equal to, or greater than the second respectively. Otherwise,
-     * the Closure is assumed to take a single parameter and return a Comparable (typically an Integer)
-     * which is then used for further comparison.
-     *
-     * @param self the array containing the elements to be sorted
-     * @param closure a Closure used to determine the correct ordering
-     * @return a sorted array
-     * @see #toSorted(Object[], Comparator)
-     * @since 2.4.0
-     */
-    public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return sort(self, false, closure);
-    }
-
     /**
      * Sorts the elements from the given map into a new ordered map using
      * a {@link NumberAwareComparator} on map entry values to determine the resulting order.
@@ -9096,25 +8384,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return result;
     }
 
-    /**
-     * Returns the last item from the array.
-     * <pre class="groovyTestCase">
-     * def array = [3, 4, 2].toArray()
-     * assert array.last() == 2
-     * </pre>
-     *
-     * @param self an array
-     * @return the last item from the array
-     * @throws NoSuchElementException if you try to access last() for an empty array
-     * @since 1.7.3
-     */
-    public static <T> T last(T[] self) {
-        if (self.length == 0) {
-            throw new NoSuchElementException("Cannot access last() element from an empty Array");
-        }
-        return self[self.length - 1];
-    }
-
     /**
      * Returns the first item from the List.
      * <pre class="groovyTestCase">
@@ -9162,31 +8431,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Returns the first item from the array.
+     * Returns the first item from the Iterable.
      * <pre class="groovyTestCase">
-     * def array = [3, 4, 2].toArray()
-     * assert array.first() == 3
-     * </pre>
-     *
-     * @param self an array
-     * @return the first item from the array
-     * @throws NoSuchElementException if you try to access first() for an empty array
-     * @since 1.7.3
-     */
-    public static <T> T first(T[] self) {
-        if (self.length == 0) {
-            throw new NoSuchElementException("Cannot access first() element from an empty array");
-        }
-        return self[0];
-    }
-
-    /**
-     * Returns the first item from the Iterable.
-     * <pre class="groovyTestCase">
-     * def set = [3, 4, 2] as LinkedHashSet
-     * assert set.head() == 3
-     * // check original is unaltered
-     * assert set == [3, 4, 2] as Set
+     * def set = [3, 4, 2] as LinkedHashSet
+     * assert set.head() == 3
+     * // check original is unaltered
+     * assert set == [3, 4, 2] as Set
      * </pre>
      * The first element returned by the Iterable's iterator is returned.
      * If the Iterable doesn't guarantee a defined order it may appear like
@@ -9216,20 +8466,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return first(self);
     }
 
-    /**
-     * Returns the first item from the Object array.
-     * <pre class="groovyTestCase">def array = [3, 4, 2].toArray()
-     * assert array.head() == 3</pre>
-     *
-     * @param self an array
-     * @return the first item from the Object array
-     * @throws NoSuchElementException if you try to access head() for an empty array
-     * @since 1.7.3
-     */
-    public static <T> T head(T[] self) {
-        return first(self);
-    }
-
     /**
      * Returns the items from the List excluding the first item.
      * <pre class="groovyTestCase">
@@ -9300,28 +8536,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return result;
     }
 
-    /**
-     * Returns the items from the array excluding the first item.
-     * <pre class="groovyTestCase">
-     * String[] strings = ["a", "b", "c"]
-     * def result = strings.tail()
-     * assert result.class.componentType == String
-     * String[] expected = ["b", "c"]
-     * assert result == expected
-     * </pre>
-     *
-     * @param self an array
-     * @return an array without its first element
-     * @throws NoSuchElementException if you try to access tail() for an empty array
-     * @since 1.7.3
-     */
-    public static <T> T[] tail(T[] self) {
-        if (self.length == 0) {
-            throw new NoSuchElementException("Cannot access tail() for an empty array");
-        }
-        return Arrays.copyOfRange(self, 1, self.length);
-    }
-
     /**
      * Returns the original iterator after throwing away the first element.
      *
@@ -9469,27 +8683,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         }
     }
 
-    /**
-     * Returns the items from the Object array excluding the last item.
-     * <pre class="groovyTestCase">
-     *     String[] strings = ["a", "b", "c"]
-     *     def result = strings.init()
-     *     assert result.length == 2
-     *     assert strings.class.componentType == String
-     * </pre>
-     *
-     * @param self an array
-     * @return an array without its last element
-     * @throws NoSuchElementException if you try to access init() for an empty array
-     * @since 2.4.0
-     */
-    public static <T> T[] init(T[] self) {
-        if (self.length == 0) {
-            throw new NoSuchElementException("Cannot access init() for an empty Object array");
-        }
-        return Arrays.copyOfRange(self, 0, self.length - 1);
-    }
-
     /**
      * Returns the first <code>num</code> elements from the head of this List.
      * <pre class="groovyTestCase">
@@ -9528,37 +8721,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return (SortedSet<T>) take((Iterable<T>) self, num);
     }
 
-    /**
-     * Returns the first <code>num</code> elements from the head of this array.
-     * <pre class="groovyTestCase">
-     * String[] strings = [ 'a', 'b', 'c' ]
-     * assert strings.take( 0 ) == [] as String[]
-     * assert strings.take( 2 ) == [ 'a', 'b' ] as String[]
-     * assert strings.take( 5 ) == [ 'a', 'b', 'c' ] as String[]
-     * </pre>
-     *
-     * @param self the original array
-     * @param num  the number of elements to take from this array
-     * @return an array consisting of the first <code>num</code> elements of this array,
-     *         or else the whole array if it has less than <code>num</code> elements.
-     * @since 1.8.1
-     */
-    public static <T> T[] take(T[] self, int num) {
-        if (self.length == 0 || num <= 0) {
-            return createSimilarArray(self, 0);
-        }
-
-        if (self.length <= num) {
-            T[] ret = createSimilarArray(self, self.length);
-            System.arraycopy(self, 0, ret, 0, self.length);
-            return ret;
-        }
-
-        T[] ret = createSimilarArray(self, num);
-        System.arraycopy(self, 0, ret, 0, num);
-        return ret;
-    }
-
     /**
      * Returns the first <code>num</code> elements from the head of this Iterable.
      * <pre class="groovyTestCase">
@@ -9704,37 +8866,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         }
     }
 
-    /**
-     * Returns the last <code>num</code> elements from the tail of this array.
-     * <pre class="groovyTestCase">
-     * String[] strings = [ 'a', 'b', 'c' ]
-     * assert strings.takeRight( 0 ) == [] as String[]
-     * assert strings.takeRight( 2 ) == [ 'b', 'c' ] as String[]
-     * assert strings.takeRight( 5 ) == [ 'a', 'b', 'c' ] as String[]
-     * </pre>
-     *
-     * @param self the original array
-     * @param num  the number of elements to take from this array
-     * @return an array consisting of the last <code>num</code> elements of this array,
-     *         or else the whole array if it has less than <code>num</code> elements.
-     * @since 2.4.0
-     */
-    public static <T> T[] takeRight(T[] self, int num) {
-        if (self.length == 0 || num <= 0) {
-            return createSimilarArray(self, 0);
-        }
-
-        if (self.length <= num) {
-            T[] ret = createSimilarArray(self, self.length);
-            System.arraycopy(self, 0, ret, 0, self.length);
-            return ret;
-        }
-
-        T[] ret = createSimilarArray(self, num);
-        System.arraycopy(self, self.length - num, ret, 0, num);
-        return ret;
-    }
-
     /**
      * Returns the last <code>num</code> elements from the tail of this Iterable.
      * <pre class="groovyTestCase">
@@ -9880,38 +9011,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return result;
     }
 
-    /**
-     * Drops the given number of elements from the head of this array
-     * if they are available.
-     * <pre class="groovyTestCase">
-     * String[] strings = [ 'a', 'b', 'c' ]
-     * assert strings.drop( 0 ) == [ 'a', 'b', 'c' ] as String[]
-     * assert strings.drop( 2 ) == [ 'c' ] as String[]
-     * assert strings.drop( 5 ) == [] as String[]
-     * </pre>
-     *
-     * @param self the original array
-     * @param num  the number of elements to drop from this array
-     * @return an array consisting of all elements of this array except the
-     *         first <code>num</code> ones, or else the empty array, if this
-     *         array has less than <code>num</code> elements.
-     * @since 1.8.1
-     */
-    public static <T> T[] drop(T[] self, int num) {
-        if (self.length <= num) {
-            return createSimilarArray(self, 0);
-        }
-        if (num <= 0) {
-            T[] ret = createSimilarArray(self, self.length);
-            System.arraycopy(self, 0, ret, 0, self.length);
-            return ret;
-        }
-
-        T[] ret = createSimilarArray(self, self.length - num);
-        System.arraycopy(self, num, ret, 0, self.length - num);
-        return ret;
-    }
-
     /**
      * Drops the given number of key/value pairs from the head of this map if they are available.
      * <pre class="groovyTestCase">
@@ -10121,38 +9220,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         }
     }
 
-    /**
-     * Drops the given number of elements from the tail of this array
-     * if they are available.
-     * <pre class="groovyTestCase">
-     * String[] strings = [ 'a', 'b', 'c' ]
-     * assert strings.dropRight( 0 ) == [ 'a', 'b', 'c' ] as String[]
-     * assert strings.dropRight( 2 ) == [ 'a' ] as String[]
-     * assert strings.dropRight( 5 ) == [] as String[]
-     * </pre>
-     *
-     * @param self the original array
-     * @param num  the number of elements to drop from this array
-     * @return an array consisting of all elements of this array except the
-     *         last <code>num</code> ones, or else the empty array, if this
-     *         array has less than <code>num</code> elements.
-     * @since 2.4.0
-     */
-    public static <T> T[] dropRight(T[] self, int num) {
-        if (self.length <= num) {
-            return createSimilarArray(self, 0);
-        }
-        if (num <= 0) {
-            T[] ret = createSimilarArray(self, self.length);
-            System.arraycopy(self, 0, ret, 0, self.length);
-            return ret;
-        }
-
-        T[] ret = createSimilarArray(self, self.length - num);
-        System.arraycopy(self, 0, ret, 0, self.length - num);
-        return ret;
-    }
-
     /**
      * Returns the longest prefix of this list where each element
      * passed to the given closure condition evaluates to true.
@@ -10265,37 +9332,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ret;
     }
 
-    /**
-     * Returns the longest prefix of this array where each element
-     * passed to the given closure evaluates to true.
-     * <pre class="groovyTestCase">
-     * def nums = [ 1, 3, 2 ] as Integer[]
-     * assert nums.takeWhile{ it {@code <} 1 } == [] as Integer[]
-     * assert nums.takeWhile{ it {@code <} 3 } == [ 1 ] as Integer[]
-     * assert nums.takeWhile{ it {@code <} 4 } == [ 1, 3, 2 ] as Integer[]
-     * </pre>
-     *
-     * @param self      the original array
-     * @param condition the closure that must evaluate to true to
-     *                  continue taking elements
-     * @return a prefix of the given array where each element passed to
-     *         the given closure evaluates to true
-     * @since 1.8.7
-     */
-    public static <T> T[] takeWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
-        int num = 0;
-        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
-        while (num < self.length) {
-            T value = self[num];
-            if (bcw.call(value)) {
-                num += 1;
-            } else {
-                break;
-            }
-        }
-        return take(self, num);
-    }
-
     /**
      * Returns the longest prefix of elements in this iterator where
      * each element passed to the given condition closure evaluates to true.
@@ -10477,38 +9513,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ret;
     }
 
-    /**
-     * Create a suffix of the given array by dropping as many elements as possible from the
-     * front of the original array such that calling the given closure condition evaluates to
-     * true when passed each of the dropped elements.
-     * <pre class="groovyTestCase">
-     * def nums = [ 1, 3, 2 ] as Integer[]
-     * assert nums.dropWhile{ it {@code <=} 3 } == [ ] as Integer[]
-     * assert nums.dropWhile{ it {@code <} 3 } == [ 3, 2 ] as Integer[]
-     * assert nums.dropWhile{ it != 2 } == [ 2 ] as Integer[]
-     * assert nums.dropWhile{ it == 0 } == [ 1, 3, 2 ] as Integer[]
-     * </pre>
-     *
-     * @param self      the original array
-     * @param condition the closure that must evaluate to true to
-     *                  continue dropping elements
-     * @return the shortest suffix of the given array such that the given closure condition
-     *         evaluates to true for each element dropped from the front of the array
-     * @since 1.8.7
-     */
-    public static <T> T[] dropWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
-        int num = 0;
-        BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
-        while (num < self.length) {
-            if (bcw.call(self[num])) {
-                num += 1;
-            } else {
-                break;
-            }
-        }
-        return drop(self, num);
-    }
-
     /**
      * Creates an Iterator that returns a suffix of the elements from an original Iterator. As many elements
      * as possible are dropped from the front of the original Iterator such that calling the given closure
@@ -10996,97 +10000,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return copy;
     }
 
-    /**
-     * Randomly reorders the elements of the specified array.
-     * <pre class="groovyTestCase">
-     * Integer[] array = [10, 5, 20]
-     * def origSize = array.size()
-     * def items = array.toList()
-     * array.shuffle()
-     * assert array.size() == origSize
-     * assert items.every{ array.contains(it) }
-     * </pre>
-     *
-     * @param self an array
-     * @since 3.0.0
-     */
-    public static <T> void shuffle(T[] self) {
-        Random rnd = r;
-        if (rnd == null)
-            r = rnd = new Random(); // harmless race.
-        shuffle(self, rnd);
-    }
-
-    private static Random r;
-
-    /**
-     * Randomly reorders the elements of the specified array using the
-     * specified random instance as the source of randomness.
-     * <pre class="groovyTestCase">
-     * def r = new Random()
-     * Integer[] array = [10, 5, 20]
-     * def origSize = array.size()
-     * def items = array.toList()
-     * array.shuffle(r)
-     * assert array.size() == origSize
-     * assert items.every{ array.contains(it) }
-     * </pre>
-     *
-     * @param self an array
-     * @since 3.0.0
-     */
-    public static <T> void shuffle(T[] self, Random rnd) {
-        for (int i = 0; i < self.length-1; i++) {
-            int nextIndex = rnd.nextInt(self.length);
-            T tmp = self[i];
-            self[i] = self[nextIndex];
-            self[nextIndex] = tmp;
-        }
-    }
-
-    /**
-     * Creates a new array containing the elements of the specified array but in a random order.
-     * <pre class="groovyTestCase">
-     * Integer[] orig = [10, 5, 20]
-     * def array = orig.shuffled()
-     * assert orig.size() == array.size()
-     * assert orig.every{ array.contains(it) }
-     * </pre>
-     *
-     * @param self an array
-     * @return the shuffled array
-     * @since 3.0.0
-     */
-    public static <T> T[] shuffled(T[] self) {
-        Random rnd = r;
-        if (rnd == null)
-            r = rnd = new Random(); // harmless race.
-        return shuffled(self, rnd);
-    }
-
-    /**
-     * Creates a new array containing the elements of the specified array but in a random
-     * order using the specified random instance as the source of randomness.
-     * <pre class="groovyTestCase">
-     * def r = new Random()
-     * Integer[] orig = [10, 5, 20]
-     * def array = orig.shuffled(r)
-     * assert orig.size() == array.size()
-     * assert orig.every{ array.contains(it) }
-     * </pre>
-     *
-     * @param self an array
-     * @return the shuffled array
-     * @since 3.0.0
-     */
-    public static <T> T[] shuffled(T[] self, Random rnd) {
-        T[] result = self.clone();
-        List<T> items = Arrays.asList(self);
-        Collections.shuffle(items, rnd);
-        System.arraycopy(items.toArray(), 0, result, 0, items.size());
-        return result;
-    }
-
     /**
      * Creates a view list with reversed order, and the order of original list will not change.
      * <pre class="groovyTestCase">
@@ -11168,45 +10081,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return answer;
     }
 
-    /**
-     * Creates a new array containing items which are the same as this array but in reverse order.
-     *
-     * @param self    an array
-     * @return an array containing the reversed items
-     * @see #reverse(Object[], boolean)
-     * @since 1.5.5
-     */
-    public static <T> T[] reverse(T[] self) {
-        return reverse(self, false);
-    }
-
-    /**
-     * Reverse the items in an array. If mutate is true, the original array is modified in place and returned.
-     * Otherwise, a new array containing the reversed items is produced.
-     *
-     * <pre class="groovyTestCase">
-     * def array = new Object[] {1,2,3}
-     * def yarra = array.reverse(true)
-     * assert array == 3..1
-     * assert yarra == 3..1
-     *
-     * yarra = array.reverse(false)
-     * assert array == 3..1
-     * assert yarra == 1..3
-     * </pre>
-     *
-     * @param self   an array
-     * @param mutate {@code true} if the array itself should be reversed in place, {@code false} if a new array should be created
-     * @return an array containing the reversed items
-     *
-     * @since 1.8.1
-     */
-    public static <T> T[] reverse(T[] self, boolean mutate) {
-        if (!mutate) self = self.clone();
-        Collections.reverse(Arrays.asList(self));
-        return self;
-    }
-
     /**
      * Reverses the iterator. The original iterator will become
      * exhausted of elements after determining the reversed values.
@@ -11221,278 +10095,53 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Create an array as a union of two arrays.
-     * <pre class="groovyTestCase">
-     * Integer[] a = [1, 2, 3]
-     * Integer[] b = [4, 5, 6]
-     * def result = a + b
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
-     *
-     * Number[] c = [-1, 0.9, null]
-     * result = c + a
-     * assert result.class == Number[]
-     * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
-     *
-     * result = a + c
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{1, 2, 3, -1, 0, null}
-     *
-     * Date[] d = [new Date()]
-     * // improper type arguments; Date can't be coerced to Integer
-     * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + d }
-     * </pre>
+     * Create a Collection as a union of two collections. If the left collection
+     * is a Set, then the returned collection will be a Set otherwise a List.
+     * This operation will always create a new object for the result,
+     * while the operands remain unchanged.
+     * <pre class="groovyTestCase">assert [1,2,3,4] == [1,2] + [3,4]</pre>
      *
-     * @param left  the left Array
-     * @param right the right Array
-     * @return A new array containing right appended to left.
-     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
-     * @since 1.8.7
+     * @param left  the left Collection
+     * @param right the right Collection
+     * @return the merged Collection
+     * @since 1.5.0
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T[] plus(final T[] left, final Object[] right) {
-        T[] result = Arrays.copyOf(left, left.length + right.length);
-        T[] temp = (T[]) DefaultTypeTransformation.castToType(right, left.getClass());
-        System.arraycopy(temp, 0, result, left.length, temp.length);
-        return result;
+    public static <T> Collection<T> plus(Collection<T> left, Collection<T> right) {
+        final Collection<T> answer = cloneSimilarCollection(left, left.size() + right.size());
+        answer.addAll(right);
+        return answer;
     }
 
     /**
-     * Create an array containing elements from an original array plus an additional appended element.
-     * <pre class="groovyTestCase">
-     * Integer[] a = [1, 2, 3]
-     * def result = a + 4
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{1, 2, 3, 4}
-     *
-     * result = a + 5.5d
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{1, 2, 3, 5}
-     *
-     * // improper type arguments; Date can't be coerced to Integer
-     * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + new Date() }
-     * </pre>
+     * Create a Collection as a union of two iterables. If the left iterable
+     * is a Set, then the returned collection will be a Set otherwise a List.
+     * This operation will always create a new object for the result,
+     * while the operands remain unchanged.
+     * <pre class="groovyTestCase">assert [1,2,3,4] == [1,2] + [3,4]</pre>
      *
-     * @param left  the array
-     * @param right the value to append
-     * @return A new array containing left with right appended to it.
-     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
-     * @since 1.8.7
+     * @param left  the left Iterable
+     * @param right the right Iterable
+     * @return the merged Collection
+     * @since 2.4.0
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T[] plus(final T[] left, final Object right) {
-        T[] result = Arrays.copyOf(left, left.length + 1);
-        result[left.length] = (T) DefaultTypeTransformation.castToType(right, left.getClass().getComponentType());
-        return result;
+    public static <T> Collection<T> plus(Iterable<T> left, Iterable<T> right) {
+        return plus(asCollection(left), asCollection(right));
     }
 
     /**
-     * Create an array containing elements from an original array plus those from a Collection.
-     * <pre class="groovyTestCase">
-     * Integer[] a = [1, 2, 3]
-     * def result = a + [4, 5, 6]
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{1, 2, 3, 4, 5, 6}
-     *
-     * Number[] c = [-1, 0.9, null]
-     * result = c + [1, 2, 3]
-     * assert result.class == Number[]
-     * assert result == new Number[]{-1, 0.9, null, 1, 2, 3}
-     *
-     * result = a + [-1, 0.9, null]
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{1, 2, 3, -1, 0, null}
-     *
-     * // improper type arguments; Date can't be coerced to Integer
-     * groovy.test.GroovyAssert.shouldFail(ClassCastException) { a + [new Date()] }
-     * </pre>
+     * Create a Collection as a union of a Collection and an Iterable. If the left collection
+     * is a Set, then the returned collection will be a Set otherwise a List.
+     * This operation will always create a new object for the result,
+     * while the operands remain unchanged.
      *
-     * @param left  the array
-     * @param right a Collection to be appended
-     * @return A new array containing left with right appended to it.
-     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
+     * @param left  the left Collection
+     * @param right the right Iterable
+     * @return the merged Collection
      * @since 1.8.7
+     * @see #plus(Collection, Collection)
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T[] plus(final T[] left, final Collection<?> right) {
-        T[] result = Arrays.copyOf(left, left.length + right.size());
-        int i = left.length;
-        Class<?> leftType = left.getClass().getComponentType();
-        for (Object t : right) {
-            result[i] = (T) DefaultTypeTransformation.castToType(t, leftType);
-            i += 1;
-        }
-        return result;
-    }
-
-    /**
-     * Create an array containing elements from an original array plus those from an Iterable.
-     * <pre class="groovyTestCase">
-     * class AbcIterable implements Iterable<String> {
-     *     Iterator<String> iterator() { "abc".iterator() }
-     * }
-     * String[] array = ['x', 'y', 'z']
-     * def result = array + new AbcIterable()
-     * assert result.class == String[]
-     * assert result == new String[]{'x', 'y', 'z', 'a', 'b', 'c'}
-     * </pre>
-     *
-     * @param left  the array
-     * @param right an Iterable to be appended
-     * @return A new array containing elements from left with those from right appended.
-     * @throws ClassCastException if any elements from right aren't compatible (according to {@link DefaultTypeTransformation#castToType(Object, Class)}) to the component type of left
-     * @see #union(Object[], Iterable)
-     * @since 1.8.7
-     */
-    public static <T> T[] plus(final T[] left, final Iterable<?> right) {
-        return plus(left, toList(right));
-    }
-
-    /**
-     * Create an Object array as a union of two arrays.
-     * This is similar to {@link #plus(Object[], Object[])} but always return an Object array
-     * and so might be more applicable when adding heterogeneous arrays.
-     * <pre class="groovyTestCase">
-     * Integer[] a = [1, 2, 3]
-     * String[] b = ['foo', 'bar']
-     * def result = a.union(b)
-     * assert result.class == Object[]
-     * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
-     * </pre>
-     *
-     * @param left  the left Array
-     * @param right the right Array
-     * @return A new Object array containing right appended to left.
-     * @since 4.0.0
-     */
-    public static Object[] union(final Object[] left, final Object[] right) {
-        Object[] result = new Object[left.length + right.length];
-        System.arraycopy(left, 0, result, 0, left.length);
-        System.arraycopy(right, 0, result, left.length, right.length);
-        return result;
-    }
-
-    /**
-     * Create an Object array containing elements from an original array plus an additional appended element.
-     * This is similar to {@link #plus(Object[], Object)} but always return an Object array
-     * and so might be more applicable when adding heterogeneous arrays.
-     * <pre class="groovyTestCase">
-     * Integer[] a = [1, 2, 3]
-     * def result = a.union('foo')
-     * assert result.class == Object[]
-     * assert result == new Object[]{1, 2, 3, 'foo'}
-     * </pre>
-     *
-     * @param left  the array
-     * @param right the value to append
-     * @return A new Object array containing left with right appended to it.
-     * @since 4.0.0
-     */
-    public static Object[] union(final Object[] left, final Object right) {
-        Object[] result = new Object[left.length + 1];
-        System.arraycopy(left, 0, result, 0, left.length);
-        result[left.length] = right;
-        return result;
-    }
-
-    /**
-     * Create an object array containing elements from an original array plus those from a Collection.
-     * This is similar to {@link #plus(Object[], Collection)} but always return an Object array
-     * and so might be more applicable when adding heterogeneous arrays.
-     * <pre class="groovyTestCase">
-     * Integer[] a = [1, 2, 3]
-     * def result = a.union(['foo', 'bar'])
-     * assert result.class == Object[]
-     * assert result == new Object[]{1, 2, 3, 'foo', 'bar'}
-     * </pre>
-     *
-     * @param left  the array
-     * @param right a Collection to be appended
-     * @return A new Object array containing left with right appended to it.
-     * @since 4.0.0
-     */
-    public static Object[] union(final Object[] left, final Collection<?> right) {
-        Object[] result = new Object[left.length + right.size()];
-        System.arraycopy(left, 0, result, 0, left.length);
-        int i = left.length;
-        for (Object t : right) {
-            result[i] = t;
-            i += 1;
-        }
-        return result;
-    }
-
-    /**
-     * Create an Object array containing elements from an original array plus those from an Iterable.
-     * This is similar to {@link #plus(Object[], Iterable)} but always return an Object array
-     * and so might be more applicable when adding heterogeneous arrays.
-     * <pre class="groovyTestCase">
-     * class AbcIterable implements Iterable<String> {
-     *     Iterator<String> iterator() { "abc".iterator() }
-     * }
-     * String[] array = ['x', 'y', 'z']
-     * def result = array.union(new AbcIterable())
-     * assert result.class == Object[]
-     * assert result == new Object[]{'x', 'y', 'z', 'a', 'b', 'c'}
-     * </pre>
-     *
-     * @param left  the array
-     * @param right an Iterable to be appended
-     * @return A new Object array containing elements from left with those from right appended.
-     * @since 4.0.0
-     */
-    public static Object[] union(final Object[] left, final Iterable<?> right) {
-        return union(left, toList(right));
-    }
-
-    /**
-     * Create a Collection as a union of two collections. If the left collection
-     * is a Set, then the returned collection will be a Set otherwise a List.
-     * This operation will always create a new object for the result,
-     * while the operands remain unchanged.
-     * <pre class="groovyTestCase">assert [1,2,3,4] == [1,2] + [3,4]</pre>
-     *
-     * @param left  the left Collection
-     * @param right the right Collection
-     * @return the merged Collection
-     * @since 1.5.0
-     */
-    public static <T> Collection<T> plus(Collection<T> left, Collection<T> right) {
-        final Collection<T> answer = cloneSimilarCollection(left, left.size() + right.size());
-        answer.addAll(right);
-        return answer;
-    }
-
-    /**
-     * Create a Collection as a union of two iterables. If the left iterable
-     * is a Set, then the returned collection will be a Set otherwise a List.
-     * This operation will always create a new object for the result,
-     * while the operands remain unchanged.
-     * <pre class="groovyTestCase">assert [1,2,3,4] == [1,2] + [3,4]</pre>
-     *
-     * @param left  the left Iterable
-     * @param right the right Iterable
-     * @return the merged Collection
-     * @since 2.4.0
-     */
-    public static <T> Collection<T> plus(Iterable<T> left, Iterable<T> right) {
-        return plus(asCollection(left), asCollection(right));
-    }
-
-    /**
-     * Create a Collection as a union of a Collection and an Iterable. If the left collection
-     * is a Set, then the returned collection will be a Set otherwise a List.
-     * This operation will always create a new object for the result,
-     * while the operands remain unchanged.
-     *
-     * @param left  the left Collection
-     * @param right the right Iterable
-     * @return the merged Collection
-     * @since 1.8.7
-     * @see #plus(Collection, Collection)
-     */
-    public static <T> Collection<T> plus(Collection<T> left, Iterable<T> right) {
-        return plus(left, asCollection(right));
+    public static <T> Collection<T> plus(Collection<T> left, Iterable<T> right) {
+        return plus(left, asCollection(right));
     }
 
     /**
@@ -12072,21 +10721,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return true;
     }
 
-    /**
-     * Chops the array into pieces, returning lists with sizes corresponding to the supplied chop sizes.
-     * If the array isn't large enough, truncated (possibly empty) pieces are returned.
-     * Using a chop size of -1 will cause that piece to contain all remaining items from the array.
-     *
-     * @param self      an Array to be chopped
-     * @param chopSizes the sizes for the returned pieces
-     * @return a list of lists chopping the original array elements into pieces determined by chopSizes
-     * @see #collate(Object[], int) to chop a list into pieces of a fixed size
-     * @since 2.5.2
-     */
-    public static <T> List<List<T>> chop(T[] self, int... chopSizes) {
-        return chop(Arrays.asList(self), chopSizes);
-    }
-
     /**
      * Chops the Iterable into pieces, returning lists with sizes corresponding to the supplied chop sizes.
      * If the Iterable isn't large enough, truncated (possibly empty) pieces are returned.
@@ -12136,20 +10770,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return result;
     }
 
-    /**
-     * Determines if the contents of this array are equal to the
-     * contents of the given list, in the same order. This returns
-     * <code>false</code> if either collection is <code>null</code>.
-     *
-     * @param left  an array
-     * @param right the List being compared
-     * @return true if the contents of both collections are equal
-     * @since 1.5.0
-     */
-    public static boolean equals(Object[] left, List right) {
-        return coercedEquals(left, right);
-    }
-
     /**
      * Determines if the contents of this list are equal to the
      * contents of the given array in the same order. This returns
@@ -12187,7 +10807,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return true;
     }
 
-    private static boolean coercedEquals(Object o1, Object o2) {
+    static boolean coercedEquals(Object o1, Object o2) {
         if (o1 instanceof Comparable) {
             if (!(o2 instanceof Comparable && numberAwareCompareTo((Comparable) o1, (Comparable) o2) == 0)) {
                 return false;
@@ -12433,67 +11053,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return (SortedSet<T>) minus((Set<T>) self, removeMe);
     }
 
-    /**
-     * Create a new array composed of the elements of the first array minus the
-     * elements of the given Iterable.
-     * <pre class="groovyTestCase">
-     * Integer[] ints = [1, 2, 3, 1]
-     * List&lt;Integer> nope = [1, 3]
-     * def result = ints - nope
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{2}
-     *
-     * Integer[] none = []
-     * result = none - 123
-     * assert result !== none
-     * assert result.length == 0
-     * assert result.class == Integer[]
-     * </pre>
-     *
-     * @param self     an array
-     * @param removeMe an Iterable of elements to remove
-     * @return an array with the supplied elements removed
-     * @since 1.5.5
-     */
-    public static <T> T[] minus(final T[] self, final Iterable removeMe) {
-        Collection<T> temp = minus((Iterable<T>) toList(self), removeMe);
-        return temp.toArray(createSimilarArray(self, temp.size()));
-    }
-
-    /**
-     * Create a new array composed of the elements of the first array minus the
-     * elements of the given array.
-     * <pre class="groovyTestCase">
-     * Integer[] ints = [1, 2, 3, 1]
-     * Integer[] nope = [1, 3]
-     * def result = ints - nope
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{2}
-     *
-     * Integer[] none = []
-     * result = none - 123
-     * assert result !== none
-     * assert result.length == 0
-     * assert result.class == Integer[]
-     * </pre>
-     *
-     * @param self     an array
-     * @param removeMe an array of elements to remove
-     * @return an array with the supplied elements removed
-     * @since 1.5.5
-     */
-    public static <T> T[] minus(final T[] self, final Object[] removeMe) {
-        switch (removeMe.length) {
-          case 0:
-            return self.clone();
-          case 1:
-            return minus(self, removeMe[0]);
-          default:
-            Collection<T> temp = minus((Collection<T>) toList(self), Arrays.asList(removeMe));
-            return (T[]) temp.toArray(createSimilarArray(self, temp.size()));
-        }
-    }
-
     /**
      * Create a List composed of the elements of the first list minus
      * every occurrence of elements of the given Collection.
@@ -12683,43 +11242,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ansList;
     }
 
-    /**
-     * Create a new array composed of the elements of the given array minus every occurrence the given object.
-     * <pre class="groovyTestCase">
-     * Integer[] ints = [1, 2, 3, 1]
-     * def result = ints - 1
-     * assert result.class == Integer[]
-     * assert result == new Integer[]{2, 3}
-     *
-     * Integer[] none = []
-     * result = none - '1'
-     * assert result !== none
-     * assert result.length == 0
-     * assert result.class == Integer[]
-     * </pre>
-     *
-     * @param self     an array
-     * @param removeMe an element to remove from the array
-     * @return a new array with the operand removed
-     * @since 1.5.5
-     */
-    public static <T> T[] minus(final T[] self, final Object removeMe) {
-        int i = 0, n = self.length;
-        T[] result = createSimilarArray(self, n);
-
-        for (T t : self) {
-            if (!coercedEquals(t, removeMe)) {
-                result[i] = t;
-                i += 1;
-            }
-        }
-        if (i != n) {
-            result = Arrays.copyOfRange(result, 0, i);
-        }
-
-        return result;
-    }
-
     /**
      * Create a Map composed of the entries of the first map minus the
      * entries of the given map.
@@ -12814,19 +11336,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return (SortedSet<?>) flatten((Collection<?>) self);
     }
 
-    /**
-     * Flatten an array. This array and any nested arrays or
-     * collections have their contents (recursively) added to the new collection.
-     *
-     * @param self an Array to flatten
-     * @return a flattened Collection
-     * @since 1.6.0
-     */
-    public static Collection flatten(Object[] self) {
-        return flatten(toList(self), new ArrayList());
-    }
-
-    @SuppressWarnings("unchecked")
     private static Collection flatten(Iterable elements, Collection addTo) {
         for (Object element : elements) {
             if (element instanceof Collection) {
@@ -13206,21 +11715,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return self;
     }
 
-    /**
-     * Checks whether the array contains the given value.
-     *
-     * @param self  the array we are searching
-     * @param value the value being searched for
-     * @return true if the array contains the value
-     * @since 1.8.6
-     */
-    public static boolean contains(Object[] self, Object value) {
-        for (Object next : self) {
-            if (DefaultTypeTransformation.compareEqual(value, next)) return true;
-        }
-        return false;
-    }
-
     /**
      * Returns the string representation of the given map.
      *
@@ -13299,31 +11793,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return (self == null) ? "null" : FormatHelper.toListString(self, maxSize);
     }
 
-    /**
-     * Returns the string representation of this array's contents.
-     *
-     * @param self an Object[]
-     * @return the string representation
-     * @see #toArrayString(java.lang.Object[])
-     * @since 1.0
-     */
-    public static String toString(Object[] self) {
-        return toArrayString(self);
-    }
-
-    /**
-     * Returns the string representation of the given array.  The string
-     * displays the contents of the array, similar to an array literal, i.e.
-     * <code>{1, 2, "a"}</code>.
-     *
-     * @param self an Object[]
-     * @return the string representation
-     * @since 1.0
-     */
-    public static String toArrayString(Object[] self) {
-        return (self == null) ? "null" : FormatHelper.toArrayString(self);
-    }
-
     /**
      * Create a String representation of this object.
      * @param value an object
@@ -16178,6 +14647,71 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.average(self, closure);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> List<List<T>> chop(T[] self, int... chopSizes) {
+        return ArrayGroovyMethods.chop(self, chopSizes);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> List<List<T>> collate(T[] self, int size) {
+        return ArrayGroovyMethods.collate(self, size);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> List<List<T>> collate(T[] self, int size, int step) {
+        return ArrayGroovyMethods.collate(self, size, step);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> List<List<T>> collate(T[] self, int size, boolean keepRemainder) {
+        return ArrayGroovyMethods.collate(self, size, keepRemainder);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> List<List<T>> collate(T[] self, int size, int step, boolean keepRemainder) {
+        return ArrayGroovyMethods.collate(self, size, step, keepRemainder);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <E, T> List<T> collect(E[] self, @ClosureParams(FirstParam.Component.class) Closure<T> transform) {
+        return ArrayGroovyMethods.collect(self, transform);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <E, T, C extends Collection<T>> C collect(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends T> transform) {
+        return ArrayGroovyMethods.collect(self, collector, transform);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <K, V, E> Map<K, V> collectEntries(E[] self) {
+        return ArrayGroovyMethods.collectEntries(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector) {
+        return ArrayGroovyMethods.collectEntries(self, collector);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+        return ArrayGroovyMethods.collectEntries(self, transform);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <K, V, E> Map<K, V> collectEntries(E[] self, Map<K, V> collector, @ClosureParams(FirstParam.Component.class) Closure<?> transform) {
+        return ArrayGroovyMethods.collectEntries(self, collector, transform);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T, E> List<T> collectMany(E[] self, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+        return ArrayGroovyMethods.collectMany(self, projection);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T, E, C extends Collection<T>> C collectMany(E[] self, C collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+        return ArrayGroovyMethods.collectMany(self, collector, projection);
+    }
+
     @Deprecated
     public static <T, K, V> Collection<T> collectMany$$bridge(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<? extends Collection<? extends T>> projection) {
         return collectMany(self, projection);
@@ -16223,6 +14757,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.contains(self, value);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static boolean contains(Object[] self, Object value) {
+        return ArrayGroovyMethods.contains(self, value);
+    }
+
     @Deprecated(since = "5.0.0")
     public static Number count(boolean[] self, Object value) {
         return ArrayGroovyMethods.count(self, value);
@@ -16278,6 +14817,21 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.countBy(self, closure);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] drop(T[] self, int num) {
+        return ArrayGroovyMethods.drop(self, num);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] dropRight(T[] self, int num) {
+        return ArrayGroovyMethods.dropRight(self, num);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] dropWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure<?> condition) {
+        return ArrayGroovyMethods.dropWhile(self, condition);
+    }
+
     @Deprecated(since = "5.0.0")
     public static <T> T[] each(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
         return ArrayGroovyMethods.each(self, closure);
@@ -16303,11 +14857,31 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.equals(left, right);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static boolean equals(Object[] left, List right) {
+        return coercedEquals(left, right);
+    }
+
     @Deprecated(since = "5.0.0")
     public static <T> boolean every(T[] self, @ClosureParams(FirstParam.Component.class) Closure predicate) {
         return ArrayGroovyMethods.every(self, predicate);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T find(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
+        return ArrayGroovyMethods.find(self, condition);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> List<T> findAll(T[] self) {
+        return ArrayGroovyMethods.findAll(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> List<T> findAll(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
+        return ArrayGroovyMethods.findAll(self, condition);
+    }
+
     @Deprecated
     public static Collection findAll$$bridge(Object self) {
         return findAll(self);
@@ -16359,6 +14933,41 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return findLastIndexOf(new ArrayIterator<>(self), startIndex, condition);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T findResult(T[] self) {
+        return ArrayGroovyMethods.findResult(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T, U extends T, V extends T> T findResult(U[] self, V defaultResult) {
+        return ArrayGroovyMethods.findResult(self, defaultResult);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <S, T> T findResult(S[] self, @ClosureParams(FirstParam.Component.class) Closure<T> condition) {
+        return ArrayGroovyMethods.findResult(self, condition);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <S, T, U extends T, V extends T> T findResult(S[] self, U defaultResult, @ClosureParams(FirstParam.Component.class) Closure<V> condition) {
+        return ArrayGroovyMethods.findResult(self, defaultResult, condition);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> Collection<T> findResults(T[] self) {
+        return ArrayGroovyMethods.findResults(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T, U> Collection<T> findResults(U[] self, @ClosureParams(FirstParam.Component.class) Closure<T> filteringTransform) {
+        return ArrayGroovyMethods.findResults(self, filteringTransform);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T first(T[] self) {
+        return ArrayGroovyMethods.first(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static Collection flatten(boolean[] self) {
         return ArrayGroovyMethods.flatten(self);
@@ -16399,6 +15008,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.flatten(self);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static Collection flatten(Object[] self) {
+        return ArrayGroovyMethods.flatten(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static List<Boolean> getAt(boolean[] self, Range range) {
         return ArrayGroovyMethods.getAt(self, range);
@@ -16639,6 +15253,26 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.grep(self, filter);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <K, T> Map<K, List<T>> groupBy(T[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
+        return ArrayGroovyMethods.groupBy(self, closure);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static Map groupBy(Object[] self, Object... closures) {
+        return ArrayGroovyMethods.groupBy(self, closures);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static Map groupBy(Object[] self, List<Closure> closures) {
+        return ArrayGroovyMethods.groupBy(self, closures);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T head(T[] self) {
+        return ArrayGroovyMethods.head(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static Map<Integer, Integer> indexed(int[] self) {
         return ArrayGroovyMethods.indexed(self);
@@ -16669,6 +15303,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.indexed(self, offset);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] init(T[] self) {
+        return ArrayGroovyMethods.init(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static <E,T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
         return ArrayGroovyMethods.inject(self, closure);
@@ -16729,6 +15368,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.join(self, separator);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T last(T[] self) {
+        return ArrayGroovyMethods.last(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static int max(int[] self) {
         return ArrayGroovyMethods.max(self);
@@ -16789,6 +15433,41 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.min(self, closure);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] minus(T[] self, Iterable removeMe) {
+        return ArrayGroovyMethods.minus(self, removeMe);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] minus(T[] self, Object[] removeMe) {
+        return ArrayGroovyMethods.minus(self, removeMe);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] minus(T[] self, Object removeMe) {
+        return ArrayGroovyMethods.minus(self, removeMe);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] plus(T[] left, Collection<?> right) {
+        return ArrayGroovyMethods.plus(left, right);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] plus(T[] left, Iterable<?> right) {
+        return ArrayGroovyMethods.plus(left, right);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] plus(T[] left, Object[] right) {
+        return ArrayGroovyMethods.plus(left, right);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] plus(T[] left, Object right) {
+        return ArrayGroovyMethods.plus(left, right);
+    }
+
     /**
      * Implements the getAt(int) method for primitive type arrays.
      *
@@ -16846,11 +15525,41 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return answer;
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] reverse(T[] self) {
+        return ArrayGroovyMethods.reverse(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] reverse(T[] self, boolean mutate) {
+        return ArrayGroovyMethods.reverse(self, mutate);
+    }
+
     @Deprecated(since = "5.0.0")
     public static <T> T[] reverseEach(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
         return ArrayGroovyMethods.reverseEach(self, closure);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> void shuffle(T[] self) {
+        ArrayGroovyMethods.shuffle(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> void shuffle(T[] self, Random rnd) {
+        ArrayGroovyMethods.shuffle(self, rnd);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] shuffled(T[] self) {
+        return ArrayGroovyMethods.shuffled(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] shuffled(T[] self, Random rnd) {
+        return ArrayGroovyMethods.shuffled(self, rnd);
+    }
+
     @Deprecated(since = "5.0.0")
     public static int size(boolean[] self) {
         return self.length;
@@ -16896,6 +15605,41 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return self.length;
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] sort(T[] self) {
+        return ArrayGroovyMethods.sort(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] sort(T[] self, boolean mutate) {
+        return ArrayGroovyMethods.sort(self, mutate);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] sort(T[] self, Comparator<? super T> comparator) {
+        return ArrayGroovyMethods.sort(self, comparator);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) {
+        return ArrayGroovyMethods.sort(self, mutate, comparator);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] sort(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure closure) {
+        return ArrayGroovyMethods.sort(self, closure);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] sort(T[] self, boolean mutate, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure closure) {
+        return ArrayGroovyMethods.sort(self, mutate, closure);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> Collection<Collection<T>> split(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
+        return ArrayGroovyMethods.split(self, closure);
+    }
+
     @Deprecated(since = "5.0.0")
     public static byte sum(byte[] self) {
         return ArrayGroovyMethods.sum(self);
@@ -17031,6 +15775,31 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.swap(self, i,  j);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] tail(T[] self) {
+        return ArrayGroovyMethods.tail(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] take(T[] self, int num) {
+        return ArrayGroovyMethods.take(self, num);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] takeRight(T[] self, int num) {
+        return ArrayGroovyMethods.takeRight(self, num);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] takeWhile(T[] self, @ClosureParams(FirstParam.Component.class) Closure condition) {
+        return ArrayGroovyMethods.takeWhile(self, condition);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static String toArrayString(Object[] self) {
+        return FormatHelper.toArrayString(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static List<Boolean> toList(boolean[] self) {
         return ArrayGroovyMethods.toList(self);
@@ -17116,6 +15885,26 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.toSet(self);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] toSorted(T[] self) {
+        return ArrayGroovyMethods.toSorted(self);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
+        return ArrayGroovyMethods.toSorted(self, comparator);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static <T> T[] toSorted(T[] self, @ClosureParams(value=FromString.class,options={"T","T,T"}) Closure closure) {
+        return ArrayGroovyMethods.toSorted(self, closure);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static SpreadMap toSpreadMap(Object[] self) {
+        return ArrayGroovyMethods.toSpreadMap(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static String toString(boolean[] self) {
         return ArrayGroovyMethods.toString(self);
@@ -17156,6 +15945,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.toString(self);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static String toString(Object[] self) {
+        return ArrayGroovyMethods.toString(self);
+    }
+
     @Deprecated(since = "5.0.0")
     public static <T> T[] toUnique(T[] self) {
         return ArrayGroovyMethods.toUnique(self);
@@ -17186,6 +15980,26 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return ArrayGroovyMethods.transpose(self);
     }
 
+    @Deprecated(since = "5.0.0")
+    public static Object[] union(final Object[] left, final Collection<?> right) {
+        return ArrayGroovyMethods.union(left, right);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static Object[] union(final Object[] left, final Iterable<?> right) {
+        return ArrayGroovyMethods.union(left, right);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static Object[] union(final Object[] left, final Object[] right) {
+        return ArrayGroovyMethods.union(left, right);
+    }
+
+    @Deprecated(since = "5.0.0")
+    public static Object[] union(final Object[] left, final Object right) {
+        return ArrayGroovyMethods.union(left, right);
+    }
+
     @Deprecated
     public static <T> List<T> withDefault$$bridge(List<T> self, @ClosureParams(value=SimpleType.class, options = "int") Closure<T> init) {
         return withDefault(self, init);