You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/12/20 01:36:01 UTC

[groovy] 01/02: GROOVY-9865: Add some DGM methods for primitive arrays (closes #1444)

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

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

commit f0518f75462da66712744949c2a4f6017647adba
Author: Paul King <pa...@asert.com.au>
AuthorDate: Fri Dec 18 15:30:04 2020 +1000

    GROOVY-9865: Add some DGM methods for primitive arrays (closes #1444)
---
 src/main/java/groovy/util/GroovyCollections.java   |   31 +-
 .../groovy/runtime/DefaultGroovyMethods.java       | 1003 ++++++++++++--------
 .../groovy/runtime/StringGroovyMethods.java        |   20 +-
 .../{ArrayIterator.java => ArrayIterable.java}     |   32 +-
 .../org/codehaus/groovy/util/ArrayIterator.java    |    3 +
 ...rrayIterator.java => BooleanArrayIterator.java} |   16 +-
 .../{ArrayIterator.java => ByteArrayIterator.java} |   16 +-
 .../{ArrayIterator.java => CharArrayIterator.java} |   16 +-
 ...ArrayIterator.java => DoubleArrayIterable.java} |   34 +-
 ...ArrayIterator.java => DoubleArrayIterator.java} |   16 +-
 ...{ArrayIterator.java => FloatArrayIterator.java} |   16 +-
 .../{ArrayIterator.java => IntArrayIterable.java}  |   34 +-
 .../{ArrayIterator.java => IntArrayIterator.java}  |   16 +-
 .../{ArrayIterator.java => LongArrayIterable.java} |   34 +-
 .../{ArrayIterator.java => LongArrayIterator.java} |   16 +-
 ...{ArrayIterator.java => ShortArrayIterator.java} |   16 +-
 .../vmplugin/v8/PluginDefaultGroovyMethods.java    |   39 +
 src/test/groovy/ClosureCurryTest.groovy            |    4 +-
 src/test/groovy/util/OrderByTest.groovy            |    8 +-
 19 files changed, 798 insertions(+), 572 deletions(-)

diff --git a/src/main/java/groovy/util/GroovyCollections.java b/src/main/java/groovy/util/GroovyCollections.java
index 05e2f67..70fb5c1 100644
--- a/src/main/java/groovy/util/GroovyCollections.java
+++ b/src/main/java/groovy/util/GroovyCollections.java
@@ -19,7 +19,6 @@
 package groovy.util;
 
 import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
 
 import java.util.ArrayList;
@@ -107,7 +106,7 @@ public class GroovyCollections {
                 collectedCombos = newCombos;
             }
 
-            if (collectedCombos.isEmpty()) 
+            if (collectedCombos.isEmpty())
                 break;
         }
         return collectedCombos;
@@ -184,7 +183,7 @@ public class GroovyCollections {
      * @return the minimum value
      */
     public static <T> T min(T[] items) {
-        return min(Arrays.asList(items));
+        return DefaultGroovyMethods.min(items);
     }
 
     /**
@@ -195,15 +194,7 @@ public class GroovyCollections {
      * @since 2.2.0
      */
     public static <T> T min(Iterable<T> items) {
-        T answer = null;
-        for (T value : items) {
-            if (value != null) {
-                if (answer == null || ScriptBytecodeAdapter.compareLessThan(value, answer)) {
-                    answer = value;
-                }
-            }
-        }
-        return answer;
+        return DefaultGroovyMethods.min(items);
     }
 
     /**
@@ -214,7 +205,7 @@ public class GroovyCollections {
      * @return the maximum value
      */
     public static <T> T max(T[] items) {
-        return max(Arrays.asList(items));
+        return DefaultGroovyMethods.max(items);
     }
 
     /**
@@ -225,15 +216,7 @@ public class GroovyCollections {
      * @since 2.2.0
      */
     public static <T> T max(Iterable<T> items) {
-        T answer = null;
-        for (T value : items) {
-            if (value != null) {
-                if (answer == null || ScriptBytecodeAdapter.compareGreaterThan(value, answer)) {
-                    answer = value;
-                }
-            }
-        }
-        return answer;
+        return DefaultGroovyMethods.max(items);
     }
 
     /**
@@ -243,7 +226,7 @@ public class GroovyCollections {
      * @return the sum of the items
      */
     public static Object sum(Object[] items) {
-        return sum(Arrays.asList(items));
+        return DefaultGroovyMethods.sum(items);
     }
 
     /**
@@ -253,7 +236,7 @@ public class GroovyCollections {
      * @return the sum of the item
      * @since 2.2.0
      */
-    public static Object sum(Iterable items) {
+    public static Object sum(Iterable<?> items) {
         return DefaultGroovyMethods.sum(items);
     }
 
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index e6be4f3..0792622 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -92,9 +92,21 @@ 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.BooleanArrayIterator;
+import org.codehaus.groovy.util.ByteArrayIterator;
+import org.codehaus.groovy.util.CharArrayIterator;
+import org.codehaus.groovy.util.DoubleArrayIterable;
+import org.codehaus.groovy.util.DoubleArrayIterator;
+import org.codehaus.groovy.util.FloatArrayIterator;
+import org.codehaus.groovy.util.IntArrayIterable;
+import org.codehaus.groovy.util.IntArrayIterator;
 import org.codehaus.groovy.util.IteratorBufferedIterator;
 import org.codehaus.groovy.util.ListBufferedIterator;
+import org.codehaus.groovy.util.LongArrayIterable;
+import org.codehaus.groovy.util.LongArrayIterator;
+import org.codehaus.groovy.util.ShortArrayIterator;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -1867,7 +1879,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.0
      */
     public static <T> Collection<T> toUnique(Iterable<T> self, Comparator<T> comparator) {
-        Collection<T> result = createSimilarCollection((Collection<T>) self);
+        Collection<T> result = createSimilarCollection(self);
         addAll(result, toUnique(self.iterator(), comparator));
         return result;
     }
@@ -2061,7 +2073,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the unique items from the array
      */
     public static <T> T[] toUnique(T[] self, Comparator<T> comparator) {
-        Collection<T> items = toUnique(toList(self), comparator);
+        Collection<T> items = toUnique(new ArrayIterable<>(self), comparator);
         T[] result = createSimilarArray(self, items.size());
         return items.toArray(result);
     }
@@ -3661,10 +3673,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.2.0
      */
     public static <T,E> Collection<T> collectMany(Iterable<E> self, Collection<T> collector, @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends Collection<? extends T>> projection) {
-        for (E next : self) {
-            collector.addAll(projection.call(next));
-        }
-        return collector;
+        return collectMany(self.iterator(), collector, projection);
     }
 
     /**
@@ -3702,11 +3711,16 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self       a map
      * @param projection a projecting Closure returning a collection of items
-     * @return the collector with the projected collections concatenated (flattened) to it
+     * @return a list created from the projected collections concatenated (flattened) together
      * @since 1.8.8
      */
-    public static <T,K,V> Collection<T> collectMany(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<? extends Collection<? extends T>> projection) {
-        return collectMany(self, new ArrayList<>(), projection);
+    public static <T,K,V> List<T> collectMany(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<? extends Collection<? extends T>> projection) {
+        return (List<T>) collectMany(self, new ArrayList<>(), 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);
     }
 
     /**
@@ -3725,7 +3739,27 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @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(toList(self), projection);
+        return (List<T>) 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> Collection<T> collectMany(E[] self, Collection<T> collector, @ClosureParams(FirstParam.Component.class) Closure<? extends Collection<? extends T>> projection) {
+        return collectMany(new ArrayIterable<>(self), collector, projection);
     }
 
     /**
@@ -3738,14 +3772,37 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * </pre>
      *
      * @param self       an iterator
+     * @param collector  an initial collection to add the projected items to
      * @param projection a projecting Closure returning a collection of items
-     * @return a list created from the projected collections concatenated (flattened) together
+     * @return the collector with the projected collections concatenated (flattened) to it
      * @see #sum(Iterator, groovy.lang.Closure)
      * @since 1.8.1
      */
-    @SuppressWarnings("unchecked")
+    public static <T,E> Collection<T> collectMany(Iterator<E> self, Collection<T> collector, @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends Collection<? extends T>> projection) {
+        while (self.hasNext()) {
+            E next = self.next();
+            collector.addAll(projection.call(next));
+        }
+        return collector;
+    }
+
+    /**
+     * Projects each item from a source iterator to a collection and concatenates (flattens) the resulting collections into a single list.
+     * <p>
+     * <pre class="groovyTestCase">
+     * def numsIter = [1, 2, 3, 4, 5, 6].iterator()
+     * def squaresAndCubesOfEvens = numsIter.collectMany{ it % 2 ? [] : [it**2, it**3] }
+     * assert squaresAndCubesOfEvens == [4, 8, 16, 64, 36, 216]
+     * </pre>
+     *
+     * @param self       an iterator
+     * @param projection a projecting Closure returning a collection of items
+     * @return a list created from the projected collections concatenated (flattened) together
+     * @see #collectMany(Iterator, Collection, groovy.lang.Closure)
+     * @since 1.8.1
+     */
     public static <T,E> List<T> collectMany(Iterator<E> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends Collection<? extends T>> projection) {
-        return collectMany((Iterable)toList(self), projection);
+        return (List<T>) collectMany(self, new ArrayList<>(), projection);
     }
 
     /**
@@ -4004,7 +4061,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      */
     @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((Iterable)toList(self), collector, transform);
+        return collectEntries(new ArrayIterator<>(self), collector, transform);
     }
 
     /**
@@ -4039,11 +4096,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @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(Iterable, Map, Closure)
+     * @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((Iterable)toList(self), new LinkedHashMap<K, V>(), transform);
+        return collectEntries(new ArrayIterator<>(self), new LinkedHashMap<>(), transform);
     }
 
     /**
@@ -5095,16 +5152,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * @deprecated Use the Iterable version of permutations instead
-     * @see #permutations(Iterable)
-     * @since 1.7.0
-     */
-    @Deprecated
-    public static <T> Set<List<T>> permutations(List<T> self) {
-        return permutations((Iterable<T>) self);
-    }
-
-    /**
      * Finds all permutations of an iterable, applies a function to each permutation and collects the result
      * into a list.
      * <p>
@@ -5122,16 +5169,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * @deprecated Use the Iterable version of permutations instead
-     * @see #permutations(Iterable, Closure)
-     * @since 2.2.0
-     */
-    @Deprecated
-    public static <T, V> List<V> permutations(List<T> self, Closure<V> function) {
-        return permutations((Iterable<T>) self, function);
-    }
-
-    /**
      * Iterates over all permutations of a collection, running a closure for each iteration.
      * <p>
      * Example usage:
@@ -5159,10 +5196,14 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * rows are constructed similarly.
      * <p>
      * Example usage:
-     * <pre class="groovyTestCase">def result = [['a', 'b'], [1, 2]].transpose()
-     * assert result == [['a', 1], ['b', 2]]</pre>
-     * <pre class="groovyTestCase">def result = [['a', 'b'], [1, 2], [3, 4]].transpose()
-     * assert result == [['a', 1, 3], ['b', 2, 4]]</pre>
+     * <pre class="groovyTestCase">
+     * def result = [['a', 'b'], [1, 2]].transpose()
+     * assert result == [['a', 1], ['b', 2]]
+     * </pre>
+     * <pre class="groovyTestCase">
+     * def result = [['a', 'b'], [1, 2], [3, 4]].transpose()
+     * assert result == [['a', 1, 3], ['b', 2, 4]]
+     * </pre>
      *
      * @param self a List of lists
      * @return a List of the transposed lists
@@ -5174,6 +5215,64 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * A transpose method for 2D int arrays.
+     * <p>
+     * Example usage:
+     * <pre class="FIXME_groovyTestCase">
+     * int[][] nums = [[10, 15, 20], [30, 35, 40]]
+     * int[][] expected = [[10, 30], [15, 35], [20, 40]]
+     * assert nums.transpose() == expected
+     * </pre>
+     *
+     * @param self a 2D int array
+     * @return the transposed 2D int array
+     * @since 3.0.8
+     */
+    public static int[][] transpose(int[][] self) {
+        int[][] result = new int[self[0].length][self.length];
+        for (int i = 0; i < self.length; i++) {
+            for (int j = 0; j < self[i].length; j++) {
+                result[j][i] = self[i][j];
+            }
+        }
+        return result;
+    }
+
+    /**
+     * A transpose method for 2D long arrays.
+     *
+     * @param self a 2D long array
+     * @return the transposed 2D long array
+     * @since 3.0.8
+     */
+    public static long[][] transpose(long[][] self) {
+        long[][] result = new long[self[0].length][self.length];
+        for (int i = 0; i < self.length; i++) {
+            for (int j = 0; j < self[i].length; j++) {
+                result[j][i] = self[i][j];
+            }
+        }
+        return result;
+    }
+
+    /**
+     * A transpose method for 2D double arrays.
+     *
+     * @param self a 2D double array
+     * @return the transposed 2D double array
+     * @since 3.0.8
+     */
+    public static double[][] transpose(double[][] self) {
+        double[][] result = new double[self[0].length][self.length];
+        for (int i = 0; i < self.length; i++) {
+            for (int j = 0; j < self[i].length; j++) {
+                result[j][i] = self[i][j];
+            }
+        }
+        return result;
+    }
+
+    /**
      * Finds all entries matching the closure condition. If the
      * closure takes one parameter then it will be passed the Map.Entry.
      * Otherwise if the closure should take two parameters, which will be
@@ -5316,7 +5415,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.2.0
      */
     public static Map groupBy(Object[] self, Object... closures) {
-        return groupBy(Arrays.asList(self), closures);
+        return groupBy(new ArrayIterable<>(self), closures);
     }
 
     /**
@@ -5369,7 +5468,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.2.0
      */
     public static Map groupBy(Object[] self, List<Closure> closures) {
-        return groupBy(Arrays.asList(self), closures);
+        return groupBy(new ArrayIterable<>(self), closures);
     }
 
     /**
@@ -5404,11 +5503,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an array to group and count
      * @param closure a closure mapping items to the frequency keys
      * @return a new Map grouped by keys with frequency counts
-     * @see #countBy(java.lang.Iterable, Closure)
+     * @see #countBy(Iterator, Closure)
      * @since 1.8.0
      */
     public static <K,E> Map<K, Integer> countBy(E[] self, @ClosureParams(FirstParam.Component.class) Closure<K> closure) {
-        return countBy((Iterable)Arrays.asList(self), closure);
+        return countBy(new ArrayIterator<>(self), closure);
     }
 
     /**
@@ -5424,7 +5523,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an iterator to group and count
      * @param closure a closure mapping items to the frequency keys
      * @return a new Map grouped by keys with frequency counts
-     * @see #countBy(java.lang.Iterable, Closure)
      * @since 1.8.0
      */
     public static <K,E> Map<K, Integer> countBy(Iterator<E> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure<K> closure) {
@@ -5871,10 +5969,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self Iterable of values to add together
      * @return The sum of all of the items
+     * @see #sum(Iterator)
      * @since 2.2.0
      */
-    public static Object sum(Iterable self) {
-        return sum(self, null, true);
+    public static Object sum(Iterable<?> self) {
+        return sum(self.iterator(), null, true);
     }
 
     /**
@@ -5887,7 +5986,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 1.7.1
      */
     public static Object sum(Object[] self) {
-        return sum(toList(self), null, true);
+        return sum(new ArrayIterator<>(self), null, true);
     }
 
     /**
@@ -5900,7 +5999,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 1.5.5
      */
     public static Object sum(Iterator<Object> self) {
-        return sum(toList(self), null, true);
+        return sum(self, null, true);
     }
 
     /**
@@ -5996,10 +6095,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self         an Iterable of values to sum
      * @param initialValue the items in the collection will be summed to this initial value
      * @return The sum of all of the items.
+     * @see #sum(Iterator, Object)
      * @since 2.2.0
      */
-    public static Object sum(Iterable self, Object initialValue) {
-        return sum(self, initialValue, false);
+    public static Object sum(Iterable<?> self, Object initialValue) {
+        return sum(self.iterator(), initialValue, false);
     }
 
     /**
@@ -6011,7 +6111,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 1.7.1
      */
     public static Object sum(Object[] self, Object initialValue) {
-        return sum(toList(self), initialValue, false);
+        return sum(new ArrayIterator<>(self), initialValue, false);
     }
 
     /**
@@ -6024,14 +6124,15 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return The sum of all of the items
      * @since 1.5.5
      */
-    public static Object sum(Iterator<Object> self, Object initialValue) {
-        return sum(toList(self), initialValue, false);
+    public static Object sum(Iterator<?> self, Object initialValue) {
+        return sum(self, initialValue, false);
     }
 
-    private static Object sum(Iterable self, Object initialValue, boolean first) {
+    private static Object sum(Iterator<?> self, Object initialValue, boolean first) {
         Object result = initialValue;
         Object[] param = new Object[1];
-        for (Object next : self) {
+        while (self.hasNext()) {
+            Object next = self.next();
             param[0] = next;
             if (first) {
                 result = param[0];
@@ -6260,7 +6361,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return sum(self, initialValue, closure, false);
     }
 
-    private static <T> Object sum(Iterator<T> self, Object initialValue, Closure closure, boolean first) {
+    private static Object sum(Iterator<?> self, Object initialValue, Closure closure, boolean first) {
         Object result = initialValue;
         Object[] closureParam = new Object[1];
         Object[] plusParam = new Object[1];
@@ -6288,23 +6389,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return The average of all of the items
      * @since 3.0.0
      */
-    public static Object average(Iterable self) {
-        Object result = null;
-        long count = 0;
-        Object[] param = new Object[1];
-        for (Object next : self) {
-            param[0] = next;
-            if (count == 0) {
-                result = param[0];
-            } else {
-                MetaClass metaClass = InvokerHelper.getMetaClass(result);
-                result = metaClass.invokeMethod(result, "plus", param);
-            }
-            count++;
-        }
-        MetaClass metaClass = InvokerHelper.getMetaClass(result);
-        result = metaClass.invokeMethod(result, "div", count);
-        return result;
+    public static Object average(Iterable<?> self) {
+        return average(self.iterator());
     }
 
     /**
@@ -6335,8 +6421,23 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return The average of all of the items
      * @since 3.0.0
      */
-    public static Object average(Iterator<Object> self) {
-        return average(toList(self));
+    public static Object average(Iterator<?> self) {
+        Object result = null;
+        long count = 0;
+        Object[] param = new Object[1];
+        while (self.hasNext()) {
+            param[0] = self.next();
+            if (count == 0) {
+                result = param[0];
+            } else {
+                MetaClass metaClass = InvokerHelper.getMetaClass(result);
+                result = metaClass.invokeMethod(result, "plus", param);
+            }
+            count++;
+        }
+        MetaClass metaClass = InvokerHelper.getMetaClass(result);
+        result = metaClass.invokeMethod(result, "div", count);
+        return result;
     }
 
     /**
@@ -6531,8 +6632,20 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the joined String
      * @since 1.5.5
      */
-    public static <T> String join(Iterator<T> self, String separator) {
-        return join(toList(self), separator);
+    public static String join(Iterator<?> self, String separator) {
+        if (separator == null) separator = "";
+        StringBuilder buffer = new StringBuilder();
+        boolean first = true;
+        while (self.hasNext()) {
+            Object value = self.next();
+            if (first) {
+                first = false;
+            } else {
+                buffer.append(separator);
+            }
+            buffer.append(InvokerHelper.toString(value));
+        }
+        return buffer.toString();
     }
 
     /**
@@ -6545,21 +6658,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the joined String
      * @since 1.0
      */
-    public static String join(Iterable self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (Object value : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(InvokerHelper.toString(value));
-        }
-        return buffer.toString();
+    public static String join(Iterable<?> self, String separator) {
+        return join(self.iterator(), separator);
     }
 
     /**
@@ -6572,22 +6672,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the joined String
      * @since 1.0
      */
-    public static String join(Object[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (Object next : self) {
-            String value = InvokerHelper.toString(next);
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(value);
-        }
-        return buffer.toString();
+    public static <T> String join(T[] self, String separator) {
+        return join(new ArrayIterator<>(self), separator);
     }
 
     /**
@@ -6601,20 +6687,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(boolean[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (boolean next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new BooleanArrayIterator(self), separator);
     }
 
     /**
@@ -6628,20 +6701,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(byte[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (byte next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new ByteArrayIterator(self), separator);
     }
 
     /**
@@ -6655,20 +6715,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(char[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (char next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new CharArrayIterator(self), separator);
     }
 
     /**
@@ -6682,20 +6729,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(double[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (double next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new DoubleArrayIterator(self), separator);
     }
 
     /**
@@ -6709,20 +6743,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(float[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (float next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new FloatArrayIterator(self), separator);
     }
 
     /**
@@ -6736,20 +6757,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(int[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (int next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new IntArrayIterator(self), separator);
     }
 
     /**
@@ -6763,20 +6771,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(long[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (long next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new LongArrayIterator(self), separator);
     }
 
     /**
@@ -6790,20 +6785,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.4.1
      */
     public static String join(short[] self, String separator) {
-        StringBuilder buffer = new StringBuilder();
-        boolean first = true;
-
-        if (separator == null) separator = "";
-
-        for (short next : self) {
-            if (first) {
-                first = false;
-            } else {
-                buffer.append(separator);
-            }
-            buffer.append(next);
-        }
-        return buffer.toString();
+        return join(new ShortArrayIterator(self), separator);
     }
 
     /**
@@ -6812,11 +6794,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self a Collection
      * @return the minimum value
-     * @see groovy.util.GroovyCollections#min(java.util.Collection)
+     * @see #min(Iterator)
      * @since 1.0
      */
     public static <T> T min(Iterable<T> self) {
-        return GroovyCollections.min(self);
+        return min(self.iterator());
     }
 
     /**
@@ -6825,11 +6807,18 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self an Iterator
      * @return the minimum value
-     * @see #min(java.lang.Iterable)
+     * @see #min(Iterable)
      * @since 1.5.5
      */
     public static <T> T min(Iterator<T> self) {
-        return min(toList(self));
+        T answer = null;
+        while (self.hasNext()) {
+            T value =  self.next();
+            if (value != null && (answer == null || ScriptBytecodeAdapter.compareLessThan(value, answer))) {
+                answer = value;
+            }
+        }
+        return answer;
     }
 
     /**
@@ -6837,11 +6826,80 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self an array
      * @return the minimum value
-     * @see #min(java.lang.Iterable)
+     * @see #min(Iterator)
      * @since 1.5.5
      */
     public static <T> T min(T[] self) {
-        return min(toList(self));
+        return min(new ArrayIterator<>(self));
+    }
+
+    /**
+     * Adds min() method to int arrays.
+     * <p/>
+     * Example usage:
+     * <pre class="groovyTestCase">
+     * int[] nums = [10, 20, 30]
+     * assert 10 == nums.min()
+     * </pre>
+     *
+     * @param self an int array
+     * @return the minimum value
+     * @see #min(Object[])
+     * @since 3.0.8
+     */
+    public static int min(int[] self) {
+        Objects.requireNonNull(self);
+        if (self.length == 0) {
+            throw new UnsupportedOperationException("Can't call min() on empty int[]");
+        }
+        int answer = self[0];
+        for (int i = 1; i < self.length; i++) {
+            int value = self[i];
+            if (value < answer) answer = value;
+        }
+        return answer;
+    }
+
+    /**
+     * Adds min() method to long arrays.
+     *
+     * @param self a long array
+     * @return the minimum value
+     * @see #min(Object[])
+     * @since 3.0.8
+     */
+    public static long min(long[] self) {
+        Objects.requireNonNull(self);
+        if (self.length == 0) {
+            throw new UnsupportedOperationException("Can't call min() on empty long[]");
+        }
+        long answer = self[0];
+        for (int i = 1; i < self.length; i++) {
+            long value = self[i];
+            if (value < answer) answer = value;
+        }
+        return answer;
+    }
+
+    /**
+     * Adds min() method to double arrays.
+     *
+     * @param self a double array
+     * @return the minimum value
+     * @see #min(Object[])
+     * @since 3.0.8
+     */
+    public static double min(double[] self) {
+        Objects.requireNonNull(self);
+        if (self.length == 0) {
+            throw new UnsupportedOperationException("Can't call min() on empty double[]");
+        }
+        double answer = self[0];
+        for (int i = 1; i < self.length; i++) {
+            double value = self[i];
+            if (value < answer) answer = value;
+        }
+        return answer;
     }
 
     /**
@@ -6851,20 +6909,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self       an Iterable
      * @param comparator a Comparator
      * @return the minimum value or null for an empty Iterable
+     * @see #min(Iterator, java.util.Comparator)
      * @since 2.2.0
      */
     public static <T> T min(Iterable<T> self, Comparator<T> comparator) {
-        T answer = null;
-        boolean first = true;
-        for (T value : self) {
-            if (first) {
-                first = false;
-                answer = value;
-            } else if (comparator.compare(value, answer) < 0) {
-                answer = value;
-            }
-        }
-        return answer;
+        return min(self.iterator(), comparator);
     }
 
     /**
@@ -6873,11 +6922,21 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self       an Iterator
      * @param comparator a Comparator
      * @return the minimum value
-     * @see #min(java.lang.Iterable, java.util.Comparator)
      * @since 1.5.5
      */
     public static <T> T min(Iterator<T> self, Comparator<T> comparator) {
-        return min(toList(self), comparator);
+        T answer = null;
+        boolean first = true;
+        while (self.hasNext()) {
+            T value = self.next();
+            if (first) {
+                first = false;
+                answer = value;
+            } else if (comparator.compare(value, answer) < 0) {
+                answer = value;
+            }
+        }
+        return answer;
     }
 
     /**
@@ -6886,11 +6945,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self       an array
      * @param comparator a Comparator
      * @return the minimum value
-     * @see #min(java.lang.Iterable, java.util.Comparator)
+     * @see #min(Iterator, java.util.Comparator)
      * @since 1.5.5
      */
     public static <T> T min(T[] self, Comparator<T> comparator) {
-        return min(toList(self), comparator);
+        return min(new ArrayIterator<>(self), comparator);
     }
 
     /**
@@ -6922,28 +6981,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an Iterable
      * @param closure a 1 or 2 arg Closure used to determine the correct ordering
      * @return an item from the Iterable having the minimum value returned by calling the supplied closure with that item as parameter or null for an empty Iterable
+     * @see #min(Iterator)
      * @since 1.0
      */
-    public static <T> T min(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        int params = closure.getMaximumNumberOfParameters();
-        if (params != 1) {
-            return min(self, new ClosureComparator<>(closure));
-        }
-        boolean first = true;
-        T answer = null;
-        Object answerValue = null;
-        for (T item : self) {
-            Object value = closure.call(item);
-            if (first) {
-                first = false;
-                answer = item;
-                answerValue = value;
-            } else if (ScriptBytecodeAdapter.compareLessThan(value, answerValue)) {
-                answer = item;
-                answerValue = value;
-            }
-        }
-        return answer;
+    public static <T> T min(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
+        return min(self.iterator(), closure);
     }
 
     /**
@@ -7040,11 +7082,29 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an Iterator
      * @param closure a Closure used to determine the correct ordering
      * @return the minimum value
-     * @see #min(java.lang.Iterable, groovy.lang.Closure)
      * @since 1.5.5
      */
     public static <T> T min(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return min(toList(self), closure);
+        int params = closure.getMaximumNumberOfParameters();
+        if (params != 1) {
+            return min(self, new ClosureComparator<>(closure));
+        }
+        boolean first = true;
+        T answer = null;
+        Object answerValue = null;
+        while (self.hasNext()) {
+            T item = self.next();
+            Object value = closure.call(item);
+            if (first) {
+                first = false;
+                answer = item;
+                answerValue = value;
+            } else if (ScriptBytecodeAdapter.compareLessThan(value, answerValue)) {
+                answer = item;
+                answerValue = value;
+            }
+        }
+        return answer;
     }
 
     /**
@@ -7063,11 +7123,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an array
      * @param closure a Closure used to determine the correct ordering
      * @return the minimum value
-     * @see #min(java.lang.Iterable, groovy.lang.Closure)
+     * @see #min(Iterator, groovy.lang.Closure)
      * @since 1.5.5
      */
     public static <T> T min(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return min(toList(self), closure);
+        return min(new ArrayIterator<>(self), closure);
     }
 
     /**
@@ -7078,11 +7138,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self an Iterable
      * @return the maximum value
-     * @see groovy.util.GroovyCollections#max(java.lang.Iterable)
+     * @see #max(Iterator)
      * @since 2.2.0
      */
     public static <T> T max(Iterable<T> self) {
-        return GroovyCollections.max(self);
+        return max(self.iterator());
     }
 
     /**
@@ -7091,11 +7151,17 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self an Iterator
      * @return the maximum value
-     * @see groovy.util.GroovyCollections#max(java.util.Collection)
      * @since 1.5.5
      */
     public static <T> T max(Iterator<T> self) {
-        return max(toList(self));
+        T answer = null;
+        while (self.hasNext()) {
+            T value =  self.next();
+            if (value != null && (answer == null || ScriptBytecodeAdapter.compareGreaterThan(value, answer))) {
+                answer = value;
+            }
+        }
+        return answer;
     }
 
     /**
@@ -7103,11 +7169,80 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self an array
      * @return the maximum value
-     * @see #max(java.lang.Iterable)
+     * @see #max(Iterator)
      * @since 1.5.5
      */
     public static <T> T max(T[] self) {
-        return max(toList(self));
+        return max(new ArrayIterator<>(self));
+    }
+
+    /**
+     * Adds max() method to int arrays.
+     *
+     * @param self an int array
+     * @return the maximum value
+     * @see #max(Object[])
+     * @since 3.0.8
+     */
+    public static int max(int[] self) {
+        Objects.requireNonNull(self);
+        if (self.length == 0) {
+            throw new UnsupportedOperationException("Can't call max() on empty int[]");
+        }
+        int answer = self[0];
+        for (int i = 1; i < self.length; i++) {
+            int value = self[i];
+            if (value > answer) answer = value;
+        }
+        return answer;
+    }
+
+    /**
+     * Adds max() method to long arrays.
+     *
+     * @param self a long array
+     * @return the maximum value
+     * @see #max(Object[])
+     * @since 3.0.8
+     */
+    public static long max(long[] self) {
+        Objects.requireNonNull(self);
+        if (self.length == 0) {
+            throw new UnsupportedOperationException("Can't call max() on empty long[]");
+        }
+        long answer = self[0];
+        for (int i = 1; i < self.length; i++) {
+            long value = self[i];
+            if (value > answer) answer = value;
+        }
+        return answer;
+    }
+
+    /**
+     * Adds max() method to double arrays.
+     * <p/>
+     * Example usage:
+     * <pre class="groovyTestCase">
+     * double[] nums = [1.1d, 2.2d, 3.3d]
+     * assert 3.3d == nums.max()
+     * </pre>
+     *
+     * @param self a double array
+     * @return the maximum value
+     * @see #max(Object[])
+     * @since 3.0.8
+     */
+    public static double max(double[] self) {
+        Objects.requireNonNull(self);
+        if (self.length == 0) {
+            throw new UnsupportedOperationException("Can't call max() on empty double[]");
+        }
+        double answer = self[0];
+        for (int i = 1; i < self.length; i++) {
+            double value = self[i];
+            if (value > answer) answer = value;
+        }
+        return answer;
     }
 
     /**
@@ -7138,25 +7273,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 2.2.0
      */
     public static <T> T max(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        int params = closure.getMaximumNumberOfParameters();
-        if (params != 1) {
-            return max(self, new ClosureComparator<>(closure));
-        }
-        boolean first = true;
-        T answer = null;
-        Object answerValue = null;
-        for (T item : self) {
-            Object value = closure.call(item);
-            if (first) {
-                first = false;
-                answer = item;
-                answerValue = value;
-            } else if (ScriptBytecodeAdapter.compareLessThan(answerValue, value)) {
-                answer = item;
-                answerValue = value;
-            }
-        }
-        return answer;
+        return max(self.iterator(), closure);
     }
 
     /**
@@ -7176,11 +7293,29 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an Iterator
      * @param closure a Closure used to determine the correct ordering
      * @return the maximum value
-     * @see #max(java.lang.Iterable, groovy.lang.Closure)
      * @since 1.5.5
      */
     public static <T> T max(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return max(toList(self), closure);
+        int params = closure.getMaximumNumberOfParameters();
+        if (params != 1) {
+            return max(self, new ClosureComparator<>(closure));
+        }
+        boolean first = true;
+        T answer = null;
+        Object answerValue = null;
+        while (self.hasNext()) {
+            T item = self.next();
+            Object value = closure.call(item);
+            if (first) {
+                first = false;
+                answer = item;
+                answerValue = value;
+            } else if (ScriptBytecodeAdapter.compareLessThan(answerValue, value)) {
+                answer = item;
+                answerValue = value;
+            }
+        }
+        return answer;
     }
 
     /**
@@ -7199,11 +7334,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    an array
      * @param closure a Closure used to determine the correct ordering
      * @return the maximum value
-     * @see #max(java.lang.Iterable, groovy.lang.Closure)
+     * @see #max(Iterator, groovy.lang.Closure)
      * @since 1.5.5
      */
     public static <T> T max(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return max(toList(self), closure);
+        return max(new ArrayIterator<>(self), closure);
     }
 
     /**
@@ -7215,20 +7350,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self       an Iterable
      * @param comparator a Comparator
      * @return the maximum value or null for an empty Iterable
+     * @see #max(Iterator, Comparator)
      * @since 2.2.0
      */
     public static <T> T max(Iterable<T> self, Comparator<T> comparator) {
-        T answer = null;
-        boolean first = true;
-        for (T value : self) {
-            if (first) {
-                first = false;
-                answer = value;
-            } else if (comparator.compare(value, answer) > 0) {
-                answer = value;
-            }
-        }
-        return answer;
+        return max(self.iterator(), comparator);
     }
 
     /**
@@ -7240,7 +7366,14 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 1.5.5
      */
     public static <T> T max(Iterator<T> self, Comparator<T> comparator) {
-        return max(toList(self), comparator);
+        T answer = null;
+        while (self.hasNext()) {
+            T value = self.next();
+            if (value != null && (answer == null || comparator.compare(value, answer) > 0)) {
+                answer = value;
+            }
+        }
+        return answer;
     }
 
     /**
@@ -7249,10 +7382,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self       an array
      * @param comparator a Comparator
      * @return the maximum value
+     * @see #max(Iterator, Comparator)
      * @since 1.5.5
      */
     public static <T> T max(T[] self, Comparator<T> comparator) {
-        return max(toList(self), comparator);
+        return max(new ArrayIterator<>(self), comparator);
     }
 
     /**
@@ -7289,6 +7423,86 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Returns indices of the boolean array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(boolean[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the byte array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(byte[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the char array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(char[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the double array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(double[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the float array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(float[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the int array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(int[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the long array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(long[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
+     * Returns indices of the short array.
+     *
+     * @see #getIndices(Object[])
+     * @since 3.0.8
+     */
+    public static IntRange getIndices(short[] self) {
+        return new IntRange(false, 0, self.length);
+    }
+
+    /**
      * Provide the standard Groovy <code>size()</code> method for <code>Iterator</code>.
      * The iterator will become exhausted of elements after determining the size value.
      *
@@ -8616,6 +8830,82 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Zips an int[] with indices in (index, value) order starting from index 0.
+     *
+     * @see #indexed(int[], int)
+     * @since 3.0.8
+     */
+    public static Map<Integer, Integer> indexed(int[] self) {
+        return indexed(self, 0);
+    }
+
+    /**
+     * Zips an int[] with indices in (index, value) order.
+     * <p/>
+     * Example usage:
+     * <pre class="groovyTestCase">
+     * int[] nums = [10, 20, 30]
+     * assert [5: 10, 6: 20, 7: 30] == nums.indexed(5)
+     * assert ["1: 10", "2: 20", "3: 30"] == nums.indexed(1).collect { idx, str {@code ->} "$idx: $str" }
+     * </pre>
+     *
+     * @param self   an Iterable
+     * @param offset an index to start from
+     * @return a Map (since the keys/indices are unique) containing the elements from the iterable zipped with indices
+     * @see #indexed(Iterable, int)
+     * @since 3.0.8
+     */
+    public static Map<Integer, Integer> indexed(int[] self, int offset) {
+        return indexed(new IntArrayIterable(self), offset);
+    }
+
+    /**
+     * Zips a long[] with indices in (index, value) order starting from index 0.
+     *
+     * @see #indexed(long[], int)
+     * @since 3.0.8
+     */
+    public static Map<Integer, Long> indexed(long[] self) {
+        return indexed(self, 0);
+    }
+
+    /**
+     * Zips a long[] with indices in (index, value) order.
+     *
+     * @param self   a long[]
+     * @param offset an index to start from
+     * @return a Map (since the keys/indices are unique) containing the elements from the iterable zipped with indices
+     * @see #indexed(Iterable, int)
+     * @since 3.0.8
+     */
+    public static Map<Integer, Long> indexed(long[] self, int offset) {
+        return indexed(new LongArrayIterable(self), offset);
+    }
+
+    /**
+     * Zips a double[] with indices in (index, value) order starting from index 0.
+     *
+     * @see #indexed(double[], int)
+     * @since 3.0.8
+     */
+    public static Map<Integer, Double> indexed(double[] self) {
+        return indexed(self, 0);
+    }
+
+    /**
+     * Zips a double[] with indices in (index, value) order.
+     *
+     * @param self   a double[]
+     * @param offset an index to start from
+     * @return a Map (since the keys/indices are unique) containing the elements from the iterable zipped with indices
+     * @see #indexed(Iterable, int)
+     * @since 3.0.8
+     */
+    public static Map<Integer, Double> indexed(double[] self, int offset) {
+        return indexed(new DoubleArrayIterable(self), offset);
+    }
+
+    /**
      * Zips an iterator with indices in (value, index) order.
      * <p/>
      * Example usage:
@@ -8742,16 +9032,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * @deprecated Use the Iterable version of sort instead
-     * @see #sort(Iterable,boolean)
-     * @since 1.0
-     */
-    @Deprecated
-    public static <T> List<T> sort(Collection<T> self) {
-        return sort((Iterable<T>) self, true);
-    }
-
-    /**
      * Sorts the Collection. Assumes that the collection items are comparable
      * and uses their natural ordering to determine the resulting order.
      * If the Collection is a List, it is sorted in place and returned.
@@ -8761,7 +9041,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *
      * @param self the Iterable to be sorted
      * @return the sorted Iterable as a List
-     * @see #sort(Collection, boolean)
+     * @see #sort(Iterable, boolean)
      * @since 2.2.0
      */
     public static <T> List<T> sort(Iterable<T> self) {
@@ -8769,16 +9049,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * @deprecated Use the Iterable version of sort instead
-     * @see #sort(Iterable, boolean)
-     * @since 1.8.1
-     */
-    @Deprecated
-    public static <T> List<T> sort(Collection<T> self, boolean mutate) {
-        return sort((Iterable<T>) self, mutate);
-    }
-
-    /**
      * Sorts the Iterable. Assumes that the Iterable items are
      * comparable and uses their natural ordering to determine the resulting order.
      * If the Iterable is a List and mutate is true,
@@ -8926,26 +9196,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * @deprecated Use the Iterable version of sort instead
-     * @see #sort(Iterable, boolean, Comparator)
-     * @since 1.0
-     */
-    @Deprecated
-    public static <T> List<T> sort(Collection<T> self, Comparator<T> comparator) {
-        return sort((Iterable<T>) self, true, comparator);
-    }
-
-    /**
-     * @deprecated Use the Iterable version of sort instead
-     * @see #sort(Iterable, boolean, Comparator)
-     * @since 1.8.1
-     */
-    @Deprecated
-    public static <T> List<T> sort(Collection<T> self, boolean mutate, Comparator<T> comparator) {
-        return sort((Iterable<T>) self, mutate, comparator);
-    }
-
-    /**
      * Sorts the Iterable using the given Comparator. If the Iterable is a List and mutate
      * is true, it is sorted in place and returned. Otherwise, the elements are first placed
      * into a new list which is then sorted and returned - leaving the original Iterable unchanged.
@@ -9082,26 +9332,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * @deprecated Use the Iterable version of sort instead
-     * @see #sort(Iterable, boolean, Closure)
-     * @since 1.8.1
-     */
-    @Deprecated
-    public static <T> List<T> sort(Collection<T> self, boolean mutate, Closure closure) {
-        return sort((Iterable<T>)self, mutate, closure);
-    }
-
-    /**
-     * @deprecated Use the Iterable version of sort instead
-     * @see #sort(Iterable, Closure)
-     * @since 1.0
-     */
-    @Deprecated
-    public static <T> List<T> sort(Collection<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
-        return sort((Iterable<T>)self, closure);
-    }
-
-    /**
      * 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
      * into a new list which is then sorted and returned - leaving the original Iterable unchanged.
@@ -9120,7 +9350,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @param self    the Iterable to be sorted
      * @param closure a 1 or 2 arg Closure used to determine the correct ordering
      * @return a newly created sorted List
-     * @see #sort(Collection, boolean, Closure)
+     * @see #sort(Iterable, boolean, Closure)
      * @since 2.2.0
      */
     public static <T> List<T> sort(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
@@ -10239,11 +10469,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         }
     }
 
-    @Deprecated
-    public static CharSequence take(CharSequence self, int num) {
-        return StringGroovyMethods.take(self, num);
-    }
-
     /**
      * Returns the last <code>num</code> elements from the tail of this array.
      * <pre class="groovyTestCase">
@@ -17086,50 +17311,55 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         if (boolean.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setBoolean(array, idx, (Boolean) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, boolean.class}));
+                Array.setBoolean(array, idx, (Boolean) invokeAsType(element, boolean.class));
             }
         } else if (byte.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setByte(array, idx, (Byte) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, byte.class}));
+                Array.setByte(array, idx, (Byte) invokeAsType(element, byte.class));
             }
         } else if (char.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setChar(array, idx, (Character) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, char.class}));
+                Array.setChar(array, idx, (Character) invokeAsType(element, char.class));
             }
         } else if (double.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setDouble(array, idx, (Double) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, double.class}));
+                Array.setDouble(array, idx, (Double) invokeAsType(element, double.class));
             }
         } else if (float.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setFloat(array, idx, (Float) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, float.class}));
+                Array.setFloat(array, idx, (Float) invokeAsType(element, float.class));
             }
         } else if (int.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setInt(array, idx, (Integer) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, int.class}));
+                Array.setInt(array, idx, (Integer) invokeAsType(element, int.class));
             }
         } else if (long.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setLong(array, idx, (Long) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, long.class}));
+                Array.setLong(array, idx, (Long) invokeAsType(element, long.class));
             }
         } else if (short.class.equals(elementType)) {
             for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
                 Object element = iter.next();
-                Array.setShort(array, idx, (Short) InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, short.class}));
+                Array.setShort(array, idx, (Short) invokeAsType(element, short.class));
             }
         } else for (Iterator iter = list.iterator(); iter.hasNext(); idx++) {
             Object element = iter.next();
-            Array.set(array, idx, InvokerHelper.invokeStaticMethod(DefaultGroovyMethods.class, "asType", new Object[]{element, elementType}));
+            Array.set(array, idx, invokeAsType(element, elementType));
         }
         return array;
     }
 
+    private static Object invokeAsType(Object element, Class<?> elementType) {
+        Class<?> target = element instanceof CharSequence ? StringGroovyMethods.class : DefaultGroovyMethods.class;
+        return InvokerHelper.invokeStaticMethod(target, "asType", new Object[]{element, elementType});
+    }
+
     /**
      * Convenience method to dynamically create a new instance of this
      * class.  Calls the default constructor.
@@ -17829,11 +18059,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
                     : new groovy.lang.groovydoc.Groovydoc(groovydocAnnotation.value(), holder);
     }
 
-    @Deprecated
-    public static <T> T asType(CharSequence self, Class<T> c) {
-        return StringGroovyMethods.asType(self, c);
-    }
-
     /**
      * Get the detail information of {@link Throwable} instance's stack trace
      *
diff --git a/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java
index 421c700..f42f922 100644
--- a/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java
@@ -145,7 +145,7 @@ public class StringGroovyMethods extends DefaultGroovyMethodsSupport {
         } else if (Number.class.isAssignableFrom(c) || c.isPrimitive()) {
             return asType(self.toString(), c);
         }
-        return DefaultGroovyMethods.asType((Object) self, c);
+        return DefaultGroovyMethods.asType(self, c);
     }
 
     /**
@@ -181,31 +181,31 @@ public class StringGroovyMethods extends DefaultGroovyMethodsSupport {
     @SuppressWarnings("unchecked")
     public static <T> T asType(final String self, final Class<T> c) {
         if (c == List.class) {
-            return (T) toList((CharSequence)self);
+            return (T) toList(self);
         } else if (c == BigDecimal.class) {
-            return (T) toBigDecimal((CharSequence)self);
+            return (T) toBigDecimal(self);
         } else if (c == BigInteger.class) {
-            return (T) toBigInteger((CharSequence)self);
+            return (T) toBigInteger(self);
         } else if (c == Long.class || c == Long.TYPE) {
-            return (T) toLong((CharSequence)self);
+            return (T) toLong(self);
         } else if (c == Integer.class || c == Integer.TYPE) {
-            return (T) toInteger((CharSequence)self);
+            return (T) toInteger(self);
         } else if (c == Short.class || c == Short.TYPE) {
-            return (T) toShort((CharSequence)self);
+            return (T) toShort(self);
         } else if (c == Byte.class || c == Byte.TYPE) {
             return (T) Byte.valueOf(self.trim());
         } else if (c == Character.class || c == Character.TYPE) {
             return (T) toCharacter(self);
         } else if (c == Double.class || c == Double.TYPE) {
-            return (T) toDouble((CharSequence)self);
+            return (T) toDouble(self);
         } else if (c == Float.class || c == Float.TYPE) {
-            return (T) toFloat((CharSequence)self);
+            return (T) toFloat(self);
         } else if (c == File.class) {
             return (T) new File(self);
         } else if (c.isEnum()) {
             return (T) InvokerHelper.invokeMethod(c, "valueOf", new Object[]{ self });
         }
-        return DefaultGroovyMethods.asType((Object) self, c);
+        return DefaultGroovyMethods.asType(self, c);
     }
 
     /**
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/ArrayIterable.java
similarity index 59%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/ArrayIterable.java
index 6a2904f..8e1b246 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/ArrayIterable.java
@@ -18,36 +18,22 @@
  */
 package org.codehaus.groovy.util;
 
-import java.lang.reflect.Array;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
+/**
+ * Allow an array to be used where an Iterable is expected.
+ *
+ * @since 3.0.8
+ */
+public class ArrayIterable<T> implements Iterable<T> {
     private final T[] array;
-    private final int length;
-    private int index;
 
-    public ArrayIterator(T[] array) {
+    public ArrayIterable(T[] array) {
         this.array = array;
-        length = Array.getLength(array);
-    }
-
-    @Override
-    public boolean hasNext() {
-        return index < length;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-        return (T) Array.get(array, index++);
     }
 
     @Override
-    public void remove() {
-        throw new UnsupportedOperationException("Remove not supported for arrays");
+    public Iterator<T> iterator() {
+        return new ArrayIterator<>(array);
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
index 6a2904f..4999d90 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
@@ -22,6 +22,9 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
+/**
+ * Allow an array to be used where an Iterator is expected.
+ */
 public class ArrayIterator<T> implements Iterator<T> {
     private final T[] array;
     private final int length;
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/BooleanArrayIterator.java
similarity index 82%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/BooleanArrayIterator.java
index 6a2904f..e4818f4 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/BooleanArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a boolean array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class BooleanArrayIterator implements Iterator<Boolean> {
+    private final boolean[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public BooleanArrayIterator(boolean[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Boolean next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/ByteArrayIterator.java
similarity index 83%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/ByteArrayIterator.java
index 6a2904f..f0c7ca2 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/ByteArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a byte array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class ByteArrayIterator implements Iterator<Byte> {
+    private final byte[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public ByteArrayIterator(byte[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Byte next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/CharArrayIterator.java
similarity index 82%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/CharArrayIterator.java
index 6a2904f..d1673a7 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/CharArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a char array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class CharArrayIterator implements Iterator<Character> {
+    private final char[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public CharArrayIterator(char[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Character next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/DoubleArrayIterable.java
similarity index 57%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/DoubleArrayIterable.java
index 6a2904f..b9f41d9 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/DoubleArrayIterable.java
@@ -18,36 +18,22 @@
  */
 package org.codehaus.groovy.util;
 
-import java.lang.reflect.Array;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
-    private final int length;
-    private int index;
+/**
+ * Allow a double array to be used where an Iterable is expected.
+ *
+ * @since 3.0.8
+ */
+public class DoubleArrayIterable implements Iterable<Double> {
+    private final double[] array;
 
-    public ArrayIterator(T[] array) {
+    public DoubleArrayIterable(double[] array) {
         this.array = array;
-        length = Array.getLength(array);
-    }
-
-    @Override
-    public boolean hasNext() {
-        return index < length;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-        return (T) Array.get(array, index++);
     }
 
     @Override
-    public void remove() {
-        throw new UnsupportedOperationException("Remove not supported for arrays");
+    public Iterator<Double> iterator() {
+        return new DoubleArrayIterator(array);
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/DoubleArrayIterator.java
similarity index 82%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/DoubleArrayIterator.java
index 6a2904f..78cd176 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/DoubleArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a double array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class DoubleArrayIterator implements Iterator<Double> {
+    private final double[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public DoubleArrayIterator(double[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Double next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/FloatArrayIterator.java
similarity index 82%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/FloatArrayIterator.java
index 6a2904f..e13d73b 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/FloatArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a float array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class FloatArrayIterator implements Iterator<Float> {
+    private final float[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public FloatArrayIterator(float[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Float next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/IntArrayIterable.java
similarity index 57%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/IntArrayIterable.java
index 6a2904f..292f25d 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/IntArrayIterable.java
@@ -18,36 +18,22 @@
  */
 package org.codehaus.groovy.util;
 
-import java.lang.reflect.Array;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
-    private final int length;
-    private int index;
+/**
+ * Allow an int array to be used where an Iterable is expected.
+ *
+ * @since 3.0.8
+ */
+public class IntArrayIterable implements Iterable<Integer> {
+    private final int[] array;
 
-    public ArrayIterator(T[] array) {
+    public IntArrayIterable(int[] array) {
         this.array = array;
-        length = Array.getLength(array);
-    }
-
-    @Override
-    public boolean hasNext() {
-        return index < length;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-        return (T) Array.get(array, index++);
     }
 
     @Override
-    public void remove() {
-        throw new UnsupportedOperationException("Remove not supported for arrays");
+    public Iterator<Integer> iterator() {
+        return new IntArrayIterator(array);
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/IntArrayIterator.java
similarity index 83%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/IntArrayIterator.java
index 6a2904f..652c8bd 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/IntArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow an int array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class IntArrayIterator implements Iterator<Integer> {
+    private final int[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public IntArrayIterator(int[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Integer next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/LongArrayIterable.java
similarity index 57%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/LongArrayIterable.java
index 6a2904f..12c8a3e 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/LongArrayIterable.java
@@ -18,36 +18,22 @@
  */
 package org.codehaus.groovy.util;
 
-import java.lang.reflect.Array;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
-    private final int length;
-    private int index;
+/**
+ * Allow a long array to be used where an Iterable is expected.
+ *
+ * @since 3.0.8
+ */
+public class LongArrayIterable implements Iterable<Long> {
+    private final long[] array;
 
-    public ArrayIterator(T[] array) {
+    public LongArrayIterable(long[] array) {
         this.array = array;
-        length = Array.getLength(array);
-    }
-
-    @Override
-    public boolean hasNext() {
-        return index < length;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-        return (T) Array.get(array, index++);
     }
 
     @Override
-    public void remove() {
-        throw new UnsupportedOperationException("Remove not supported for arrays");
+    public Iterator<Long> iterator() {
+        return new LongArrayIterator(array);
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/LongArrayIterator.java
similarity index 83%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/LongArrayIterator.java
index 6a2904f..1e30adb 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/LongArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a longt array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class LongArrayIterator implements Iterator<Long> {
+    private final long[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public LongArrayIterator(long[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Long next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java b/src/main/java/org/codehaus/groovy/util/ShortArrayIterator.java
similarity index 82%
copy from src/main/java/org/codehaus/groovy/util/ArrayIterator.java
copy to src/main/java/org/codehaus/groovy/util/ShortArrayIterator.java
index 6a2904f..542a2b3 100644
--- a/src/main/java/org/codehaus/groovy/util/ArrayIterator.java
+++ b/src/main/java/org/codehaus/groovy/util/ShortArrayIterator.java
@@ -22,12 +22,17 @@ import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-public class ArrayIterator<T> implements Iterator<T> {
-    private final T[] array;
+/**
+ * Allow a short array to be used where an Iterator is expected.
+ *
+ * @since 3.0.8
+ */
+public class ShortArrayIterator implements Iterator<Short> {
+    private final short[] array;
     private final int length;
     private int index;
 
-    public ArrayIterator(T[] array) {
+    public ShortArrayIterator(short[] array) {
         this.array = array;
         length = Array.getLength(array);
     }
@@ -38,12 +43,11 @@ public class ArrayIterator<T> implements Iterator<T> {
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public T next() {
+    public Short next() {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
-        return (T) Array.get(array, index++);
+        return array[index++];
     }
 
     @Override
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/PluginDefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/PluginDefaultGroovyMethods.java
index 40dd8d0..330cb19 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/PluginDefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/PluginDefaultGroovyMethods.java
@@ -654,6 +654,19 @@ public class PluginDefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Returns a sequential {@link IntStream} with the specified array as its
+     * source.
+     *
+     * @param self The array, assumed to be unmodified during use
+     * @return a {@code Stream} for the array
+     *
+     * @since 3.0.8
+     */
+    public static IntStream intStream(final int[] self) {
+        return Arrays.stream(self);
+    }
+
+    /**
      * Returns a sequential {@link Stream} with the specified array as its
      * source.
      *
@@ -667,6 +680,19 @@ public class PluginDefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Returns a sequential {@link LongStream} with the specified array as its
+     * source.
+     *
+     * @param self The array, assumed to be unmodified during use
+     * @return a {@code Stream} for the array
+     *
+     * @since 3.0.8
+     */
+    public static LongStream longStream(final long[] self) {
+        return Arrays.stream(self);
+    }
+
+    /**
      * Returns a sequential {@link Stream} with the specified array as its
      * source.
      *
@@ -680,6 +706,19 @@ public class PluginDefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Returns a sequential {@link DoubleStream} with the specified array as its
+     * source.
+     *
+     * @param self The array, assumed to be unmodified during use
+     * @return a {@code Stream} for the array
+     *
+     * @since 3.0.8
+     */
+    public static DoubleStream doubleStream(final double[] self) {
+        return Arrays.stream(self);
+    }
+
+    /**
      * Returns a sequential {@link Stream} with the specified array as its
      * source.
      *
diff --git a/src/test/groovy/ClosureCurryTest.groovy b/src/test/groovy/ClosureCurryTest.groovy
index 57bb4e0..799b91f 100644
--- a/src/test/groovy/ClosureCurryTest.groovy
+++ b/src/test/groovy/ClosureCurryTest.groovy
@@ -179,8 +179,8 @@ class ClosureCurryTest extends GroovyTestCase {
         def catSearcher = Collections.&binarySearch.ncurry(1, "cat")
         def combos = [[animals1, animals2], [caseInsensitive, caseSensitive]].combinations()
         assert combos.collect{ List a, Comparator c ->
-            // make use we use DGM#sort, not JDK8 sort
-            def sorted = DefaultGroovyMethods.sort(a,c)
+            // make sure we use DGM#sort, not JDK8 sort
+            def sorted = a.sort(false, c)
             catSearcher(sorted, c)
         } == [-3, 2, -3, -4]
     }
diff --git a/src/test/groovy/util/OrderByTest.groovy b/src/test/groovy/util/OrderByTest.groovy
index ca107b7..0dca10f 100644
--- a/src/test/groovy/util/OrderByTest.groovy
+++ b/src/test/groovy/util/OrderByTest.groovy
@@ -30,18 +30,18 @@ class OrderByTest extends GroovyTestCase {
         def people = buildPeople()
 
         def order = new OrderBy({it.get('@cheese')})
-        def sorted = DefaultGroovyMethods.sort(people,order)
+        def sorted = people.sort(false, order)
         assert (0..3).collect{ sorted.get(it).get('@name') } == ['Joe', 'Bob', 'James', 'Chris']
 
         order = new OrderBy({it.get('@name')})
-        sorted = DefaultGroovyMethods.sort(people,order)
+        sorted = people.sort(false, order)
         assert (0..3).collect{ sorted.get(it).get('@name') } == ['Bob', 'Chris', 'James', 'Joe']
     }
 
     void testSortByMultipleFields() {
         def people = buildPeople()
         def order = new OrderBy([{it.get('@location')}, {it.get('@cheese')}])
-        def sorted = DefaultGroovyMethods.sort(people,order)
+        def sorted = people.sort(false, order)
         assert (0..3).collect{ sorted.get(it).get('@name') } == ['Bob', 'Joe', 'James', 'Chris']
     }
 
@@ -63,7 +63,7 @@ class OrderByTest extends GroovyTestCase {
 
         def people = [bobby, bob, raul]
         def order = new OrderBy([{it}, {it.age}])
-        def sorted = DefaultGroovyMethods.sort(people,order)
+        def sorted = people.sort(false, order)
 
         assert sorted[0].first == 'Bob'
         assert sorted[0].age == '10'