Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 2,194   Methods: 335
NCLOC: 1,257   Classes: 15
 
 Source file Conditionals Statements Methods TOTAL
IterUtil.java 31.2% 32% 33.4% 32.3%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK*
 2   
 3    PLT Utilities BSD License
 4   
 5    Copyright (c) 2007-2010 JavaPLT group at Rice University
 6    All rights reserved.
 7   
 8    Developed by: Java Programming Languages Team
 9    Rice University
 10    http://www.cs.rice.edu/~javaplt/
 11   
 12    Redistribution and use in source and binary forms, with or without modification, are permitted
 13    provided that the following conditions are met:
 14   
 15    - Redistributions of source code must retain the above copyright notice, this list of conditions
 16    and the following disclaimer.
 17    - Redistributions in binary form must reproduce the above copyright notice, this list of
 18    conditions and the following disclaimer in the documentation and/or other materials provided
 19    with the distribution.
 20    - Neither the name of the JavaPLT group, Rice University, nor the names of the library's
 21    contributors may be used to endorse or promote products derived from this software without
 22    specific prior written permission.
 23   
 24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 25    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 26    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND
 27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 30    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 31    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   
 33    *END_COPYRIGHT_BLOCK*/
 34   
 35    package edu.rice.cs.plt.iter;
 36   
 37    import java.util.*;
 38    import java.lang.reflect.Array;
 39    import java.io.Reader;
 40    import java.io.InputStream;
 41    import java.io.IOException;
 42    import java.io.Serializable;
 43   
 44    import edu.rice.cs.plt.lambda.*;
 45    import edu.rice.cs.plt.tuple.*;
 46    import edu.rice.cs.plt.collect.CollectUtil;
 47    import edu.rice.cs.plt.collect.ConsList;
 48    import edu.rice.cs.plt.text.TextUtil;
 49    import edu.rice.cs.plt.object.ObjectUtil;
 50   
 51    /**
 52    * <p>A collection of static methods operating on iterables and iterators.</p>
 53    *
 54    * <p>Most classes instantiated by these methods are serializable. However, since the classes generally
 55    * wrap other objects, those objects must be serializable in order for serialization to succeed.</p>
 56    */
 57   
 58    public final class IterUtil {
 59   
 60    /** Prevents instance creation */
 61  0 private IterUtil() {}
 62   
 63    /** @return {@code true} iff the given iterable contains no elements */
 64  305 public static boolean isEmpty(Iterable<?> iter) {
 65  23 if (iter instanceof Collection<?>) { return ((Collection<?>) iter).isEmpty(); }
 66  258 else if (iter instanceof SizedIterable<?>) { return ((SizedIterable<?>) iter).isEmpty(); }
 67  24 else { return ! iter.iterator().hasNext(); }
 68    }
 69   
 70    /**
 71    * Compute the size of the given iterable. Where possible (when {@code iter} is a {@code SizedIterable} or a
 72    * {@code Collection}), this is a potentially constant-time operation; otherwise, it is linear in the size of
 73    * {@code iter} (if {@code iter} is infinite in this case, this method will loop {@code Integer.MAX_VALUE} times
 74    * before returning).
 75    */
 76  503 public static int sizeOf(Iterable<?> iter) {
 77  469 if (iter instanceof SizedIterable<?>) { return ((SizedIterable<?>) iter).size(); }
 78  34 else if (iter instanceof Collection<?>) { return ((Collection<?>) iter).size(); }
 79    else {
 80  0 int result = 0;
 81    // javac 1.5.0_16 crashes with this annotation
 82    //for (@SuppressWarnings("unused") Object o : iter) { result++; if (result == Integer.MAX_VALUE) break; }
 83  0 for (Object o : iter) { result++; if (result == Integer.MAX_VALUE) break; }
 84  0 return result;
 85    }
 86    }
 87   
 88    /**
 89    * Compute the size of the given iterable, or {@code bound} -- whichever is less. This allows a size to be
 90    * computed where the iterable may be infinite. Where possible (when {@code iter} is a {@code SizedIterable}
 91    * or a {@code Collection}), this is a potentially constant-time operation; otherwise, it is linear in the size
 92    * of {@code iter} or {@code bound} (whichever is smaller).
 93    */
 94  176 public static int sizeOf(Iterable<?> iter, int bound) {
 95  162 if (iter instanceof SizedIterable<?>) { return ((SizedIterable<?>) iter).size(bound); }
 96  14 else if (iter instanceof Collection<?>) {
 97  14 int result = ((Collection<?>) iter).size();
 98  14 return result <= bound ? result : bound;
 99    }
 100    else {
 101  0 int result = 0;
 102    // javac 1.5.0_16 crashes with this annotation
 103    //for (@SuppressWarnings("unused") Object o : iter) { result++; if (result == bound) break; }
 104  0 for (Object o : iter) { result++; if (result == bound) break; }
 105  0 return result;
 106    }
 107    }
 108   
 109    /**
 110    * Return {@code true} iff the given iterable is known to have an infinite size.
 111    * @see SizedIterable#isInfinite
 112    */
 113  23 public static boolean isInfinite(Iterable<?> iter) {
 114  23 if (iter instanceof SizedIterable<?>) { return ((SizedIterable<?>) iter).isInfinite(); }
 115  0 else { return false; }
 116    }
 117   
 118    /**
 119    * Return {@code true} iff the given iterable is known to have a fixed size. Infinite iterables are considered
 120    * fixed if they will never become finite.
 121    * @see SizedIterable#hasFixedSize
 122    */
 123  161 public static boolean hasFixedSize(Iterable<?> iter) {
 124  134 if (iter instanceof SizedIterable<?>) { return ((SizedIterable<?>) iter).hasFixedSize(); }
 125  27 else if (iter instanceof Collection<?>) { return isFixedSizeCollection((Collection<?>) iter); }
 126  0 else { return false; }
 127    }
 128   
 129    /** Return {@code true} iff the given collection is known to have a fixed size. */
 130  27 private static boolean isFixedSizeCollection(Collection<?> iter) {
 131  27 return (iter == Collections.EMPTY_SET) || (iter == Collections.EMPTY_LIST);
 132    }
 133   
 134    /**
 135    * Return {@code true} iff the given iterable is known to be immutable.
 136    * @see SizedIterable#isStatic
 137    */
 138  70 public static boolean isStatic(Iterable<?> iter) {
 139  53 if (iter instanceof SizedIterable<?>) { return ((SizedIterable<?>) iter).isStatic(); }
 140  17 else if (iter instanceof Collection<?>) { return isStaticCollection((Collection<?>) iter); }
 141  0 else { return false; }
 142    }
 143   
 144    /** Return {@code true} iff the given collection is known to be immutable. */
 145  17 private static boolean isStaticCollection(Collection<?> iter) {
 146  17 return (iter == Collections.EMPTY_SET) || (iter == Collections.EMPTY_LIST);
 147    }
 148   
 149    /**
 150    * Test whether the given object appears in an iteration of {@code iter}. Uses the
 151    * {@link Collection#contains} method where possible; otherwise, may take linear time.
 152    */
 153  56 public static boolean contains(Iterable<?> iter, Object o) {
 154  0 if (iter instanceof Collection<?>) { return ((Collection<?>) iter).contains(o); }
 155  56 else { return iteratedContains(iter, o); }
 156    }
 157   
 158    /**
 159    * Test whether the given objects all appear in when iterating over {@code iter}. Uses the
 160    * {@link Collection#containsAll} and {@link Collection#contains} methods where possible;
 161    * otherwise, may take quadratic time.
 162    * @see CollectUtil#containsAll
 163    * @see #and
 164    */
 165  8 public static boolean containsAll(Iterable<?> iter, Iterable<?> subset) {
 166  5 if (iter instanceof Collection<?>) { return CollectUtil.containsAll((Collection<?>) iter, subset); }
 167    else {
 168  3 for (Object o : subset) {
 169  0 if (!iteratedContains(iter, o)) { return false; }
 170    }
 171  3 return true;
 172    }
 173    }
 174   
 175    /**
 176    * Test whether one of the given objects appears in an iteration of {@code iter}. Uses the
 177    * {@link Collection#contains} method where possible; otherwise, may take quadratic time.
 178    * @see #or
 179    */
 180  0 public static boolean containsAny(Iterable<?> iter, Iterable<?> candidates) {
 181  0 if (iter instanceof Collection<?>) { return CollectUtil.containsAny((Collection<?>) iter, candidates); }
 182    else {
 183  0 for (Object o : candidates) {
 184  0 if (iteratedContains(iter, o)) { return true; }
 185    }
 186  0 return false;
 187    }
 188    }
 189   
 190  84 private static boolean iteratedContains(Iterable<?> iter, Object o) {
 191  84 if (o == null) {
 192  0 for (Object elt : iter) {
 193  0 if (elt == null) { return true; }
 194    }
 195  0 return false;
 196    }
 197    else {
 198  84 for (Object elt : iter) {
 199  60 if (o.equals(elt)) { return true; }
 200    }
 201  24 return false;
 202    }
 203    }
 204   
 205    /**
 206    * Generate a string representation of the given iterable, matching the {@link Collection}
 207    * conventions (results like {@code "[foo, bar, baz]"}). Invokes
 208    * {@link TextUtil#toString(Object)} on each element. If the iterable is known to be
 209    * infinite ({@link #isInfinite}), the string contains a few elements followed by {@code "..."}.
 210    */
 211  12 public static String toString(Iterable<?> iter) {
 212  12 return toString(iter, "[", ", ", "]");
 213    }
 214   
 215    /**
 216    * Generate a string representation of the given iterable where each element is listed on a
 217    * separate line. Invokes {@link TextUtil#toString(Object)} on each element. If the iterable
 218    * is known to be infinite ({@link #isInfinite}), the string contains a few elements followed by
 219    * {@code "..."}.
 220    */
 221  0 public static String multilineToString(Iterable<?> iter) {
 222  0 return toString(iter, "", TextUtil.NEWLINE, "");
 223    }
 224   
 225    /**
 226    * Generate a string representation of the given iterable beginning with {@code prefix}, ending with
 227    * {@code suffix}, and delimited by {@code delimiter}. Invokes {@link TextUtil#toString(Object)}
 228    * on each element. If the iterable is known to be infinite ({@link #isInfinite}), the string contains
 229    * a few elements followed by {@code "..."}.
 230    */
 231  23 public static String toString(Iterable<?> iter, String prefix, String delimiter, String suffix) {
 232  0 if (isInfinite(iter)) { iter = compose(new TruncatedIterable<Object>(iter, 8), "..."); }
 233  23 StringBuilder result = new StringBuilder();
 234  23 result.append(prefix);
 235  23 boolean first = true;
 236  23 for (Object obj : iter) {
 237  21 if (first) { first = false; }
 238  145 else { result.append(delimiter); }
 239  166 result.append(TextUtil.toString(obj));
 240    }
 241  23 result.append(suffix);
 242  23 return result.toString();
 243    }
 244   
 245    /**
 246    * Return {@code true} iff the lists are identical (according to {@code ==}), or they
 247    * have the same size (according to {@link #sizeOf}) and each corresponding element is equal
 248    * (according to {@link LambdaUtil#EQUAL}). Assumes that at least one of the iterables is finite.
 249    */
 250  167 public static boolean isEqual(Iterable<?> iter1, Iterable<?> iter2) {
 251  12 if (iter1 == iter2) { return true; }
 252  155 else if (sizeOf(iter1) == sizeOf(iter2)) { return and(iter1, iter2, LambdaUtil.EQUAL); }
 253  0 else { return false; }
 254    }
 255   
 256    /**
 257    * Return a hash code computed based on the hashes of each element. The result is consistent
 258    * with {@link #isEqual}, but may not be consistent with the input's {@code equals} and
 259    * {@code hashCode} methods. Assumes the iterable is finite. Implemented with
 260    * {@link ObjectUtil#hash(Iterable)}.
 261    */
 262  0 public static int hashCode(Iterable<?> iter) {
 263  0 return ObjectUtil.hash(iter);
 264    }
 265   
 266    /**
 267    * Make an iterator based on a (legacy-style) {@link Enumeration}. If an {@code Iterable} is
 268    * needed (rather than an {@code Iterator}), the result can be wrapped in a
 269    * {@link ReadOnceIterable}.
 270    */
 271  0 public static <T> ReadOnlyIterator<T> asIterator(final Enumeration<? extends T> en) {
 272  0 return new ReadOnlyIterator<T>() {
 273  0 public boolean hasNext() { return en.hasMoreElements(); }
 274  0 public T next() { return en.nextElement(); }
 275    };
 276    }
 277   
 278    /**
 279    * Make an iterator based on a {@link StringTokenizer}. (This is similar to
 280    * {@link #asIterator(Enumeration)}, but allows the tokenizer to be treated as an enumeration
 281    * of {@code String}s rather than, as defined, an enumeration of {@code Object}s.) If an
 282    * {@code Iterable} is needed (rather than an {@code Iterator}), the result can be wrapped in a
 283    * {@link ReadOnceIterable}.
 284    */
 285  0 public static ReadOnlyIterator<String> asIterator(final StringTokenizer s) {
 286  0 return new ReadOnlyIterator<String>() {
 287  0 public boolean hasNext() { return s.hasMoreTokens(); }
 288  0 public String next() { return s.nextToken(); }
 289    };
 290    }
 291   
 292    /**
 293    * Make an iterator based on a {@link Reader}. If an {@link IOException}
 294    * occurs while reading, an {@link IllegalStateException} is thrown. If an
 295    * {@code Iterable} is needed (rather than an {@code Iterator}), the result
 296    * can be wrapped in a {@link ReadOnceIterable}.
 297    */
 298  2 public static ReadOnlyIterator<Character> asIterator(final Reader in) {
 299  2 return new ReadOnlyIterator<Character>() {
 300    private int _lookahead = readNext();
 301   
 302  5 public boolean hasNext() { return _lookahead >= 0; }
 303   
 304  3 public Character next() {
 305  0 if (_lookahead < 0) { throw new NoSuchElementException(); }
 306  3 Character result = (char) _lookahead;
 307  3 _lookahead = readNext();
 308  3 return result;
 309    }
 310   
 311  5 private int readNext() {
 312  5 try { return in.read(); }
 313  0 catch (IOException e) { throw new IllegalStateException(e); }
 314    }
 315   
 316    };
 317    }
 318   
 319    /**
 320    * Make an iterator based on an {@link InputStream}. If an {@link IOException}
 321    * occurs while reading, an {@link IllegalStateException} is thrown. If an
 322    * {@code Iterable} is needed (rather than an {@code Iterator}), the result
 323    * can be wrapped in a {@link ReadOnceIterable}.
 324    */
 325  2 public static ReadOnlyIterator<Byte> asIterator(final InputStream in) {
 326  2 return new ReadOnlyIterator<Byte>() {
 327    private int _lookahead = readNext();
 328   
 329  5 public boolean hasNext() { return _lookahead >= 0; }
 330   
 331  3 public Byte next() {
 332  0 if (_lookahead < 0) { throw new NoSuchElementException(); }
 333  3 Byte result = (byte) _lookahead;
 334  3 _lookahead = readNext();
 335  3 return result;
 336    }
 337   
 338  5 private int readNext() {
 339  5 try { return in.read(); }
 340  0 catch (IOException e) { throw new IllegalStateException(e); }
 341    }
 342   
 343    };
 344    }
 345   
 346    /** Make an {@code Enumeration} based on the given {@code Iterator}. For compatibility with legacy APIs. */
 347  0 public static <T> Enumeration<T> asEnumeration(final Iterator<? extends T> iter) {
 348  0 return new Enumeration<T>() {
 349  0 public boolean hasMoreElements() { return iter.hasNext(); }
 350  0 public T nextElement() { return iter.next(); }
 351    };
 352    }
 353   
 354   
 355    /** Create an {@link EmptyIterable}; equivalent to {@link #make()}. */
 356  47 @SuppressWarnings("unchecked") public static <T> EmptyIterable<T> empty() {
 357  47 return (EmptyIterable<T>) EmptyIterable.INSTANCE;
 358    }
 359   
 360    /** Create a {@link SingletonIterable}; equivalent to {@link #make(Object)}. */
 361  17 public static <T> SingletonIterable<T> singleton(T value) {
 362  17 return new SingletonIterable<T>(value);
 363    }
 364   
 365    /** Create a {@link ComposedIterable} with the given arguments. */
 366  0 public static <T> ComposedIterable<T> compose(T first, Iterable<? extends T> rest) {
 367  0 return new ComposedIterable<T>(first, rest);
 368    }
 369   
 370    /** Produce a lambda that invokes {@link #compose(Object, Iterable)}. */
 371  0 @SuppressWarnings("unchecked") public static <T> Lambda2<T, Iterable<? extends T>, Iterable<T>> composeLeftLambda() {
 372  0 return (Lambda2<T, Iterable<? extends T>, Iterable<T>>) (Lambda2<?, ?, ?>) ComposeLeftLambda.INSTANCE;
 373    }
 374   
 375    private static class ComposeLeftLambda<T> implements Lambda2<T, Iterable<? extends T>, Iterable<T>>, Serializable {
 376    private static ComposeLeftLambda<Object> INSTANCE = new ComposeLeftLambda<Object>();
 377  0 private ComposeLeftLambda() {}
 378  0 public Iterable<T> value(T first, Iterable<? extends T> rest) {
 379  0 return new ComposedIterable<T>(first, rest);
 380    }
 381    }
 382   
 383    /** Create a {@link ComposedIterable} with the given arguments. */
 384  22 public static <T> ComposedIterable<T> compose(Iterable<? extends T> rest, T last) {
 385  22 return new ComposedIterable<T>(rest, last);
 386    }
 387   
 388    /** Produce a lambda that invokes {@link #compose(Iterable, Object)}. */
 389  1 @SuppressWarnings("unchecked") public static <T> Lambda2<Iterable<? extends T>, T, Iterable<T>> composeRightLambda() {
 390  1 return (Lambda2<Iterable<? extends T>, T, Iterable<T>>) (Lambda2<?, ?, ?>) ComposeRightLambda.INSTANCE;
 391    }
 392   
 393    private static class ComposeRightLambda<T> implements Lambda2<Iterable<? extends T>, T, Iterable<T>>, Serializable {
 394    private static ComposeRightLambda<Object> INSTANCE = new ComposeRightLambda<Object>();
 395  1 private ComposeRightLambda() {}
 396  8 public Iterable<T> value(Iterable<? extends T> rest, T last) {
 397  8 return new ComposedIterable<T>(rest, last);
 398    }
 399    }
 400   
 401    /** Create a {@link ComposedIterable} with the given arguments. */
 402  10 public static <T> ComposedIterable<T> compose(Iterable<? extends T> i1, Iterable<? extends T> i2) {
 403  10 return new ComposedIterable<T>(i1, i2);
 404    }
 405   
 406    /** Produce a lambda that invokes {@link #compose(Object, Iterable)}. */
 407  0 @SuppressWarnings("unchecked")
 408    public static <T> Lambda2<Iterable<? extends T>, Iterable<? extends T>, Iterable<T>> composeLambda() {
 409  0 return (Lambda2<Iterable<? extends T>, Iterable<? extends T>, Iterable<T>>) (Lambda2<?, ?, ?>)
 410    ComposeLambda.INSTANCE;
 411    }
 412   
 413    private static class ComposeLambda<T>
 414    implements Lambda2<Iterable<? extends T>, Iterable<? extends T>, Iterable<T>>, Serializable {
 415    private static ComposeLambda<Object> INSTANCE = new ComposeLambda<Object>();
 416  0 private ComposeLambda() {}
 417  0 public Iterable<T> value(Iterable<? extends T> i1, Iterable<? extends T> i2) {
 418  0 return new ComposedIterable<T>(i1, i2);
 419    }
 420    }
 421   
 422   
 423    /** Create a {@link SnapshotIterable} with the given iterable. */
 424  85 public static <T> SnapshotIterable<T> snapshot(Iterable<? extends T> iter) {
 425  85 return new SnapshotIterable<T>(iter);
 426    }
 427   
 428    /** Create a {@link SnapshotIterable} with the given iterator. */
 429  9 public static <T> SnapshotIterable<T> snapshot(Iterator<? extends T> iter) {
 430  9 return new SnapshotIterable<T>(iter);
 431    }
 432   
 433    /**
 434    * Produce a snapshot of {@code iter} if its composite size is greater than the given threshold.
 435    * @see ObjectUtil#compositeSize
 436    */
 437  0 public static <T> Iterable<T> conditionalSnapshot(Iterable<T> iter, int threshold) {
 438  0 if (ObjectUtil.compositeSize(iter) > threshold) { return new SnapshotIterable<T>(iter); }
 439  0 else { return iter; }
 440    }
 441   
 442    /** Produce an {@link ImmutableIterable} with the given iterable. */
 443  0 public static <T> ImmutableIterable<T> immutable(Iterable<? extends T> iter) {
 444  0 return new ImmutableIterable<T>(iter);
 445    }
 446   
 447    /**
 448    * Allow covariance in situations where wildcards can't be used by wrapping the iterable with a less-
 449    * precise type parameter.
 450    */
 451  1 public static <T> SizedIterable<T> relax(Iterable<? extends T> iter) {
 452  1 return new ImmutableIterable<T>(iter);
 453    }
 454   
 455    /**
 456    * Allow covariance in situations where wildcards can't be used by wraping the iterator with a less-
 457    * precise type parameter.
 458    */
 459  1 public static <T> Iterator<T> relax(Iterator<? extends T> iter) {
 460  1 return new ImmutableIterator<T>(iter);
 461    }
 462   
 463    /** Create an immutable SizedIterable containing the given values. */
 464  0 public static <T> SizedIterable<T> make() {
 465  0 @SuppressWarnings("unchecked") EmptyIterable<T> result = (EmptyIterable<T>) EmptyIterable.INSTANCE;
 466  0 return result;
 467    }
 468   
 469    /** Create an immutable SizedIterable containing the given values. */
 470  3 public static <T> SizedIterable<T> make(T v1) {
 471  3 return new SingletonIterable<T>(v1);
 472    }
 473   
 474    /** Create an immutable SizedIterable containing the given values. */
 475  7 public static <T> SizedIterable<T> make(T v1, T v2) {
 476  7 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2 };
 477  7 return new ObjectArrayWrapper<T>(values, false);
 478    }
 479   
 480    /** Create an immutable SizedIterable containing the given values. */
 481  7 public static <T> SizedIterable<T> make(T v1, T v2, T v3) {
 482  7 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3 };
 483  7 return new ObjectArrayWrapper<T>(values, false);
 484    }
 485   
 486    /** Create an immutable SizedIterable containing the given values. */
 487  1 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4) {
 488  1 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4 };
 489  1 return new ObjectArrayWrapper<T>(values, false);
 490    }
 491   
 492    /** Create an immutable SizedIterable containing the given values. */
 493  3 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4, T v5) {
 494  3 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4, v5 };
 495  3 return new ObjectArrayWrapper<T>(values, false);
 496    }
 497   
 498    /** Create an immutable SizedIterable containing the given values. */
 499  2 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4, T v5, T v6) {
 500  2 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4, v5, v6 };
 501  2 return new ObjectArrayWrapper<T>(values, false);
 502    }
 503   
 504    /** Create an immutable SizedIterable containing the given values. */
 505  0 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4, T v5, T v6, T v7) {
 506  0 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4, v5, v6 , v7 };
 507  0 return new ObjectArrayWrapper<T>(values, false);
 508    }
 509   
 510    /** Create an immutable SizedIterable containing the given values. */
 511  1 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8) {
 512  1 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4, v5, v6 , v7, v8 };
 513  1 return new ObjectArrayWrapper<T>(values, false);
 514    }
 515   
 516    /** Create an immutable SizedIterable containing the given values. */
 517  7 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9) {
 518  7 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4, v5, v6 , v7, v8, v9 };
 519  7 return new ObjectArrayWrapper<T>(values, false);
 520    }
 521   
 522    /** Create an immutable SizedIterable containing the given values. */
 523  0 public static <T> SizedIterable<T> make(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9, T v10) {
 524  0 @SuppressWarnings("unchecked") T[] values = (T[]) new Object[]{ v1, v2, v3, v4, v5, v6 , v7, v8, v9, v10 };
 525  0 return new ObjectArrayWrapper<T>(values, false);
 526    }
 527   
 528    /**
 529    * Create an immutable SizedIterable containing the given values. Requires linear time to make a copy
 530    * (necessary because {@code vals} can be mutated by the caller). Note that restrictions on array
 531    * creation may lead to errors or warnings at the invocation site where {@code T} is a non-reifiable type.
 532    */
 533  24 public static <T> SizedIterable<T> make(T... vals) {
 534  24 return snapshot(new ObjectArrayWrapper<T>(vals));
 535    }
 536   
 537    /**
 538    * Create an immutable SizedIterable containing the given values, from index {@code start} through the end
 539    * of the array. Requires linear time to make a copy (necessary because {@code vals} can be mutated by the
 540    * caller).
 541    */
 542  0 public static <T> SizedIterable<T> make(T[] vals, int start) {
 543  0 return snapshot(new ObjectArrayWrapper<T>(vals, start));
 544    }
 545   
 546    /**
 547    * Create an immutable SizedIterable containing the given values, from array index {@code start} through
 548    * {@code end-1}, inclusive (the size of the result is {@code end-start}). Requires linear time to make a
 549    * copy (necessary because {@code vals} can be mutated by the caller).
 550    */
 551  0 public static <T> SizedIterable<T> make(T[] vals, int start, int end) {
 552  0 return snapshot(new ObjectArrayWrapper<T>(vals, start, end));
 553    }
 554   
 555   
 556    /** Create an infinite sequence defined by an initial value and a successor function. */
 557  0 public static <T> SequenceIterable<T> infiniteSequence(T initial, Lambda<? super T, ? extends T> successor) {
 558  0 return new SequenceIterable<T>(initial, successor);
 559    }
 560   
 561    /** Create a finite sequence of the given size defined by an initial value and a successor function. */
 562  0 public static <T> FiniteSequenceIterable<T> finiteSequence(T initial, Lambda<? super T, ? extends T> successor,
 563    int size) {
 564  0 return new FiniteSequenceIterable<T>(initial, successor, size);
 565    }
 566   
 567    /**
 568    * Create a simple sequence containing the numbers between {@code start} and {@code end}
 569    * (inclusive). {@code start} may be less than <em>or</em> greater than {@code end} (or even
 570    * equal to it); the resulting iterator will increment or decrement as necessary.
 571    */
 572  0 public static FiniteSequenceIterable<Integer> integerSequence(int start, int end) {
 573  0 return FiniteSequenceIterable.makeIntegerSequence(start, end);
 574    }
 575   
 576    /** Create a sequence containing {@code copies} instances of the given value. */
 577  0 public static <T> FiniteSequenceIterable<T> copy(T value, int copies) {
 578  0 return FiniteSequenceIterable.makeCopies(value, copies);
 579    }
 580   
 581    /**
 582    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 583    * result. (If that is not the desired behavior, make a copy instead with {@link #make(Object[])}.)
 584    */
 585  252 public static <T> SizedIterable<T> asIterable(T... array) {
 586  252 return new ObjectArrayWrapper<T>(array);
 587    }
 588   
 589    /**
 590    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 591    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 592    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 593    * and potential memory leaks, make a copy instead with {@link #make(Object[], int)}.)
 594    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 595    */
 596  18 public static <T> SizedIterable<T> arraySegment(T[] array, int start) {
 597  18 return new ObjectArrayWrapper<T>(array, start);
 598    }
 599   
 600    /**
 601    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 602    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 603    * will be reflected in the result; also note that entire array will remain in memory until references to
 604    * this segment are discarded. (To prevent mutation and potential memory leaks, make a copy instead with
 605    * {@link #make(Object[], int, int)}.)
 606    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 607    * with the length of the array.
 608    */
 609  0 public static <T> SizedIterable<T> arraySegment(T[] array, int start, int end) {
 610  0 return new ObjectArrayWrapper<T>(array, start, end);
 611    }
 612   
 613    private static final class ObjectArrayWrapper<T> extends AbstractIterable<T>
 614    implements SizedIterable<T>, OptimizedLastIterable<T>, Serializable {
 615    private final T[] _array;
 616    private final int _start; // start index
 617    private final int _end; // 1 + the last index
 618    private final boolean _refs; // whether there may be other references to _array (allowing mutation)
 619   
 620  277 public ObjectArrayWrapper(T[] array) { this(array, 0, array.length, true); }
 621   
 622  18 public ObjectArrayWrapper(T[] array, int start) {
 623  18 this(array, start, array.length, true);
 624  0 if (_start < 0 || _start > _end) { throw new IndexOutOfBoundsException(); }
 625    }
 626   
 627  0 public ObjectArrayWrapper(T[] array, int start, int end) {
 628  0 this(array, start, end, true);
 629  0 if (_start < 0 || _start > _end || _end > _array.length) { throw new IndexOutOfBoundsException(); }
 630    }
 631   
 632  28 public ObjectArrayWrapper(T[] array, boolean refs) { this(array, 0, array.length, refs); }
 633   
 634  323 public ObjectArrayWrapper(T[] array, int start, int end, boolean refs) {
 635  323 _array = array;
 636  323 _start = start;
 637  323 _end = end;
 638  323 _refs = refs;
 639    }
 640   
 641  160 public boolean isEmpty() { return _start == _end; }
 642  212 public int size() { return _end-_start; }
 643  160 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 644  5 public boolean isInfinite() { return false; }
 645  74 public boolean hasFixedSize() { return true; }
 646  0 public boolean isStatic() { return !_refs; }
 647  0 public T last() { return _array[_end-1]; }
 648   
 649  398 public Iterator<T> iterator() {
 650  398 return new IndexedIterator<T>() {
 651  1022 protected int size() { return _end-_start; }
 652  880 protected T get(int i) { return _array[_start+i]; }
 653    };
 654    }
 655    }
 656   
 657    /**
 658    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 659    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 660    */
 661  1 public static SizedIterable<Boolean> asIterable(boolean[] array) {
 662  1 return new BooleanArrayWrapper(array);
 663    }
 664   
 665    /**
 666    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 667    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 668    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 669    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 670    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 671    */
 672  0 public static SizedIterable<Boolean> arraySegment(boolean[] array, int start) {
 673  0 return new BooleanArrayWrapper(array, start);
 674    }
 675   
 676    /**
 677    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 678    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 679    * will be reflected in the result; also note that entire array will remain in memory until references to
 680    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 681    * may be invoked on the result.)
 682    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 683    * with the length of the array.
 684    */
 685  0 public static SizedIterable<Boolean> arraySegment(boolean[] array, int start, int end) {
 686  0 return new BooleanArrayWrapper(array, start, end);
 687    }
 688   
 689    private static final class BooleanArrayWrapper extends AbstractIterable<Boolean>
 690    implements SizedIterable<Boolean>, OptimizedLastIterable<Boolean>, Serializable {
 691    private final boolean[] _array;
 692    private final int _start; // start index
 693    private final int _end; // 1 + the last index
 694  2 public BooleanArrayWrapper(boolean[] array) { _array = array; _start = 0; _end = _array.length; }
 695  0 public BooleanArrayWrapper(boolean[] array, int start) {
 696  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 697  0 _array = array; _start = start; _end = array.length;
 698    }
 699  0 public BooleanArrayWrapper(boolean[] array, int start, int end) {
 700  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 701  0 _array = array; _start = start; _end = end;
 702    }
 703   
 704  2 public boolean isEmpty() { return _start == _end; }
 705  0 public int size() { return _end-_start; }
 706  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 707  0 public boolean isInfinite() { return false; }
 708  0 public boolean hasFixedSize() { return true; }
 709  0 public boolean isStatic() { return false; }
 710  0 public Boolean last() { return _array[_end-1]; }
 711  0 public Iterator<Boolean> iterator() {
 712  0 return new IndexedIterator<Boolean>() {
 713  0 protected int size() { return _end-_start; }
 714  0 protected Boolean get(int i) { return _array[_start+i]; }
 715    };
 716    }
 717    }
 718   
 719    /**
 720    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 721    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 722    */
 723  1 public static SizedIterable<Character> asIterable(char[] array) {
 724  1 return new CharArrayWrapper(array);
 725    }
 726   
 727    /**
 728    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 729    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 730    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 731    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 732    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 733    */
 734  0 public static SizedIterable<Character> arraySegment(char[] array, int start) {
 735  0 return new CharArrayWrapper(array, start);
 736    }
 737   
 738    /**
 739    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 740    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 741    * will be reflected in the result; also note that entire array will remain in memory until references to
 742    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 743    * may be invoked on the result.)
 744    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 745    * with the length of the array.
 746    */
 747  0 public static SizedIterable<Character> arraySegment(char[] array, int start, int end) {
 748  0 return new CharArrayWrapper(array, start, end);
 749    }
 750   
 751    private static final class CharArrayWrapper extends AbstractIterable<Character>
 752    implements SizedIterable<Character>, OptimizedLastIterable<Character>, Serializable {
 753    private final char[] _array;
 754    private final int _start; // start index
 755    private final int _end; // 1 + the last index
 756  2 public CharArrayWrapper(char[] array) { _array = array; _start = 0; _end = _array.length; }
 757  0 public CharArrayWrapper(char[] array, int start) {
 758  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 759  0 _array = array; _start = start; _end = array.length;
 760    }
 761  0 public CharArrayWrapper(char[] array, int start, int end) {
 762  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 763  0 _array = array; _start = start; _end = end;
 764    }
 765   
 766  2 public boolean isEmpty() { return _start == _end; }
 767  0 public int size() { return _end-_start; }
 768  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 769  0 public boolean isInfinite() { return false; }
 770  0 public boolean hasFixedSize() { return true; }
 771  0 public boolean isStatic() { return false; }
 772  0 public Character last() { return _array[_end-1]; }
 773  0 public Iterator<Character> iterator() {
 774  0 return new IndexedIterator<Character>() {
 775  0 protected int size() { return _end-_start; }
 776  0 protected Character get(int i) { return _array[_start+i]; }
 777    };
 778    }
 779    }
 780   
 781    /**
 782    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 783    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 784    */
 785  1 public static SizedIterable<Byte> asIterable(byte[] values) {
 786  1 return new ByteArrayWrapper(values);
 787    }
 788    /**
 789    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 790    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 791    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 792    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 793    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 794    */
 795  0 public static SizedIterable<Byte> arraySegment(byte[] array, int start) {
 796  0 return new ByteArrayWrapper(array, start);
 797    }
 798   
 799    /**
 800    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 801    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 802    * will be reflected in the result; also note that entire array will remain in memory until references to
 803    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 804    * may be invoked on the result.)
 805    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 806    * with the length of the array.
 807    */
 808  0 public static SizedIterable<Byte> arraySegment(byte[] array, int start, int end) {
 809  0 return new ByteArrayWrapper(array, start, end);
 810    }
 811   
 812    private static final class ByteArrayWrapper extends AbstractIterable<Byte>
 813    implements SizedIterable<Byte>, OptimizedLastIterable<Byte>, Serializable {
 814    private final byte[] _array;
 815    private final int _start; // start index
 816    private final int _end; // 1 + the last index
 817  2 public ByteArrayWrapper(byte[] array) { _array = array; _start = 0; _end = _array.length; }
 818  0 public ByteArrayWrapper(byte[] array, int start) {
 819  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 820  0 _array = array; _start = start; _end = array.length;
 821    }
 822  0 public ByteArrayWrapper(byte[] array, int start, int end) {
 823  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 824  0 _array = array; _start = start; _end = end;
 825    }
 826   
 827  2 public boolean isEmpty() { return _start == _end; }
 828  0 public int size() { return _end-_start; }
 829  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 830  0 public boolean isInfinite() { return false; }
 831  0 public boolean hasFixedSize() { return true; }
 832  0 public boolean isStatic() { return false; }
 833  0 public Byte last() { return _array[_end-1]; }
 834  0 public Iterator<Byte> iterator() {
 835  0 return new IndexedIterator<Byte>() {
 836  0 protected int size() { return _end-_start; }
 837  0 protected Byte get(int i) { return _array[_start+i]; }
 838    };
 839    }
 840    }
 841   
 842    /**
 843    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 844    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 845    */
 846  1 public static SizedIterable<Short> asIterable(short[] values) {
 847  1 return new ShortArrayWrapper(values);
 848    }
 849    /**
 850    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 851    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 852    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 853    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 854    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 855    */
 856  0 public static SizedIterable<Short> arraySegment(short[] array, int start) {
 857  0 return new ShortArrayWrapper(array, start);
 858    }
 859   
 860    /**
 861    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 862    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 863    * will be reflected in the result; also note that entire array will remain in memory until references to
 864    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 865    * may be invoked on the result.)
 866    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 867    * with the length of the array.
 868    */
 869  0 public static SizedIterable<Short> arraySegment(short[] array, int start, int end) {
 870  0 return new ShortArrayWrapper(array, start, end);
 871    }
 872   
 873    private static final class ShortArrayWrapper extends AbstractIterable<Short>
 874    implements SizedIterable<Short>, OptimizedLastIterable<Short>, Serializable {
 875    private final short[] _array;
 876    private final int _start; // start index
 877    private final int _end; // 1 + the last index
 878  2 public ShortArrayWrapper(short[] array) { _array = array; _start = 0; _end = _array.length; }
 879  0 public ShortArrayWrapper(short[] array, int start) {
 880  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 881  0 _array = array; _start = start; _end = array.length;
 882    }
 883  0 public ShortArrayWrapper(short[] array, int start, int end) {
 884  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 885  0 _array = array; _start = start; _end = end;
 886    }
 887   
 888  2 public boolean isEmpty() { return _start == _end; }
 889  0 public int size() { return _end-_start; }
 890  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 891  0 public boolean isInfinite() { return false; }
 892  0 public boolean hasFixedSize() { return true; }
 893  0 public boolean isStatic() { return false; }
 894  0 public Short last() { return _array[_end-1]; }
 895  0 public Iterator<Short> iterator() {
 896  0 return new IndexedIterator<Short>() {
 897  0 protected int size() { return _end-_start; }
 898  0 protected Short get(int i) { return _array[_start+i]; }
 899    };
 900    }
 901    }
 902   
 903    /**
 904    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 905    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 906    */
 907  2 public static SizedIterable<Integer> asIterable(int[] values) {
 908  2 return new IntArrayWrapper(values);
 909    }
 910   
 911    /**
 912    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 913    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 914    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 915    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 916    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 917    */
 918  0 public static SizedIterable<Integer> arraySegment(int[] array, int start) {
 919  0 return new IntArrayWrapper(array, start);
 920    }
 921   
 922    /**
 923    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 924    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 925    * will be reflected in the result; also note that entire array will remain in memory until references to
 926    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 927    * may be invoked on the result.)
 928    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 929    * with the length of the array.
 930    */
 931  0 public static SizedIterable<Integer> arraySegment(int[] array, int start, int end) {
 932  0 return new IntArrayWrapper(array, start, end);
 933    }
 934   
 935    private static final class IntArrayWrapper extends AbstractIterable<Integer>
 936    implements SizedIterable<Integer>, OptimizedLastIterable<Integer>, Serializable {
 937    private final int[] _array;
 938    private final int _start; // start index
 939    private final int _end; // 1 + the last index
 940  3 public IntArrayWrapper(int[] array) { _array = array; _start = 0; _end = _array.length; }
 941  0 public IntArrayWrapper(int[] array, int start) {
 942  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 943  0 _array = array; _start = start; _end = array.length;
 944    }
 945  0 public IntArrayWrapper(int[] array, int start, int end) {
 946  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 947  0 _array = array; _start = start; _end = end;
 948    }
 949   
 950  2 public boolean isEmpty() { return _start == _end; }
 951  0 public int size() { return _end-_start; }
 952  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 953  0 public boolean isInfinite() { return false; }
 954  0 public boolean hasFixedSize() { return true; }
 955  0 public boolean isStatic() { return false; }
 956  0 public Integer last() { return _array[_end-1]; }
 957  1 public Iterator<Integer> iterator() {
 958  1 return new IndexedIterator<Integer>() {
 959  6 protected int size() { return _end-_start; }
 960  5 protected Integer get(int i) { return _array[_start+i]; }
 961    };
 962    }
 963    }
 964   
 965    /**
 966    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 967    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 968    */
 969  1 public static SizedIterable<Long> asIterable(long[] values) {
 970  1 return new LongArrayWrapper(values);
 971    }
 972   
 973    /**
 974    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 975    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 976    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 977    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 978    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 979    */
 980  0 public static SizedIterable<Long> arraySegment(long[] array, int start) {
 981  0 return new LongArrayWrapper(array, start);
 982    }
 983   
 984    /**
 985    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 986    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 987    * will be reflected in the result; also note that entire array will remain in memory until references to
 988    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 989    * may be invoked on the result.)
 990    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 991    * with the length of the array.
 992    */
 993  0 public static SizedIterable<Long> arraySegment(long[] array, int start, int end) {
 994  0 return new LongArrayWrapper(array, start, end);
 995    }
 996   
 997    private static final class LongArrayWrapper extends AbstractIterable<Long>
 998    implements SizedIterable<Long>, OptimizedLastIterable<Long>, Serializable {
 999    private final long[] _array;
 1000    private final int _start; // start index
 1001    private final int _end; // 1 + the last index
 1002  2 public LongArrayWrapper(long[] array) { _array = array; _start = 0; _end = _array.length; }
 1003  0 public LongArrayWrapper(long[] array, int start) {
 1004  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 1005  0 _array = array; _start = start; _end = array.length;
 1006    }
 1007  0 public LongArrayWrapper(long[] array, int start, int end) {
 1008  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 1009  0 _array = array; _start = start; _end = end;
 1010    }
 1011   
 1012  2 public boolean isEmpty() { return _start == _end; }
 1013  0 public int size() { return _end-_start; }
 1014  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 1015  0 public boolean isInfinite() { return false; }
 1016  0 public boolean hasFixedSize() { return true; }
 1017  0 public boolean isStatic() { return false; }
 1018  0 public Long last() { return _array[_end-1]; }
 1019  0 public Iterator<Long> iterator() {
 1020  0 return new IndexedIterator<Long>() {
 1021  0 protected int size() { return _end-_start; }
 1022  0 protected Long get(int i) { return _array[_start+i]; }
 1023    };
 1024    }
 1025    }
 1026   
 1027    /**
 1028    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 1029    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 1030    */
 1031  1 public static SizedIterable<Float> asIterable(float[] values) {
 1032  1 return new FloatArrayWrapper(values);
 1033    }
 1034   
 1035    /**
 1036    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 1037    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 1038    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 1039    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 1040    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 1041    */
 1042  0 public static SizedIterable<Float> arraySegment(float[] array, int start) {
 1043  0 return new FloatArrayWrapper(array, start);
 1044    }
 1045   
 1046    /**
 1047    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 1048    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 1049    * will be reflected in the result; also note that entire array will remain in memory until references to
 1050    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 1051    * may be invoked on the result.)
 1052    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 1053    * with the length of the array.
 1054    */
 1055  0 public static SizedIterable<Float> arraySegment(float[] array, int start, int end) {
 1056  0 return new FloatArrayWrapper(array, start, end);
 1057    }
 1058   
 1059    private static final class FloatArrayWrapper extends AbstractIterable<Float>
 1060    implements SizedIterable<Float>, OptimizedLastIterable<Float>, Serializable {
 1061    private final float[] _array;
 1062    private final int _start; // start index
 1063    private final int _end; // 1 + the last index
 1064  2 public FloatArrayWrapper(float[] array) { _array = array; _start = 0; _end = _array.length; }
 1065  0 public FloatArrayWrapper(float[] array, int start) {
 1066  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 1067  0 _array = array; _start = start; _end = array.length;
 1068    }
 1069  0 public FloatArrayWrapper(float[] array, int start, int end) {
 1070  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 1071  0 _array = array; _start = start; _end = end;
 1072    }
 1073   
 1074  2 public boolean isEmpty() { return _start == _end; }
 1075  0 public int size() { return _end-_start; }
 1076  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 1077  0 public boolean isInfinite() { return false; }
 1078  0 public boolean hasFixedSize() { return true; }
 1079  0 public boolean isStatic() { return false; }
 1080  0 public Float last() { return _array[_end-1]; }
 1081  0 public Iterator<Float> iterator() {
 1082  0 return new IndexedIterator<Float>() {
 1083  0 protected int size() { return _end-_start; }
 1084  0 protected Float get(int i) { return _array[_start+i]; }
 1085    };
 1086    }
 1087    }
 1088   
 1089    /**
 1090    * Create a SizedIterable wrapping the given array. Subsequent changes to the array will be reflected in the
 1091    * result. (If that is not the desired behavior, {@link #snapshot(Iterable)} may be invoked on the result.)
 1092    */
 1093  1 public static SizedIterable<Double> asIterable(double[] values) {
 1094  1 return new DoubleArrayWrapper(values);
 1095    }
 1096   
 1097    /**
 1098    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through the
 1099    * end of the array are included. Subsequent changes to the array will be reflected in the result; also note
 1100    * that entire array will remain in memory until references to this segment are discarded. (To prevent mutation
 1101    * and potential memory leaks, {@link #snapshot(Iterable)} may be invoked on the result.)
 1102    * @throws IndexOutOfBoundsException If {@code start} is an invalid index.
 1103    */
 1104  0 public static SizedIterable<Double> arraySegment(double[] array, int start) {
 1105  0 return new DoubleArrayWrapper(array, start);
 1106    }
 1107   
 1108    /**
 1109    * Create a SizedIterable wrapping a segment of the given array. Elements from index {@code start} through
 1110    * {@code end-1} are included (and the size is thus {@code end-start}). Subsequent changes to the array
 1111    * will be reflected in the result; also note that entire array will remain in memory until references to
 1112    * this segment are discarded. (To prevent mutation and potential memory leaks, {@link #snapshot(Iterable)}
 1113    * may be invoked on the result.)
 1114    * @throws IndexOutOfBoundsException If {@code start} and {@code end} are inconsistent with each other or
 1115    * with the length of the array.
 1116    */
 1117  0 public static SizedIterable<Double> arraySegment(double[] array, int start, int end) {
 1118  0 return new DoubleArrayWrapper(array, start, end);
 1119    }
 1120   
 1121    private static final class DoubleArrayWrapper extends AbstractIterable<Double>
 1122    implements SizedIterable<Double>, OptimizedLastIterable<Double>, Serializable {
 1123    private final double[] _array;
 1124    private final int _start; // start index
 1125    private final int _end; // 1 + the last index
 1126  2 public DoubleArrayWrapper(double[] array) { _array = array; _start = 0; _end = _array.length; }
 1127  0 public DoubleArrayWrapper(double[] array, int start) {
 1128  0 if (start < 0 || start > array.length) { throw new IndexOutOfBoundsException(); }
 1129  0 _array = array; _start = start; _end = array.length;
 1130    }
 1131  0 public DoubleArrayWrapper(double[] array, int start, int end) {
 1132  0 if (start < 0 || start > end || end > array.length) { throw new IndexOutOfBoundsException(); }
 1133  0 _array = array; _start = start; _end = end;
 1134    }
 1135   
 1136  2 public boolean isEmpty() { return _start == _end; }
 1137  0 public int size() { return _end-_start; }
 1138  0 public int size(int bound) { int result = _end-_start; return result <= bound ? result : bound; }
 1139  0 public boolean isInfinite() { return false; }
 1140  0 public boolean hasFixedSize() { return true; }
 1141  0 public boolean isStatic() { return false; }
 1142  0 public Double last() { return _array[_end-1]; }
 1143  0 public Iterator<Double> iterator() {
 1144  0 return new IndexedIterator<Double>() {
 1145  0 protected int size() { return _end-_start; }
 1146  0 protected Double get(int i) { return _array[_start+i]; }
 1147    };
 1148    }
 1149    }
 1150   
 1151    /**
 1152    * Returns an iterable that traverses the given array, which may contain primitives or references.
 1153    * @throws IllegalArgumentException If {@code array} is not an array
 1154    */
 1155  10 public static SizedIterable<?> arrayAsIterable(Object array) {
 1156  1 if (array instanceof Object[]) { return new ObjectArrayWrapper<Object>((Object[]) array); }
 1157  1 else if (array instanceof int[]) { return new IntArrayWrapper((int[]) array); }
 1158  1 else if (array instanceof char[]) { return new CharArrayWrapper((char[]) array); }
 1159  1 else if (array instanceof byte[]) { return new ByteArrayWrapper((byte[]) array); }
 1160  1 else if (array instanceof double[]) { return new DoubleArrayWrapper((double[]) array); }
 1161  1 else if (array instanceof boolean[]) { return new BooleanArrayWrapper((boolean[]) array); }
 1162  1 else if (array instanceof short[]) { return new ShortArrayWrapper((short[]) array); }
 1163  1 else if (array instanceof long[]) { return new LongArrayWrapper((long[]) array); }
 1164  1 else if (array instanceof float[]) { return new FloatArrayWrapper((float[]) array); }
 1165  1 else { throw new IllegalArgumentException("Non-array argument"); }
 1166    }
 1167   
 1168   
 1169    /**
 1170    * Convert the given {@code Collection} to a {@code SizedIterable}. If it already <em>is</em>
 1171    * a {@code SizedIterable}, cast it as such. Otherwise, wrap it. In either case, subsequent
 1172    * changes made to the collection will be reflected in the result (if this is not the desired
 1173    * behavior, {@link #snapshot(Iterable)} can be used instead).
 1174    */
 1175  37 public static <T> SizedIterable<T> asSizedIterable(Collection<T> coll) {
 1176  0 if (coll instanceof SizedIterable<?>) { return (SizedIterable<T>) coll; }
 1177  37 else { return new CollectionWrapper<T>(coll); }
 1178    }
 1179   
 1180    private static final class CollectionWrapper<T> extends AbstractIterable<T>
 1181    implements SizedIterable<T>, OptimizedLastIterable<T>,
 1182    Serializable {
 1183    private final Collection<T> _c;
 1184  37 public CollectionWrapper(Collection<T> c) { _c = c; }
 1185  23 public Iterator<T> iterator() { return _c.iterator(); }
 1186  9 public boolean isEmpty() { return _c.isEmpty(); }
 1187  27 public int size() { return _c.size(); }
 1188  0 public int size(int bound) { int result = _c.size(); return result <= bound ? result : bound; }
 1189  0 public boolean isInfinite() { return false; }
 1190  0 public boolean hasFixedSize() { return isFixedSizeCollection(_c); }
 1191  0 public boolean isStatic() { return isStaticCollection(_c); }
 1192  0 public T last() { return IterUtil.last(_c); }
 1193    }
 1194   
 1195   
 1196    /** Create an iterable that wraps the given {@code CharSequence}. */
 1197  0 public static SizedIterable<Character> asIterable(CharSequence sequence) {
 1198  0 return new CharSequenceWrapper(sequence, true);
 1199    }
 1200   
 1201    /**
 1202    * Create an iterable that wraps the given string. This is similar to {@link #asIterable(CharSequence)},
 1203    * but takes advantage of the fact that {@code String}s are immutable.
 1204    */
 1205  2 public static SizedIterable<Character> asIterable(final String sequence) {
 1206  2 return new CharSequenceWrapper(sequence, false);
 1207    }
 1208   
 1209    private static final class CharSequenceWrapper extends AbstractIterable<Character>
 1210    implements SizedIterable<Character>, OptimizedLastIterable<Character>, Serializable {
 1211    private final CharSequence _s;
 1212    private final boolean _mutable; // whether this sequence is possibly mutable
 1213  2 public CharSequenceWrapper(CharSequence s, boolean mutable) { _s = s; _mutable = mutable; }
 1214  1 public boolean isEmpty() { return _s.length() == 0; }
 1215  0 public int size() { return _s.length(); }
 1216  0 public int size(int bound) { int result = _s.length(); return result <= bound ? result : bound; }
 1217  0 public boolean isInfinite() { return false; }
 1218  0 public boolean hasFixedSize() { return !_mutable; }
 1219  0 public boolean isStatic() { return !_mutable; }
 1220  0 public Character last() { return _s.charAt(_s.length()-1); }
 1221  1 public Iterator<Character> iterator() {
 1222  1 return new IndexedIterator<Character>() {
 1223  10 protected int size() { return _s.length(); }
 1224  9 protected Character get(int i) { return _s.charAt(i); }
 1225    };
 1226    }
 1227    }
 1228   
 1229    /** Produce an iterable of size 0 or 1 from an {@code Option}. */
 1230  0 public static <T> SizedIterable<T> toIterable(Option<? extends T> option) {
 1231  0 return option.apply(new OptionVisitor<T, SizedIterable<T>>() {
 1232  0 public SizedIterable<T> forSome(T val) { return new SingletonIterable<T>(val); }
 1233  0 @SuppressWarnings("unchecked")
 1234  0 public SizedIterable<T> forNone() { return (EmptyIterable<T>) EmptyIterable.INSTANCE; }
 1235    });
 1236    }
 1237   
 1238    /** Produce an iterable of size 1 from a {@code Wrapper}. */
 1239  0 public static <T> SizedIterable<T> toIterable(Wrapper<? extends T> tuple) {
 1240  0 return new SingletonIterable<T>(tuple.value());
 1241    }
 1242   
 1243    /** Produce an iterable of size 2 from a {@code Pair}. */
 1244  0 public static <T> SizedIterable<T> toIterable(Pair<? extends T, ? extends T> tuple) {
 1245  0 @SuppressWarnings("unchecked")
 1246    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second() };
 1247  0 return new ObjectArrayWrapper<T>(values, false);
 1248    }
 1249   
 1250    /** Produce an iterable of size 3 from a {@code Triple}. */
 1251  0 public static <T> SizedIterable<T> toIterable(Triple<? extends T, ? extends T, ? extends T> tuple) {
 1252  0 @SuppressWarnings("unchecked")
 1253    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second(), tuple.third() };
 1254  0 return new ObjectArrayWrapper<T>(values, false);
 1255    }
 1256   
 1257    /** Produce an iterable of size 4 from a {@code Quad}. */
 1258  0 public static <T> SizedIterable<T> toIterable(Quad<? extends T, ? extends T, ? extends T, ? extends T> tuple) {
 1259  0 @SuppressWarnings("unchecked")
 1260    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second(), tuple.third(), tuple.fourth() };
 1261  0 return new ObjectArrayWrapper<T>(values, false);
 1262    }
 1263   
 1264    /** Produce an iterable of size 5 from a {@code Quint}. */
 1265  0 public static <T> SizedIterable<T>
 1266    toIterable(Quint<? extends T, ? extends T, ? extends T, ? extends T, ? extends T> tuple) {
 1267  0 @SuppressWarnings("unchecked")
 1268    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second(), tuple.third(), tuple.fourth(),
 1269    tuple.fifth() };
 1270  0 return new ObjectArrayWrapper<T>(values, false);
 1271    }
 1272   
 1273    /** Produce an iterable of size 6 from a {@code Sextet}. */
 1274  0 public static <T> SizedIterable<T>
 1275    toIterable(Sextet<? extends T, ? extends T, ? extends T, ? extends T, ? extends T, ? extends T> tuple) {
 1276  0 @SuppressWarnings("unchecked")
 1277    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second(), tuple.third(), tuple.fourth(),
 1278    tuple.fifth(), tuple.sixth() };
 1279  0 return new ObjectArrayWrapper<T>(values, false);
 1280    }
 1281   
 1282    /** Produce an iterable of size 7 from a {@code Septet}. */
 1283  0 public static <T> SizedIterable<T>
 1284    toIterable(Septet<? extends T, ? extends T, ? extends T, ? extends T, ? extends T, ? extends T, ? extends T> tuple) {
 1285  0 @SuppressWarnings("unchecked")
 1286    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second(), tuple.third(), tuple.fourth(),
 1287    tuple.fifth(), tuple.sixth(), tuple.seventh() };
 1288  0 return new ObjectArrayWrapper<T>(values, false);
 1289    }
 1290   
 1291    /** Produce an iterable of size 8 from an {@code Octet}. */
 1292  0 public static <T> SizedIterable<T> toIterable(Octet<? extends T, ? extends T, ? extends T, ? extends T,
 1293    ? extends T, ? extends T, ? extends T, ? extends T> tuple) {
 1294  0 @SuppressWarnings("unchecked")
 1295    T[] values = (T[]) new Object[]{ tuple.first(), tuple.second(), tuple.third(), tuple.fourth(),
 1296    tuple.fifth(), tuple.sixth(), tuple.seventh(), tuple.eighth() };
 1297  0 return new ObjectArrayWrapper<T>(values, false);
 1298    }
 1299   
 1300    /**
 1301    * Make an array with the given elements. Takes advantage of the (potentially optimized)
 1302    * {@link Collection#toArray} method where possible; otherwise, just iterates through
 1303    * {@code iter} to fill the array. If the size of the iterable is larger than {@code Integer.MAX_VALUE}
 1304    * or is infinite, it will be truncated to fit in an array.
 1305    */
 1306  29 public static <T> T[] toArray(Iterable<? extends T> iter, Class<T> type) {
 1307    // Cast is safe because the result has the type of the variable "type"
 1308  29 @SuppressWarnings("unchecked") T[] result = (T[]) Array.newInstance(type, sizeOf(iter));
 1309  29 if (iter instanceof Collection<?>) {
 1310    // javac 6 doesn't like this -- Collection<? extends T> </: Iterable<capture extends T>
 1311  20 @SuppressWarnings("unchecked") T[] newResult = ((Collection<? extends T>) iter).toArray(result);
 1312  20 result = newResult; // redeclared for the sake of @SuppressWarnings
 1313    }
 1314    else {
 1315  9 int i = 0;
 1316  0 for (T t : iter) { result[i++] = t; if (i < 0) break; }
 1317    }
 1318  29 return result;
 1319    }
 1320   
 1321    /**
 1322    * Access the first value in the given iterable.
 1323    * @throws NoSuchElementException If the iterable is empty
 1324    */
 1325  97 public static <T> T first(Iterable<? extends T> iter) {
 1326  97 return iter.iterator().next();
 1327    }
 1328   
 1329    /** Produce an iterable that skips the first element of {@code iter} (if it exists) */
 1330  7 public static <T> SkipFirstIterable<T> skipFirst(Iterable<T> iter) {
 1331  7 return new SkipFirstIterable<T>(iter);
 1332    }
 1333   
 1334    /**
 1335    * Access the last value in the given iterable. With the exception of some special cases
 1336    * ({@link OptimizedLastIterable}s, {@link SortedSet}s, or {@link List}s), this operation takes time on
 1337    * the order of the length of the list. Assumes the iterable is finite.
 1338    * @throws NoSuchElementException If the iterable is empty
 1339    */
 1340  0 public static <T> T last(Iterable<? extends T> iter) {
 1341  0 if (iter instanceof OptimizedLastIterable<?>) {
 1342    // javac 6 doesn't like this -- OptimizedLastIterable<? extends T> </: Iterable<capture extends T>
 1343  0 @SuppressWarnings("unchecked") OptimizedLastIterable<? extends T> o = (OptimizedLastIterable<? extends T>) iter;
 1344  0 return o.last();
 1345    }
 1346  0 else if (iter instanceof List<?>) {
 1347    // javac 6 doesn't like this -- List<? extends T> </: Iterable<capture extends T>
 1348  0 @SuppressWarnings("unchecked") List<? extends T> l = (List<? extends T>) iter;
 1349  0 int size = l.size();
 1350  0 if (size == 0) { throw new NoSuchElementException(); }
 1351  0 return l.get(size - 1);
 1352    }
 1353  0 else if (iter instanceof SortedSet<?>) {
 1354    // javac 6 doesn't like this -- SortedSet<? extends T> </: Iterable<capture extends T>
 1355  0 @SuppressWarnings("unchecked") SortedSet<? extends T> s = (SortedSet<? extends T>) iter;
 1356  0 return s.last();
 1357    }
 1358    else {
 1359  0 Iterator<? extends T> i = iter.iterator();
 1360  0 T result = i.next();
 1361  0 while (i.hasNext()) { result = i.next(); }
 1362  0 return result;
 1363    }
 1364    }
 1365   
 1366    /**
 1367    * Produce an iterable that skips the last element of {@code iter} (if it exists). Assumes the iterable
 1368    * is finite.
 1369    */
 1370  0 public static <T> SkipLastIterable<T> skipLast(Iterable<? extends T> iter) {
 1371  0 return new SkipLastIterable<T>(iter);
 1372    }
 1373   
 1374    /**
 1375    * Convert an iterable of 0 or 1 elements to an {@code Option}.
 1376    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1377    */
 1378  0 public static <T> Option<T> makeOption(Iterable<? extends T> iter) {
 1379  0 int size = sizeOf(iter);
 1380  0 if (size == 0) { return Option.none(); }
 1381  0 else if (size == 1) { return Option.some(first(iter)); }
 1382    else {
 1383  0 throw new IllegalArgumentException("Iterable has more than 1 element: size == " + size);
 1384    }
 1385    }
 1386   
 1387    /**
 1388    * Convert an iterable of 1 element to a {@code Wrapper}.
 1389    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1390    */
 1391  0 public static <T> Wrapper<T> makeWrapper(Iterable<? extends T> iter) {
 1392  0 int size = sizeOf(iter);
 1393  0 if (size != 1) {
 1394  0 throw new IllegalArgumentException("Iterable does not have 1 element: size == " + size);
 1395    }
 1396  0 Iterator<? extends T> i = iter.iterator();
 1397  0 return new Wrapper<T>(i.next());
 1398    }
 1399   
 1400    /**
 1401    * Convert an iterable of 2 elements to a {@code Pair}.
 1402    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1403    */
 1404  11 public static <T> Pair<T, T> makePair(Iterable<? extends T> iter) {
 1405  11 int size = sizeOf(iter);
 1406  11 if (size != 2) {
 1407  0 throw new IllegalArgumentException("Iterable does not have 2 elements: size == " + size);
 1408    }
 1409  11 Iterator<? extends T> i = iter.iterator();
 1410  11 return new Pair<T, T>(i.next(), i.next());
 1411    }
 1412   
 1413    /**
 1414    * Convert an iterable of 3 elements to a {@code Triple}.
 1415    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1416    */
 1417  0 public static <T> Triple<T, T, T> makeTriple(Iterable<? extends T> iter) {
 1418  0 int size = sizeOf(iter);
 1419  0 if (size != 3) {
 1420  0 throw new IllegalArgumentException("Iterable does not have 3 elements: size == " + size);
 1421    }
 1422  0 Iterator<? extends T> i = iter.iterator();
 1423  0 return new Triple<T, T, T>(i.next(), i.next(), i.next());
 1424    }
 1425   
 1426    /**
 1427    * Convert an iterable of 4 elements to a {@code Quad}.
 1428    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1429    */
 1430  0 public static <T> Quad<T, T, T, T> makeQuad(Iterable<? extends T> iter) {
 1431  0 int size = sizeOf(iter);
 1432  0 if (size != 4) {
 1433  0 throw new IllegalArgumentException("Iterable does not have 4 elements: size == " + size);
 1434    }
 1435  0 Iterator<? extends T> i = iter.iterator();
 1436  0 return new Quad<T, T, T, T>(i.next(), i.next(), i.next(), i.next());
 1437    }
 1438   
 1439    /**
 1440    * Convert an iterable of 5 elements to a {@code Quint}.
 1441    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1442    */
 1443  0 public static <T> Quint<T, T, T, T, T> makeQuint(Iterable<? extends T> iter) {
 1444  0 int size = sizeOf(iter);
 1445  0 if (size != 5) {
 1446  0 throw new IllegalArgumentException("Iterable does not have 5 elements: size == " + size);
 1447    }
 1448  0 Iterator<? extends T> i = iter.iterator();
 1449  0 return new Quint<T, T, T, T, T>(i.next(), i.next(), i.next(), i.next(), i.next());
 1450    }
 1451   
 1452    /**
 1453    * Convert an iterable of 6 elements to a {@code Sextet}.
 1454    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1455    */
 1456  0 public static <T> Sextet<T, T, T, T, T, T> makeSextet(Iterable<? extends T> iter) {
 1457  0 int size = sizeOf(iter);
 1458  0 if (size != 6) {
 1459  0 throw new IllegalArgumentException("Iterable does not have 6 elements: size == " + size);
 1460    }
 1461  0 Iterator<? extends T> i = iter.iterator();
 1462  0 return new Sextet<T, T, T, T, T, T>(i.next(), i.next(), i.next(), i.next(), i.next(), i.next());
 1463    }
 1464   
 1465    /**
 1466    * Convert an iterable of 7 elements to a {@code Septet}.
 1467    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1468    */
 1469  0 public static <T> Septet<T, T, T, T, T, T, T> makeSeptet(Iterable<? extends T> iter) {
 1470  0 int size = sizeOf(iter);
 1471  0 if (size != 7) {
 1472  0 throw new IllegalArgumentException("Iterable does not have 7 elements: size == " + size);
 1473    }
 1474  0 Iterator<? extends T> i = iter.iterator();
 1475  0 return new Septet<T, T, T, T, T, T, T>(i.next(), i.next(), i.next(), i.next(), i.next(), i.next(), i.next());
 1476    }
 1477   
 1478    /**
 1479    * Convert an iterable of 8 elements to an {@code Octet}.
 1480    * @throws IllegalArgumentException If the iterable is not of the appropriate size.
 1481    */
 1482  0 public static <T> Octet<T, T, T, T, T, T, T, T> makeOctet(Iterable<? extends T> iter) {
 1483  0 int size = sizeOf(iter);
 1484  0 if (size != 8) {
 1485  0 throw new IllegalArgumentException("Iterable does not have 8 elements: size == " + size);
 1486    }
 1487  0 Iterator<? extends T> i = iter.iterator();
 1488  0 return new Octet<T, T, T, T, T, T, T, T>(i.next(), i.next(), i.next(), i.next(), i.next(), i.next(), i.next(),
 1489    i.next());
 1490    }
 1491   
 1492   
 1493    /**
 1494    * Produce a reverse-order iterable over the given elements. Subsequent changes to {@code iter} will not
 1495    * be reflected in the result. Runs in linear time.
 1496    */
 1497  0 public static <T> SizedIterable<T> reverse(Iterable<? extends T> iter) {
 1498  0 ConsList<T> result = ConsList.empty();
 1499  0 for (T elt : iter) { result = ConsList.cons(elt, result); }
 1500  0 return result;
 1501    }
 1502   
 1503    /**
 1504    * Produce a shuffled iterable over the given elements. Subsequent changes to {@code iter} will not
 1505    * be reflected in the result. Runs in linear time.
 1506    */
 1507  0 public static <T> SizedIterable<T> shuffle(Iterable<T> iter) {
 1508  0 ArrayList<T> result = CollectUtil.makeArrayList(iter);
 1509  0 Collections.shuffle(result);
 1510  0 return asSizedIterable(result);
 1511    }
 1512   
 1513    /**
 1514    * Produce a shuffled iterable over the given elements, using the specified random number generator.
 1515    * Subsequent changes to {@code iter} will not be reflected in the result. Runs in linear time.
 1516    */
 1517  0 public static <T> SizedIterable<T> shuffle(Iterable<T> iter, Random random) {
 1518  0 ArrayList<T> result = CollectUtil.makeArrayList(iter);
 1519  0 Collections.shuffle(result, random);
 1520  0 return asSizedIterable(result);
 1521    }
 1522   
 1523    /**
 1524    * Produce a sorted iterable over the given elements. Subsequent changes to {@code iter} will not
 1525    * be reflected in the result. Runs in n log n time.
 1526    */
 1527  0 public static <T extends Comparable<? super T>> SizedIterable<T> sort(Iterable<T> iter) {
 1528  0 ArrayList<T> result = CollectUtil.makeArrayList(iter);
 1529  0 Collections.sort(result);
 1530  0 return asSizedIterable(result);
 1531    }
 1532   
 1533    /**
 1534    * Produce a sorted iterable over the given elements, using the specified comparator.
 1535    * Subsequent changes to {@code iter} will not be reflected in the result. Runs in n log n time.
 1536    */
 1537  0 public static <T> SizedIterable<T> sort(Iterable<T> iter, Comparator<? super T> comp) {
 1538  0 ArrayList<T> result = CollectUtil.makeArrayList(iter);
 1539  0 Collections.sort(result, comp);
 1540  0 return asSizedIterable(result);
 1541    }
 1542   
 1543   
 1544    /**
 1545    * Split the given iterable into two at the given index. The first {@code index} values in
 1546    * {@code iter} will belong to the first half; the rest will belong to the second half.
 1547    * Where there are less than {@code index} values in {@code iter}, the first half will contain
 1548    * them all and the second half will be empty. Note that the result is a snapshot &mdash; later
 1549    * modifications to {@code iter} will not be reflected. Assumes the iterable is finite.
 1550    */
 1551  0 public static <T> Pair<SizedIterable<T>, SizedIterable<T>> split(Iterable<? extends T> iter, int index) {
 1552  0 Iterator<? extends T> iterator = iter.iterator();
 1553  0 @SuppressWarnings("unchecked") SizedIterable<T> left = (EmptyIterable<T>) EmptyIterable.INSTANCE;
 1554  0 for (int i = 0; i < index && iterator.hasNext(); i++) {
 1555  0 left = new ComposedIterable<T>(left, iterator.next());
 1556    }
 1557  0 return new Pair<SizedIterable<T>, SizedIterable<T>>(left, new SnapshotIterable<T>(iterator));
 1558    }
 1559   
 1560    /**
 1561    * Truncate the given iterable. The result will have size less than or equal to {@code size}. Subsequent
 1562    * changes to {@code iter} <em>will</em> be reflected in the result.
 1563    */
 1564  0 public static <T> TruncatedIterable<T> truncate(Iterable<? extends T> iter, int size) {
 1565  0 return new TruncatedIterable<T>(iter, size);
 1566    }
 1567   
 1568    /**
 1569    * Collapse a list of lists into a single list. Subsequent changes to {@code iter} or its sublists
 1570    * will be reflected in the result.
 1571    */
 1572  0 public static <T> CollapsedIterable<T> collapse(Iterable<? extends Iterable<? extends T>> iters) {
 1573  0 return new CollapsedIterable<T>(iters);
 1574    }
 1575   
 1576    /** Produce an iterable that only contains values from the given iterable that satisfy a predicate. */
 1577  56 public static <T> FilteredIterable<T> filter(Iterable<? extends T> iter, Predicate<? super T> pred) {
 1578  56 return new FilteredIterable<T>(iter, pred);
 1579    }
 1580   
 1581    /** Produce an iterable that only contains values from the given iterable that satisfy a predicate. */
 1582  0 public static <T> SnapshotIterable<T> filterSnapshot(Iterable<? extends T> iter, Predicate<? super T> pred) {
 1583  0 return new SnapshotIterable<T>(new FilteredIterable<T>(iter, pred));
 1584    }
 1585   
 1586    /** Cast all instances of the given type appropriately; filter out any non-instances. */
 1587  0 public static <T> FilteredIterable<T> filterInstances(Iterable<? super T> iter, final Class<? extends T> c) {
 1588  0 Iterable<T> cast = IterUtil.map(iter, new Lambda<Object, T>() {
 1589  0 public T value(Object obj) {
 1590  0 if (c.isInstance(obj)) { return c.cast(obj); }
 1591  0 else { return null; }
 1592    }
 1593    });
 1594  0 return new FilteredIterable<T>(cast, LambdaUtil.NOT_NULL);
 1595    }
 1596   
 1597    /**
 1598    * Compute the left fold of the given list. That is, for some combination function {@code #} (written here
 1599    * with infix notation), compute {@code base # iter.next() # iter.next() # ...}. Assumes the iterable is finite.
 1600    */
 1601  0 public static <T, R> R fold(Iterable<? extends T> iter, R base,
 1602    Lambda2<? super R, ? super T, ? extends R> combiner) {
 1603  0 R result = base;
 1604  0 for (T elt : iter) { result = combiner.value(result, elt); }
 1605  0 return result;
 1606    }
 1607   
 1608    /**
 1609    * Check whether the given predicate holds for all values in {@code iter}. Computation halts immediately where the
 1610    * predicate fails. May never halt if the iterable is infinite.
 1611    */
 1612  0 public static <T> boolean and(Iterable<? extends T> iter, Predicate<? super T> pred) {
 1613  0 for (T elt : iter) { if (!pred.contains(elt)) { return false; } }
 1614  0 return true;
 1615    }
 1616   
 1617    /**
 1618    * Check whether the given predicate holds for some value in {@code iter}. Computation halts immediately where the
 1619    * predicate succeeds. May never halt if the interable is infinite.
 1620    */
 1621  86 public static <T> boolean or(Iterable<? extends T> iter, Predicate<? super T> pred) {
 1622  30 for (T elt : iter) { if (pred.contains(elt)) { return true; } }
 1623  56 return false;
 1624    }
 1625   
 1626    /**
 1627    * Check whether the given predicate holds for all corresponding values in {@code iter1} and {@code iter2}. The
 1628    * iterables are assumed to have the same length; computation halts immediately where the predicate fails.
 1629    * May never halt if the iterables are infinite.
 1630    */
 1631  155 public static <T1, T2> boolean and(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1632    Predicate2<? super T1, ? super T2> pred) {
 1633  155 Iterator<? extends T1> i1 = iter1.iterator();
 1634  155 Iterator<? extends T2> i2 = iter2.iterator();
 1635  0 while (i1.hasNext()) { if (!pred.contains(i1.next(), i2.next())) { return false; } }
 1636  155 return true;
 1637    }
 1638   
 1639    /**
 1640    * Check whether the given predicate holds for some corresponding values in {@code iter1} and {@code iter2}. The
 1641    * iterables are assumed to have the same length; computation halts immediately where the predicate succeeds.
 1642    * May never halt if the iterables are infinite.
 1643    */
 1644  0 public static <T1, T2> boolean or(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1645    Predicate2<? super T1, ? super T2> pred) {
 1646  0 Iterator<? extends T1> i1 = iter1.iterator();
 1647  0 Iterator<? extends T2> i2 = iter2.iterator();
 1648  0 while (i1.hasNext()) { if (pred.contains(i1.next(), i2.next())) { return true; } }
 1649  0 return false;
 1650    }
 1651   
 1652    /**
 1653    * Check whether the given predicate holds for all corresponding values in the given iterables. The iterables
 1654    * are assumed to all have the same length; computation halts immediately where the predicate fails.
 1655    * May never halt if the iterables are infinite.
 1656    */
 1657  0 public static <T1, T2, T3> boolean and(Iterable<? extends T1> iter1,
 1658    Iterable<? extends T2> iter2,
 1659    Iterable<? extends T3> iter3,
 1660    Predicate3<? super T1, ? super T2, ? super T3> pred) {
 1661  0 Iterator<? extends T1> i1 = iter1.iterator();
 1662  0 Iterator<? extends T2> i2 = iter2.iterator();
 1663  0 Iterator<? extends T3> i3 = iter3.iterator();
 1664  0 while (i1.hasNext()) { if (!pred.contains(i1.next(), i2.next(), i3.next())) { return false; } }
 1665  0 return true;
 1666    }
 1667   
 1668    /**
 1669    * Check whether the given predicate holds for some corresponding values in the given iterables. The iterables
 1670    * are assumed to all have the same length; computation halts immediately where the predicate fails.
 1671    * May never halt if the iterables are infinite.
 1672    */
 1673  0 public static <T1, T2, T3> boolean or(Iterable<? extends T1> iter1,
 1674    Iterable<? extends T2> iter2,
 1675    Iterable<? extends T3> iter3,
 1676    Predicate3<? super T1, ? super T2, ? super T3> pred) {
 1677  0 Iterator<? extends T1> i1 = iter1.iterator();
 1678  0 Iterator<? extends T2> i2 = iter2.iterator();
 1679  0 Iterator<? extends T3> i3 = iter3.iterator();
 1680  0 while (i1.hasNext()) { if (pred.contains(i1.next(), i2.next(), i3.next())) { return true; } }
 1681  0 return false;
 1682    }
 1683   
 1684    /**
 1685    * Check whether the given predicate holds for all corresponding values in the given iterables. The iterables
 1686    * are assumed to all have the same length; computation halts immediately where the predicate fails.
 1687    * May never halt if the iterables are infinite.
 1688    */
 1689  0 public static <T1, T2, T3, T4> boolean and(Iterable<? extends T1> iter1,
 1690    Iterable<? extends T2> iter2,
 1691    Iterable<? extends T3> iter3,
 1692    Iterable<? extends T4> iter4,
 1693    Predicate4<? super T1, ? super T2, ? super T3, ? super T4> pred) {
 1694  0 Iterator<? extends T1> i1 = iter1.iterator();
 1695  0 Iterator<? extends T2> i2 = iter2.iterator();
 1696  0 Iterator<? extends T3> i3 = iter3.iterator();
 1697  0 Iterator<? extends T4> i4 = iter4.iterator();
 1698  0 while (i1.hasNext()) {
 1699  0 if (!pred.contains(i1.next(), i2.next(), i3.next(), i4.next())) { return false; }
 1700    }
 1701  0 return true;
 1702    }
 1703   
 1704    /**
 1705    * Check whether the given predicate holds for some corresponding values in the given iterables. The iterables
 1706    * are assumed to all have the same length; computation halts immediately where the predicate fails.
 1707    * May never halt if the iterables are infinite.
 1708    */
 1709  0 public static <T1, T2, T3, T4> boolean or(Iterable<? extends T1> iter1,
 1710    Iterable<? extends T2> iter2,
 1711    Iterable<? extends T3> iter3,
 1712    Iterable<? extends T4> iter4,
 1713    Predicate4<? super T1, ? super T2, ? super T3, ? super T4> pred) {
 1714  0 Iterator<? extends T1> i1 = iter1.iterator();
 1715  0 Iterator<? extends T2> i2 = iter2.iterator();
 1716  0 Iterator<? extends T3> i3 = iter3.iterator();
 1717  0 Iterator<? extends T4> i4 = iter4.iterator();
 1718  0 while (i1.hasNext()) {
 1719  0 if (pred.contains(i1.next(), i2.next(), i3.next(), i4.next())) { return true; }
 1720    }
 1721  0 return false;
 1722    }
 1723   
 1724   
 1725    /** Lazily apply a map function to each element in an iterable. */
 1726  67 public static <T, R> SizedIterable<R> map(Iterable<? extends T> source, Lambda<? super T, ? extends R> map) {
 1727  67 return new MappedIterable<T, R>(source, map);
 1728    }
 1729   
 1730    /** Immediately apply a map function to each element in an iterable. */
 1731  16 public static <T, R> SnapshotIterable<R> mapSnapshot(Iterable<? extends T> source,
 1732    Lambda<? super T, ? extends R> map) {
 1733  16 return new SnapshotIterable<R>(new MappedIterable<T, R>(source, map));
 1734    }
 1735   
 1736    /**
 1737    * Lazily apply a map function to each corresponding pair of elements in the given iterables. The input
 1738    * iterables are assumed to have the same size.
 1739    */
 1740  0 public static <T1, T2, R> SizedIterable<R> map(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1741    Lambda2<? super T1, ? super T2, ? extends R> map) {
 1742  0 return new BinaryMappedIterable<T1, T2, R>(iter1, iter2, map);
 1743    }
 1744   
 1745    /**
 1746    * Immediately apply a map function to each corresponding pair of elements in the given iterables. The input
 1747    * iterables are assumed to have the same size.
 1748    */
 1749  0 public static <T1, T2, R> SnapshotIterable<R> mapSnapshot(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1750    Lambda2<? super T1, ? super T2, ? extends R> map) {
 1751  0 return new SnapshotIterable<R>(new BinaryMappedIterable<T1, T2, R>(iter1, iter2, map));
 1752    }
 1753   
 1754    /**
 1755    * Lazily apply a map function to each corresponding triple of elements in the given iterables. The input
 1756    * iterables are assumed to have the same size.
 1757    */
 1758  0 public static <T1, T2, T3, R> SizedIterable<R> map(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1759    Iterable<? extends T3> iter3,
 1760    Lambda3<? super T1, ? super T2, ? super T3, ? extends R> map) {
 1761  0 Iterable<Lambda<T1, Lambda<T2, Lambda<T3, R>>>> r0 = singleton(LambdaUtil.<T1, T2, T3, R>curry(map));
 1762  0 Iterable<Lambda<T2, Lambda<T3, R>>> r1 =
 1763    cross(r0, iter1, LambdaUtil.<T1, Lambda<T2, Lambda<T3, R>>>applicationLambda());
 1764  0 Iterable<Lambda<T3, R>> r2 =
 1765    BinaryMappedIterable.make(r1, iter2, LambdaUtil.<T2, Lambda<T3, R>>applicationLambda());
 1766  0 return BinaryMappedIterable.make(r2, iter3, LambdaUtil.<T3, R>applicationLambda());
 1767    }
 1768   
 1769    /**
 1770    * Immediately apply a map function to each corresponding triple of elements in the given iterables. The input
 1771    * iterables are assumed to have the same size.
 1772    */
 1773  0 public static <T1, T2, T3, R> SnapshotIterable<R>
 1774    mapSnapshot(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3,
 1775    Lambda3<? super T1, ? super T2, ? super T3, ? extends R> map) {
 1776  0 return new SnapshotIterable<R>(map(iter1, iter2, iter3, map));
 1777    }
 1778   
 1779    /**
 1780    * Lazily apply a map function to each corresponding quadruple of elements in the given iterables. The input
 1781    * iterables are assumed to have the same size.
 1782    */
 1783  0 public static <T1, T2, T3, T4, R> SizedIterable<R>
 1784    map(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3,
 1785    Iterable<? extends T4> iter4, Lambda4<? super T1, ? super T2, ? super T3, ? super T4, ? extends R> map) {
 1786  0 Iterable<Lambda<T1, Lambda<T2, Lambda<T3, Lambda<T4, R>>>>> r0 =
 1787    singleton(LambdaUtil.<T1, T2, T3, T4, R>curry(map));
 1788  0 Iterable<Lambda<T2, Lambda<T3, Lambda<T4, R>>>> r1 =
 1789    cross(r0, iter1, LambdaUtil.<T1, Lambda<T2, Lambda<T3, Lambda<T4, R>>>>applicationLambda());
 1790  0 Iterable<Lambda<T3, Lambda<T4, R>>> r2 =
 1791    BinaryMappedIterable.make(r1, iter2, LambdaUtil.<T2, Lambda<T3, Lambda<T4, R>>>applicationLambda());
 1792  0 Iterable<Lambda<T4, R>> r3 =
 1793    BinaryMappedIterable.make(r2, iter3, LambdaUtil.<T3, Lambda<T4, R>>applicationLambda());
 1794  0 return BinaryMappedIterable.make(r3, iter4, LambdaUtil.<T4, R>applicationLambda());
 1795    }
 1796   
 1797    /**
 1798    * Immediately apply a map function to each corresponding quadruple of elements in the given iterables. The input
 1799    * iterables are assumed to have the same size.
 1800    */
 1801  0 public static <T1, T2, T3, T4, R> SnapshotIterable<R>
 1802    mapSnapshot(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3,
 1803    Iterable<? extends T4> iter4,
 1804    Lambda4<? super T1, ? super T2, ? super T3, ? super T4, ? extends R> map) {
 1805  0 return new SnapshotIterable<R>(map(iter1, iter2, iter3, iter4, map));
 1806    }
 1807   
 1808    /** Apply the given runnable to every element in an iterable. */
 1809  0 public static <T> void run(Iterable<? extends T> iter, Runnable1<? super T> runnable) {
 1810  0 for (T elt : iter) { runnable.run(elt); }
 1811    }
 1812   
 1813    /**
 1814    * Apply the given runnable to every pair of corresponding elements in the given iterables.
 1815    * The iterables are assumed to have the same length.
 1816    */
 1817  0 public static <T1, T2> void run(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1818    Runnable2<? super T1, ? super T2> runnable) {
 1819  0 Iterator<? extends T1> i1 = iter1.iterator();
 1820  0 Iterator<? extends T2> i2 = iter2.iterator();
 1821  0 while (i1.hasNext()) { runnable.run(i1.next(), i2.next()); }
 1822    }
 1823   
 1824    /**
 1825    * Apply the given runnable to every triple of corresponding elements in the given iterables.
 1826    * The iterables are assumed to have the same length.
 1827    */
 1828  0 public static <T1, T2, T3> void run(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1829    Iterable<? extends T3> iter3,
 1830    Runnable3<? super T1, ? super T2, ? super T3> runnable) {
 1831  0 Iterator<? extends T1> i1 = iter1.iterator();
 1832  0 Iterator<? extends T2> i2 = iter2.iterator();
 1833  0 Iterator<? extends T3> i3 = iter3.iterator();
 1834  0 while (i1.hasNext()) { runnable.run(i1.next(), i2.next(), i3.next()); }
 1835    }
 1836   
 1837    /**
 1838    * Apply the given runnable to every quadruple of corresponding elements in the given iterables.
 1839    * The iterables are assumed to have the same length.
 1840    */
 1841  0 public static <T1, T2, T3, T4> void run(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1842    Iterable<? extends T3> iter3, Iterable<? extends T4> iter4,
 1843    Runnable4<? super T1, ? super T2, ? super T3, ? super T4> runnable) {
 1844  0 Iterator<? extends T1> i1 = iter1.iterator();
 1845  0 Iterator<? extends T2> i2 = iter2.iterator();
 1846  0 Iterator<? extends T3> i3 = iter3.iterator();
 1847  0 Iterator<? extends T4> i4 = iter4.iterator();
 1848  0 while (i1.hasNext()) { runnable.run(i1.next(), i2.next(), i3.next(), i4.next()); }
 1849    }
 1850   
 1851   
 1852    /**
 1853    * Lazily produce the cartesian (cross) product of two iterables. Each pair of elements is combined by the
 1854    * given function. The order of results is defined by {@link CartesianIterable}.
 1855    */
 1856  0 public static <T1, T2, R> SizedIterable<R> cross(Iterable<? extends T1> left, Iterable<? extends T2> right,
 1857    Lambda2<? super T1, ? super T2, ? extends R> combiner) {
 1858  0 return new CartesianIterable<T1, T2, R>(left, right, combiner);
 1859    }
 1860   
 1861    /**
 1862    * Lazily produce the cartesian (cross) product of two iterables, wrapping each combination of elements in a
 1863    * {@code Pair}. The order of results is defined by {@link CartesianIterable}.
 1864    */
 1865  0 public static <T1, T2> SizedIterable<Pair<T1, T2>> cross(Iterable<? extends T1> left, Iterable<? extends T2> right) {
 1866  0 return cross(left, right, Pair.<T1, T2>factory());
 1867    }
 1868   
 1869    /**
 1870    * Lazily produce the cartesian (cross) product of two iterables. Each pair of elements is combined by the
 1871    * given function. The order of results is defined by {@link DiagonalCartesianIterable}.
 1872    */
 1873  0 public static <T1, T2, R> SizedIterable<R> diagonalCross(Iterable<? extends T1> left, Iterable<? extends T2> right,
 1874    Lambda2<? super T1, ? super T2, ? extends R> combiner) {
 1875  0 return new DiagonalCartesianIterable<T1, T2, R>(left, right, combiner);
 1876    }
 1877   
 1878    /**
 1879    * Lazily produce the cartesian (cross) product of two iterables, wrapping each combination of elements in a
 1880    * {@code Pair}. The order of results is defined by {@link DiagonalCartesianIterable}.
 1881    */
 1882  0 public static <T1, T2> SizedIterable<Pair<T1, T2>> diagonalCross(Iterable<? extends T1> left,
 1883    Iterable<? extends T2> right) {
 1884  0 return diagonalCross(left, right, Pair.<T1, T2>factory());
 1885    }
 1886   
 1887    /**
 1888    * Lazily produce the cartesian (cross) product of three iterables. Each triple of elements is combined by the
 1889    * given function. The order of results is defined by {@link CartesianIterable}.
 1890    */
 1891  0 public static <T1, T2, T3, R>
 1892    SizedIterable<R> cross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3,
 1893    Lambda3<? super T1, ? super T2, ? super T3, ? extends R> combiner) {
 1894  0 Iterable<Lambda<T1, Lambda<T2, Lambda<T3, R>>>> r0 = singleton(LambdaUtil.<T1, T2, T3, R>curry(combiner));
 1895  0 Iterable<Lambda<T2, Lambda<T3, R>>> r1 =
 1896    CartesianIterable.make(r0, iter1, LambdaUtil.<T1, Lambda<T2, Lambda<T3, R>>>applicationLambda());
 1897  0 Iterable<Lambda<T3, R>> r2 =
 1898    CartesianIterable.make(r1, iter2,LambdaUtil.<T2, Lambda<T3, R>>applicationLambda());
 1899  0 return CartesianIterable.make(r2, iter3, LambdaUtil.<T3, R>applicationLambda());
 1900    }
 1901   
 1902    /**
 1903    * Lazily produce the cartesian (cross) product of three iterables, wrapping each combination of elements in a
 1904    * {@code Triple}. The order of results is defined by {@link CartesianIterable}.
 1905    */
 1906  0 public static <T1, T2, T3> SizedIterable<Triple<T1, T2, T3>>
 1907    cross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3) {
 1908  0 return cross(iter1, iter2, iter3, Triple.<T1, T2, T3>factory());
 1909    }
 1910   
 1911    /**
 1912    * Lazily produce the cartesian (cross) product of three iterables. Each triple of elements is combined by the
 1913    * given function. The order of results is defined by {@link DiagonalCartesianIterable}.
 1914    */
 1915  0 public static <T1, T2, T3, R> SizedIterable<R>
 1916    diagonalCross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3,
 1917    Lambda3<? super T1, ? super T2, ? super T3, ? extends R> combiner) {
 1918  0 Iterable<Lambda<T1, Lambda<T2, Lambda<T3, R>>>> r0 = singleton(LambdaUtil.<T1, T2, T3, R>curry(combiner));
 1919  0 Iterable<Lambda<T2, Lambda<T3, R>>> r1 =
 1920    DiagonalCartesianIterable.make(r0, iter1, LambdaUtil.<T1, Lambda<T2, Lambda<T3, R>>>applicationLambda());
 1921  0 Iterable<Lambda<T3, R>> r2 =
 1922    DiagonalCartesianIterable.make(r1, iter2,LambdaUtil.<T2, Lambda<T3, R>>applicationLambda());
 1923  0 return DiagonalCartesianIterable.make(r2, iter3, LambdaUtil.<T3, R>applicationLambda());
 1924    }
 1925   
 1926    /**
 1927    * Lazily produce the cartesian (cross) product of three iterables, wrapping each combination of elements in a
 1928    * {@code Triple}. The order of results is defined by {@link DiagonalCartesianIterable}.
 1929    */
 1930  0 public static <T1, T2, T3> SizedIterable<Triple<T1, T2, T3>>
 1931    diagonalCross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2, Iterable<? extends T3> iter3) {
 1932  0 return diagonalCross(iter1, iter2, iter3, Triple.<T1, T2, T3>factory());
 1933    }
 1934   
 1935    /**
 1936    * Lazily produce the cartesian (cross) product of four iterables. Each quadruple of elements is combined by the
 1937    * given function. The order of results is defined by {@link CartesianIterable}.
 1938    */
 1939  0 public static <T1, T2, T3, T4, R>
 1940    SizedIterable<R> cross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1941    Iterable<? extends T3> iter3, Iterable<? extends T4> iter4,
 1942    Lambda4<? super T1, ? super T2, ? super T3, ? super T4, ? extends R> combiner) {
 1943  0 Iterable<Lambda<T1, Lambda<T2, Lambda<T3, Lambda<T4, R>>>>> r0 =
 1944    singleton(LambdaUtil.<T1, T2, T3, T4, R>curry(combiner));
 1945  0 Iterable<Lambda<T2, Lambda<T3, Lambda<T4, R>>>> r1 =
 1946    CartesianIterable.make(r0, iter1, LambdaUtil.<T1, Lambda<T2, Lambda<T3, Lambda<T4, R>>>>applicationLambda());
 1947  0 Iterable<Lambda<T3, Lambda<T4, R>>> r2 =
 1948    CartesianIterable.make(r1, iter2, LambdaUtil.<T2, Lambda<T3, Lambda<T4, R>>>applicationLambda());
 1949  0 Iterable<Lambda<T4, R>> r3 =
 1950    CartesianIterable.make(r2, iter3,LambdaUtil.<T3, Lambda<T4, R>>applicationLambda());
 1951  0 return CartesianIterable.make(r3, iter4, LambdaUtil.<T4, R>applicationLambda());
 1952    }
 1953   
 1954    /**
 1955    * Lazily produce the cartesian (cross) product of four iterables, wrapping each combination of elements in a
 1956    * {@code Quad}. The order of results is defined by {@link CartesianIterable}.
 1957    */
 1958  0 public static <T1, T2, T3, T4>
 1959    SizedIterable<Quad<T1, T2, T3, T4>> cross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1960    Iterable<? extends T3> iter3, Iterable<? extends T4> iter4) {
 1961  0 return cross(iter1, iter2, iter3, iter4, Quad.<T1, T2, T3, T4>factory());
 1962    }
 1963   
 1964    /**
 1965    * Lazily produce the cartesian (cross) product of four iterables. Each quadruple of elements is combined by the
 1966    * given function. The order of results is defined by {@link DiagonalCartesianIterable}.
 1967    */
 1968  0 public static <T1, T2, T3, T4, R>
 1969    SizedIterable<R> diagonalCross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1970    Iterable<? extends T3> iter3, Iterable<? extends T4> iter4,
 1971    Lambda4<? super T1, ? super T2, ? super T3, ? super T4, ? extends R> combiner) {
 1972  0 Iterable<Lambda<T1, Lambda<T2, Lambda<T3, Lambda<T4, R>>>>> r0 =
 1973    singleton(LambdaUtil.<T1, T2, T3, T4, R>curry(combiner));
 1974  0 Iterable<Lambda<T2, Lambda<T3, Lambda<T4, R>>>> r1 =
 1975    DiagonalCartesianIterable.make(r0, iter1,
 1976    LambdaUtil.<T1, Lambda<T2, Lambda<T3, Lambda<T4, R>>>>applicationLambda());
 1977  0 Iterable<Lambda<T3, Lambda<T4, R>>> r2 =
 1978    DiagonalCartesianIterable.make(r1, iter2, LambdaUtil.<T2, Lambda<T3, Lambda<T4, R>>>applicationLambda());
 1979  0 Iterable<Lambda<T4, R>> r3 =
 1980    DiagonalCartesianIterable.make(r2, iter3,LambdaUtil.<T3, Lambda<T4, R>>applicationLambda());
 1981  0 return DiagonalCartesianIterable.make(r3, iter4, LambdaUtil.<T4, R>applicationLambda());
 1982    }
 1983   
 1984    /**
 1985    * Lazily produce the cartesian (cross) product of four iterables, wrapping each combination of elements in a
 1986    * {@code Quad}. The order of results is defined by {@link DiagonalCartesianIterable}.
 1987    */
 1988  0 public static <T1, T2, T3, T4>
 1989    SizedIterable<Quad<T1, T2, T3, T4>> diagonalCross(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2,
 1990    Iterable<? extends T3> iter3, Iterable<? extends T4> iter4) {
 1991  0 return diagonalCross(iter1, iter2, iter3, iter4, Quad.<T1, T2, T3, T4>factory());
 1992    }
 1993   
 1994    /**
 1995    * Lazily produce the cartesian (cross) product of an arbitrary number of iterables. Each tuple in the result
 1996    * is represented by an iterable. If {@code iters} is empty, the result is a single empty iterable.
 1997    * The order of results is defined by {@link CartesianIterable}. The input iterable is assumed to be finite;
 1998    * the elements of this list, on the other hand, need not be.
 1999    */
 2000  1 public static <T> SizedIterable<Iterable<T>> cross(Iterable<? extends Iterable<? extends T>> iters) {
 2001  1 return crossFold(iters, IterUtil.<T>empty(), IterUtil.<T>composeRightLambda());
 2002    }
 2003   
 2004    /**
 2005    * Lazily produce the cartesian (cross) product of an arbitrary number of iterables. Each tuple in the result
 2006    * is represented by an iterable. If {@code iters} is empty, the result is a single empty iterable.
 2007    * The order of results is defined by {@link DiagonalCartesianIterable}. The input iterable is assumed
 2008    * to be finite; the elements of this list, on the other hand, need not be.
 2009    */
 2010  0 public static <T> SizedIterable<Iterable<T>> diagonalCross(Iterable<? extends Iterable<? extends T>> iters) {
 2011  0 return diagonalCrossFold(iters, IterUtil.<T>empty(), IterUtil.<T>composeRightLambda());
 2012    }
 2013   
 2014    /**
 2015    * Lazily apply the given folding function to each tuple in the cartesian (cross) product of the given iterables.
 2016    * The order of results is defined by {@link CartesianIterable}. The input iterable is assumed
 2017    * to be finite; the elements of this list, on the other hand, need not be.
 2018    */
 2019  1 public static <T, R> SizedIterable<R> crossFold(Iterable<? extends Iterable<? extends T>> iters, R base,
 2020    Lambda2<? super R, ? super T, ? extends R> combiner) {
 2021  1 SizedIterable<R> result = singleton(base);
 2022  1 for (Iterable<? extends T> iter : iters) {
 2023  2 result = new CartesianIterable<R, T, R>(result, iter, combiner);
 2024    }
 2025  1 return result;
 2026    }
 2027   
 2028    /**
 2029    * Lazily apply the given folding function to each tuple in the cartesian (cross) product of the given iterables.
 2030    * The order of results is defined by {@link DiagonalCartesianIterable}. The input iterable is assumed
 2031    * to be finite; the elements of this list, on the other hand, need not be.
 2032    */
 2033  0 public static <T, R> SizedIterable<R> diagonalCrossFold(Iterable<? extends Iterable<? extends T>> iters, R base,
 2034    Lambda2<? super R, ? super T, ? extends R> combiner) {
 2035  0 SizedIterable<R> result = singleton(base);
 2036  0 for (Iterable<? extends T> iter : iters) {
 2037  0 result = new DiagonalCartesianIterable<R, T, R>(result, iter, combiner);
 2038    }
 2039  0 return result;
 2040    }
 2041   
 2042    /**
 2043    * Use the {@link #cross(Iterable)} function to lazily apply a distribution rule to the given composite
 2044    * object list. Given a list of conjunctions, for example, this method transforms the list into an
 2045    * equivalent list of disjunctions.
 2046    * @param <T1> The original object's components, each composed of {@code A}s.
 2047    * @param <A> The type of atomic components of a {@code T1} or {@code S2}.
 2048    * @param <S2> The type of the result's components, again composed of {@code A}s.
 2049    * @param original A list of original {@code T1}s.
 2050    * @param breakT Decomposes a {@code T1} into its constituent elements.
 2051    * @param makeS Construct an {@code S2} from the given elements.
 2052    */
 2053  1 public static <T1, A, S2> Iterable<S2> distribute(Iterable<? extends T1> original,
 2054    Lambda<? super T1, ? extends Iterable<? extends A>> breakT,
 2055    Lambda<? super Iterable<A>, ? extends S2> makeS) {
 2056    // to make things concrete, assume original is a sum of products, and we want a product of sums
 2057  1 Iterable<Iterable<? extends A>> sumOfProducts = map(original, breakT);
 2058  1 Iterable<Iterable<A>> productOfSums = cross(sumOfProducts);
 2059  1 return map(productOfSums, makeS);
 2060    }
 2061   
 2062    /**
 2063    * Use the {@link #cross(Iterable)} function to apply a distribution rule to the given composite object.
 2064    * Given constructors {@code $} and {@code %}, for example, this method transforms an object of the form
 2065    * {@code (a$b) % (c$d$e)} to {@code (a%c) $ (a%d) $ (a%e) $ (b%c) $ (b%d) $ (b%e)}. For maximum flexibility,
 2066    * the types produced by the {@code $} and {@code %} constructors may be different from each other and from
 2067    * the type of atomic elements. Additionally, the type of {@code $} applied to some {@code %}-constructed
 2068    * elements may be different than the type of {@code $} applied to atomic elements (and the same for {@code %}).
 2069    * @param <S1> The original object type, composed of {@code T1}s.
 2070    * @param <T1> The type of {@code S1}'s components, composed of {@code A}s.
 2071    * @param <A> The type of atomic components of a {@code T1} or {@code S2}.
 2072    * @param <S2> The type of a {@code T2}'s components in the result, composed of {@code A}s.
 2073    * @param <T2> The result type, composed of {@code S2}s.
 2074    * @param original The original object
 2075    * @param breakS Decomposes an {@code S1} into its constituent elements.
 2076    * @param breakT Decomposes a {@code T1} into its constituent elements.
 2077    * @param makeS Construct an {@code S2} from the given elements.
 2078    * @param makeT Construct a {@code T2} from the given elements.
 2079    */
 2080  1 public static <S1, T1, A, S2, T2> T2 distribute(S1 original,
 2081    Lambda<? super S1, ? extends Iterable<? extends T1>> breakS,
 2082    Lambda<? super T1, ? extends Iterable<? extends A>> breakT,
 2083    Lambda<? super Iterable<A>, ? extends S2> makeS,
 2084    Lambda<? super Iterable<S2>, ? extends T2> makeT) {
 2085  1 return makeT.value(distribute(breakS.value(original), breakT, makeS));
 2086    }
 2087   
 2088   
 2089    /** Lazily create an iterable containing the values of the given thunks. */
 2090  5 public static <R> SizedIterable<R> valuesOf(Iterable<? extends Thunk<? extends R>> iter) {
 2091  5 return new MappedIterable<Thunk<? extends R>, R>(iter, LambdaUtil.<R>thunkValueLambda());
 2092    }
 2093   
 2094    /** Lazily create an iterable containing the values of the application of the given lambdas. */
 2095  0 public static <T, R> Iterable<R> valuesOf(Iterable<? extends Lambda<? super T, ? extends R>> iter, T arg) {
 2096  0 Lambda<Lambda<? super T, ? extends R>, R> l = LambdaUtil.bindSecond(LambdaUtil.<T, R>applicationLambda(), arg);
 2097  0 return new MappedIterable<Lambda<? super T, ? extends R>, R>(iter, l);
 2098    }
 2099   
 2100    /** Lazily create an iterable containing the values of the application of the given lambdas. */
 2101  0 public static <T1, T2, R> SizedIterable<R>
 2102    valuesOf(Iterable<? extends Lambda2<? super T1, ? super T2, ? extends R>> iter, T1 arg1, T2 arg2) {
 2103  0 Lambda<Lambda2<? super T1, ? super T2, ? extends R>, R> l =
 2104    LambdaUtil.bindSecond(LambdaUtil.bindThird(LambdaUtil.<T1, T2, R>binaryApplicationLambda(), arg2), arg1);
 2105  0 return new MappedIterable<Lambda2<? super T1, ? super T2, ? extends R>, R>(iter, l);
 2106    }
 2107   
 2108    /** Lazily create an iterable containing the values of the application of the given lambdas. */
 2109  0 public static <T1, T2, T3, R> SizedIterable<R>
 2110    valuesOf(Iterable<? extends Lambda3<? super T1, ? super T2, ? super T3, ? extends R>> iter,
 2111    T1 arg1, T2 arg2, T3 arg3) {
 2112  0 Lambda<Lambda3<? super T1, ? super T2, ? super T3, ? extends R>, R> l =
 2113    LambdaUtil.bindSecond(LambdaUtil.bindThird(LambdaUtil.bindFourth(
 2114    LambdaUtil.<T1, T2, T3, R>ternaryApplicationLambda(), arg3), arg2), arg1);
 2115  0 return new MappedIterable<Lambda3<? super T1, ? super T2, ? super T3, ? extends R>, R>(iter, l);
 2116    }
 2117   
 2118   
 2119    /** Lazily create an iterable containing the first values of the given tuples. */
 2120  116 public static <T> SizedIterable<T> pairFirsts(Iterable<? extends Pair<? extends T, ?>> iter) {
 2121  116 return new MappedIterable<Pair<? extends T, ?>, T>(iter, Pair.<T>firstGetter());
 2122    }
 2123   
 2124    /** Lazily create an iterable containing the second values of the given tuples. */
 2125  56 public static <T> SizedIterable<T> pairSeconds(Iterable<? extends Pair<?, ? extends T>> iter) {
 2126  56 return new MappedIterable<Pair<?, ? extends T>, T>(iter, Pair.<T>secondGetter());
 2127    }
 2128   
 2129    /** Lazily create an iterable containing the first values of the given tuples. */
 2130  0 public static <T> SizedIterable<T> tripleFirsts(Iterable<? extends Triple<? extends T, ?, ?>> iter) {
 2131  0 return new MappedIterable<Triple<? extends T, ?, ?>, T>(iter, Triple.<T>firstGetter());
 2132    }
 2133   
 2134    /** Lazily create an iterable containing the second values of the given tuples. */
 2135  0 public static <T> SizedIterable<T> tripleSeconds(Iterable<? extends Triple<?, ? extends T, ?>> iter) {
 2136  0 return new MappedIterable<Triple<?, ? extends T, ?>, T>(iter, Triple.<T>secondGetter());
 2137    }
 2138   
 2139    /** Lazily create an iterable containing the third values of the given tuples. */
 2140  0 public static <T> SizedIterable<T> tripleThirds(Iterable<? extends Triple<?, ?, ? extends T>> iter) {
 2141  0 return new MappedIterable<Triple<?, ?, ? extends T>, T>(iter, Triple.<T>thirdGetter());
 2142    }
 2143   
 2144    /** Lazily create an iterable containing the first values of the given tuples. */
 2145  0 public static <T> SizedIterable<T> quadFirsts(Iterable<? extends Quad<? extends T, ?, ?, ?>> iter) {
 2146  0 return new MappedIterable<Quad<? extends T, ?, ?, ?>, T>(iter, Quad.<T>firstGetter());
 2147    }
 2148   
 2149    /** Lazily create an iterable containing the second values of the given tuples. */
 2150  0 public static <T> SizedIterable<T> quadSeconds(Iterable<? extends Quad<?, ? extends T, ?, ?>> iter) {
 2151  0 return new MappedIterable<Quad<?, ? extends T, ?, ?>, T>(iter, Quad.<T>secondGetter());
 2152    }
 2153   
 2154    /** Lazily create an iterable containing the third values of the given tuples. */
 2155  0 public static <T> SizedIterable<T> quadThirds(Iterable<? extends Quad<?, ?, ? extends T, ?>> iter) {
 2156  0 return new MappedIterable<Quad<?, ?, ? extends T, ?>, T>(iter, Quad.<T>thirdGetter());
 2157    }
 2158   
 2159    /** Lazily create an iterable containing the fourth values of the given tuples. */
 2160  0 public static <T> SizedIterable<T> quadFourths(Iterable<? extends Quad<?, ?, ?, ? extends T>> iter) {
 2161  0 return new MappedIterable<Quad<?, ?, ?, ? extends T>, T>(iter, Quad.<T>fourthGetter());
 2162    }
 2163   
 2164   
 2165    /**
 2166    * Lazily create an iterable of {@code Pair}s of corresponding values from the given iterables (assumed to always
 2167    * have the same length). Useful for simultaneous iteration of multiple lists in a {@code for} loop.
 2168    */
 2169  19 public static <T1, T2> SizedIterable<Pair<T1, T2>> zip(Iterable<? extends T1> iter1, Iterable<? extends T2> iter2) {
 2170  19 return new BinaryMappedIterable<T1, T2, Pair<T1, T2>>(iter1, iter2, Pair.<T1, T2>factory());
 2171    }
 2172   
 2173    /**
 2174    * Lazily create an iterable of {@code Triple}s of corresponding values from the given iterables (assumed to
 2175    * always have the same length). Useful for simultaneous iteration of multiple lists in a {@code for} loop.
 2176    */
 2177  0 public static <T1, T2, T3> SizedIterable<Triple<T1, T2, T3>> zip(Iterable<? extends T1> iter1,
 2178    Iterable<? extends T2> iter2,
 2179    Iterable<? extends T3> iter3) {
 2180  0 return map(iter1, iter2, iter3, Triple.<T1, T2, T3>factory());
 2181    }
 2182   
 2183    /**
 2184    * Lazily create an iterable of {@code Quad}s of corresponding values from the given iterables (assumed to
 2185    * always have the same length). Useful for simultaneous iteration of multiple lists in a {@code for} loop.
 2186    */
 2187  0 public static <T1, T2, T3, T4> SizedIterable<Quad<T1, T2, T3, T4>> zip(Iterable<? extends T1> iter1,
 2188    Iterable<? extends T2> iter2,
 2189    Iterable<? extends T3> iter3,
 2190    Iterable<? extends T4> iter4) {
 2191  0 return map(iter1, iter2, iter3, iter4, Quad.<T1, T2, T3, T4>factory());
 2192    }
 2193   
 2194    }