/* 
 * LingPipe v. 3.9 
 * Copyright (C) 2003-2010 Alias-i 
 * 
 * This program is licensed under the Alias-i Royalty Free License 
 * Version 1 WITHOUT ANY WARRANTY, without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Alias-i 
 * Royalty Free License Version 1 for more details. 
 * 
 * You should have received a copy of the Alias-i Royalty Free License 
 * Version 1 along with this program; if not, visit 
 * http://alias-i.com/lingpipe/licenses/lingpipe-license-1.txt or contact 
 * Alias-i, Inc. at 181 North 11th Street, Suite 401, Brooklyn, NY 11211, 
 * +1 (718) 290-9170. 
 */ 
 
//package com.aliasi.util; 
 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.NoSuchElementException; 
import java.util.List; 
 
 
/** 
 * Static utility methods, classes, and abstract classes for 
 * iteration. 
 * 
 * @author  Bob Carpenter 
 * @author  Mike Ross 
 * @version 4.0.0 
 * @since   LingPipe2.0 
 */ 
public class Iterators { 
 
    // do not allow instances 
    private Iterators() { 
        /* no instances */ 
    } 
 
    static final Iterator<Object> EMPTY_ITERATOR 
        = new Empty<Object>(); 
 
    /** 
     * Returns an iterator that has no elements.  Thus {@code 
     * hasNext()} will always return {@code false} and {@code next()} 
     * will always throw a {@code NoSuchElementException}. 
     * 
     * @return The empty iterator. 
     */ 
    public static <E> Iterator<E> empty() { 
        @SuppressWarnings("unchecked") 
        Iterator<E> emptyIterator = (Iterator<E>) EMPTY_ITERATOR; 
        return emptyIterator; 
    } 
 
    /** 
     * Returns an iterator over the single specified element. 
     * Thus {@code next()} will return the specified element 
     * on the first call, with subsequent calls 
     * throwing a {@code NoSuchElementException}  . 
     * 
     * @param e The object to return in the iterator. 
     * @return The iterator over the specified object. 
     */ 
    public static <E> Iterator<E> singleton(E e) { 
        Iterator<E> singletonIterator = new Singleton<E>(e); 
        return singletonIterator; 
    } 
 
    /** 
     * Returns a newly constructed iterator over the specified pair of 
     * elements. 
     * 
     * <p><i>Implementation Note:</i> References to the elemenets are 
     * removed from iterator after they are returned through {@code 
     * next()}. 
     * 
     * @param e1 First element returned. 
     * @param e2 Second element returned. 
     * @return The iterator over the pair of elements specified. 
     */ 
    public static <E> Iterator<E> pair(E e1, E e2) { 
        return new Pair<E>(e1,e2); 
    } 
 
    /** 
     * Returns an iterator constructed from the specified variable 
     * length argument list of objects.   
     * 
     * <p>Remove is supported, but has no effect on anything as the 
     * list from which elements are being deleted is only used for the 
     * iterator. 
     * 
     * @param es Array of objects for iteration. 
     * @return Iterator over list. 
     */ 
    public static <E> Iterator<E> list(E... es) { 
        return java.util.Arrays.<E>asList(es).iterator(); 
    } 
 
    /** 
     * Returns an unmodifiable view of the specified iterator. 
     * Calls to {@code next()} and {@code hasNext()} are delegated 
     * to the specified iterator as made.  Calls to {@code remove()} 
     * throw unsupported operation exceptions. 
     * 
     * @param it Iterator to view. 
     * @return Unmodifiable view of specified iterator. 
     */ 
    public static <E> Iterator<E> unmodifiable(Iterator<E> it) { 
        final Iterator<E> mIt = it; 
        return new Iterator<E>() { 
            public boolean hasNext() { 
                return mIt.hasNext(); 
            } 
            public E next() { 
                return mIt.next(); 
            } 
            public void remove() { 
                String msg = "Cannot remove from an unmodifiable iterator."; 
                throw new UnsupportedOperationException(msg); 
            } 
        }; 
    } 
 
    /** 
     * Returns an iterator that runs through the first iterator's 
     * elements and then runs through the second iterator's elements. 
     * 
     * <p>References to the iterators are freed after it is finished 
     * iterating. 
     * 
     * @param it1 The first iterator in the sequence. 
     * @param it2 The second iterator in the sequence. 
     * @return The iterator over the two iterators. 
     */ 
    public static <E> Iterator<E> sequence(Iterator<? extends E> it1, 
                                           Iterator<? extends E> it2) { 
        Iterator<E> result = new Sequence<E>(it1,it2); 
        return result; 
    } 
 
    public static <E> Iterator<E> sequence(List<? extends Iterator<? extends E>> iterators) { 
        @SuppressWarnings({"unchecked","rawtypes"}) 
        Iterator<? extends E>[] elts 
            = (Iterator<? extends E>[]) iterators.toArray(new Iterator[0]); 
        Iterator<E> it = new Sequence<E>(elts); 
        return it; 
    } 
 
    public static <E> Iterator<E> 
        sequence(Iterator<? extends Iterator<? extends E>> iteratorOfIterators) { 
 
        Iterator<E> it = new Sequence<E>(iteratorOfIterators); 
        return it; 
    } 
 
 
    /** 
     * Returns an iterator over the specified array of objects. 
     * 
     * <p><i>Warning:</i> The array is not copied, so any changes in 
     * the underlying array are reflected in the iterator. 
     * 
     * <P><I>Implementation Note:</I> this class does not 
     * automatically free references in the underlying array, because 
     * the array may be used elswhere.  If reference freeing is 
     * critical here, a call to {@code remove()} after ever call to 
     * {@code next()} will free the references in the array. 
     * 
     * @param members Array of elements over which to iterate. 
     * @return The iterator over the array elements. 
     */ 
    public static <E> Iterator<E> array(E[] members) { 
        return new Array<E>(members); 
    } 
 
    /** 
     * Returns a newly constructed iterator over the specified 
     * object array slice. 
     * 
     * <p>The {@code remove()} method is not supported. 
     * 
     * <p><i>Warning:</i> The array is not copied, so any changes in 
     * the underlying array are reflected in the iterator. 
     * 
     * <P><I>Implementation Note:</I> this class does not 
     * automatically free references in the underlying array, because 
     * the array may be used elswhere. 
     * 
     * @param members Array of objects over which to iterate. 
     * @param start Index of first object to return. 
     * @param length Number of objects to iterate. 
     * @throws Illegal argument exception if {@code start < 0} or 
     * {@code start + length > objects.length()}. 
     */ 
    public static <E> Iterator<E> arraySlice(E[] members, int start, int length) { 
        return new ArraySlice<E>(members,start,length); 
    } 
 
    /** 
     * An <code>Iterator.Array</code> iterates over the elements of an 
     * array specified at construction time. 
     * 
     * <P><I>Implementation Note:</I> this class does not automatically 
     * free references in the underlying array, because the array 
     * may be used elswhere.  If reference freeing is critical here, 
     * a call to <code>remove()</code> after ever <code>next()</code> 
     * will free the references in the array. 
     * 
     * @author  Bob Carpenter 
     * @version 3.8 
     * @since   LingPipe1.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    static class Array<E> implements Iterator<E> { 
 
        /** 
         * Array to iterate over. 
         */ 
        private final E[] mMembers; 
 
        /** 
         * Current position of next element to return in array. 
         */ 
        private int mPosition; 
 
        /** 
         * Construct an array iterator from the specified array. 
         * 
         * @param members Array basis of the constructed iterator. 
         */ 
        public Array(E[] members) { 
            mMembers = members; 
        } 
 
        /** 
         * Returns <code>true</code> if this iterator has more 
         * elements. 
         * 
         * @return <code>true</code> if this iterator has more 
         * elements. 
         */ 
        public boolean hasNext() { 
            return mPosition < mMembers.length; 
        } 
 
        /** 
         * Returns the next element in the array. 
         * 
         * @return Next element in the array. 
         * @throws NoSuchElementException If there are no more 
         * elements left in the array to return. 
         */ 
        public E next() { 
            if (!hasNext()) 
                throw new NoSuchElementException(); 
            return mMembers[mPosition++]; 
        } 
 
        /** 
         * Sets position in underlying array corresponding to the most 
         * recently returned token to <code>null</code>. 
         * 
         * @throws IllegalStateException If the <code>next</code> 
         * method has not been called, or the <code>remove</code> 
         * method has already been called after the last call to the 
         * next method. 
         */ 
        public void remove() { 
            if (mPosition < 1) 
                throw new IllegalStateException("Next not yet called."); 
            if (mMembers[mPosition-1] == null) 
                throw new IllegalStateException("Remove already called."); 
            mMembers[mPosition-1] = null; 
        } 
    } 
 
    /** 
     * An <code>Iterators.ArraySlice</code> iterates over a slice of 
     * an array specified by start index and length. 
     * 
     * @author  Bob Carpenter 
     * @version 3.8 
     * @since   LingPipe1.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    static class ArraySlice<E> implements Iterator<E> { 
 
        /** 
         * The underlying objects represented in this array iterator. 
         */ 
        private final E[] mObjects; 
 
        /** 
         * Index of next element to return. 
         */ 
        private int mNext; 
 
        /** 
         * Index one past the index of the last element to return. 
         */ 
        private final int mLast; 
 
        /** 
         * Construct an iterator over the specified array of objects 
         * that begins at the object at the specified start index 
         * and carries through to the other objects. 
         * 
         * @param objects Array of objects over which to iterate. 
         * @param start Index of first object to return. 
         * @param length Number of objects to iterate. 
         * @throws Illegal argument exception if {@code start < 0} or 
         * {@code start + length > objects.length}. 
         */ 
        public ArraySlice(E[] objects, 
                          int start, int length) { 
            if (start < 0) { 
                String msg = "Require start of slice to be non-negative." 
                    + " Found start=" + start; 
                throw new IllegalArgumentException(msg); 
            } 
            if (start + length > objects.length) { 
                String msg = "Start plus length must not exceed array length." 
                    + " Found objects.length=" + objects.length 
                    + " start=" + start 
                    + " length=" + length 
                    + " (start+length)=" + (start+length); 
                throw new IllegalArgumentException(msg); 
            } 
            mObjects = objects; 
            mNext = start; 
            mLast = start + length; 
        } 
 
        /** 
         * Returns <code>true</code> if there are more objects 
         * to return. 
         * 
         * @return <code>true</code> if this iterator has more 
         * elements. 
         */ 
        public boolean hasNext() { 
            return mNext < mLast; 
        } 
 
        /** 
         * Returns the next object for this iterator, throwing 
         * an exception if there are no more objects left. 
         * 
         * @return Next object from this iterator. 
         * @throws NoSuchElementException If there are no more 
         * elements to return. 
         */ 
        public E next() { 
            if (!hasNext()) throw new NoSuchElementException(); 
            return mObjects[mNext++]; 
        } 
 
        /** 
         * Throws an <code>UnsupportedOperationException</code>. 
         * 
         * @throws UnsupportedOperationException If called. 
         */ 
        public void remove() { 
            throw new UnsupportedOperationException(); 
        } 
    } 
 
    /** 
     * An <code>Iterator.Empty</code> is an iterator with no 
     * objects.  The method {@link #hasNext()} always returns 
     * <code>false</code>, while the methods {@link #next()} 
     * and {@link #remove()} always throw exceptions. 
     * 
     * @author  Bob Carpenter 
     * @version 3.8 
     * @since   LingPipe3.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    static class Empty<E> implements Iterator<E> { 
 
        /** 
         * Construct an empty iterator. 
         */ 
        public Empty() { 
            /* do nothing */ 
        } 
 
        /** 
         * Always returns <code>false</code>. 
         * 
         * @return <code>false</code>. 
         */ 
        public boolean hasNext() { 
            return false; 
        } 
 
        /** 
         * Calling this method throws a no-such-element exception. 
         * 
         * @return Always throws an exception. 
         * @throws NoSuchElementException Always. 
         */ 
        public E next() { 
            String msg = "No elements in empty iterator."; 
            throw new NoSuchElementException(msg); 
        } 
 
        /** 
         * Calling this method throws an illegal state exception. 
         * 
         * @throws IllegalStateException Always. 
         */ 
        public void remove() { 
            String msg = "No elements to remove in empty iterator."; 
            throw new IllegalStateException(msg); 
        } 
 
    } 
 
    /** 
     * An <code>Iterator.Singleton</code> is an iterator over a 
     * singleton object. 
     * 
     * @author  Bob Carpenter 
     * @version 3.8 
     * @since   LingPipe2.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    static class Singleton<E> implements Iterator<E> { 
 
        /** 
         * The single object to return. 
         */ 
        private E mMember; 
 
        /** 
         * <code>true</code> if the single element has not already 
         * been returned. 
         */ 
        private boolean mHasNext = true; 
 
        /** 
         * Construct a singleton iterator that returns the specified 
         * object. 
         * 
         * @param member Single member over which to iterate. 
         */ 
        public Singleton(E member) { 
            mMember = member; 
        } 
 
        /** 
         * Returns <code>true</code> if the single member has not 
         * already been returned. 
         * 
         * @return <code>true</code> if the single member has not 
         * already been returned. 
         */ 
        public boolean hasNext() { 
            return mHasNext; 
        } 
 
        /** 
         * Returns the singleton member if it has not yet been 
         * returned, otherwise throw an exception. 
         * 
         * @return Singleton member if it has not yet been returned. 
         * @throws NoSuchElementException If the singleton member has 
         * already been returned and no elements remain. 
         */ 
        public E next() { 
            if (!mHasNext) 
                throw new NoSuchElementException(); 
            mHasNext = false; 
            E result = mMember; 
            mMember = null; 
            return result; 
        } 
 
        /** 
         * Throws an unsupported operation exception. 
         * 
         * @throws UnsupportedOperationException Whenver called. 
         */ 
        public void remove() { 
            String msg = "This iterator does not support remove()." 
                + " class=" + this.getClass(); 
            throw new UnsupportedOperationException(msg); 
        } 
    } 
 
 
    /** 
     * An <code>Iterators.Pair</code> provides an iterator 
     * over a sequence of exactly two elements. 
     * 
     * @author  Bob Carpenter 
     * @version 3.0 
     * @since   LingPipe2.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    static class Pair<E> implements Iterator<E> { 
 
        /** 
         * Number of members returned so far. 
         */ 
        private int mMembersReturned = 0; 
 
        private E mMember1; 
        private E mMember2; 
 
        /** 
         * Construct a pair iterator based on the containing 
         * pair set. 
         * 
         * @param member1 First member. 
         * @param member2 Second member. 
         */ 
        public Pair(E member1, E member2) { 
            mMember1 = member1; 
            mMember2 = member2; 
        } 
 
        /** 
         * Returns <code>true</code> if there are more elements 
         * left to return. 
         * 
         * @return <code>true</code> if there are more elements 
         * left to return. 
         */ 
        public boolean hasNext() { 
            return mMembersReturned < 2; 
        } 
 
        /** 
         * Returns the next object in this pair iterator, 
         * or throws an exception if there aren't any more. 
         * 
         * @return Next object in this pair iterator. 
         */ 
        public E next() { 
            if (mMembersReturned == 0) { 
                ++mMembersReturned; 
                E result1 = mMember1; 
                mMember1 = null; 
                return result1; 
            } 
            if (mMembersReturned == 1) { 
                ++mMembersReturned; 
                E result2 = mMember2; 
                mMember2 = null; 
                return result2; 
            } 
            throw new NoSuchElementException(); 
        } 
 
        /** 
         * Throws an unsupported operation exception. 
         * 
         * @throws UnsupportedOperationException Whenver called. 
         */ 
        public void remove() { 
            String msg = "This iterator does not support remove()." 
                + " class=" + this.getClass(); 
            throw new UnsupportedOperationException(msg); 
        } 
 
    } 
 
 
    /** 
     * An <code>Iterators.Filter</code> filters the stream of objects 
     * returned by another iterator by subjecting them to an acceptance 
     * test.  Instances are constructed with a specified iterator to be 
     * filtered; this filter is saved in this class and should not be 
     * accessed by other methods.  Concrete subclasses must implement 
     * {@link #accept(Object)}, which determines which of the elements 
     * produced by the containediterator are returned. 
     * 
     * @author  Bob Carpenter 
     * @version 3.0 
     * @since   LingPipe1.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    public static abstract class Filter<E> implements Iterator<E> { 
 
        private final Iterator<? extends E> mIterator; 
        private boolean mFoundNext = false; 
        private E mNext; 
 
        /** 
         * Construct a filtered iterator from the specified iterator. 
         * 
         * @param iterator Contained iterator to be filtered. 
         */ 
        public Filter(Iterator<? extends E> iterator) { 
            mIterator = iterator; 
        } 
 
        /** 
         * Returns <code>true</code> for objects returned by the contained 
         * iterator that should be returned by this iterator. 
         * 
         * @param x Object to test. 
         * @return <code>true</code> if this object should be returned by 
         * this iterator. 
         */ 
        abstract public boolean accept(E x); 
 
        /** 
         * Returns <code>true</code> if calls to <code>next()</code> will 
         * return a value. 
         * 
         * <P><i>Implementation note:</i> This iterator stores the next 
         * element in a local variable after calls to this method.  Calls to 
         * {@link #next()} remove this reference. 
         * 
         * @return <code>true</code> if calls to <code>next()</code> will 
         * return a value. 
         */ 
        public boolean hasNext() { 
            if (mFoundNext) return true; 
            while (mIterator.hasNext()) { 
                E y = mIterator.next(); 
                if (accept(y)) { 
                    mFoundNext = true; 
                    mNext = y; 
                    return true; 
                } 
            } 
            return false; 
        } 
 
 
        /** 
         * Returns the next value from the contained iterator that is accepted. 
         * Acceptance is determined by the method {@link #accept(Object)}. 
         * 
         * @return Next object from the underlying iterator that passes 
         * the acceptance test. 
         * @throws NoSuchElementException If there are no more elements in 
         * the underlying iterator that pass the acceptance test. 
         */ 
        public E next() { 
            if (!hasNext()) 
                throw new NoSuchElementException(); 
            mFoundNext = false; 
            E result = mNext; 
            mNext = null; 
            return result; 
        } 
 
        /** 
         * This operation is not supported. 
         * 
         * <P><i>Implementation Note:</i> Because calls to {@link 
         * #hasNext()} must iterate over the contained iterator to find 
         * the next acceptable object to return, it is not guaranteed that 
         * the last element returned by this iterator is the same as the 
         * last element returned by the underlying iterator.  Thus the 
         * underlying iterator can't be used to do the removal without 
         * tripping the fail-fast behavior of {@link Iterator}. 
         * 
         * @throws UnsupportedOperationException Always. 
         */ 
        public void remove() { 
            String msg = "Cannot remove from a filtered iterator."; 
            throw new UnsupportedOperationException(msg); 
        } 
 
    } 
 
 
    /** 
     * An <code>Iterator.Modifier</code> uses a single abstract method 
     * to operate on the elements returned by an underlying iterator 
     * to return modified objects.  The {@link #remove()} and {@link 
     * #hasNext()} methods are simply passed to the underlying iterator. 
     * This implements the filter pattern, which is known as a map in 
     * functional programming. 
     * 
     * @author  Bob Carpenter 
     * @version 3.0 
     * @since   LingPipe2.1 
     * @param <E> the type of objects returned by the iterator 
     */ 
    public static abstract class Modifier<E> implements Iterator<E> { 
        private final Iterator<? extends E> mIt; 
 
        /** 
         * Construct a modifier from an underlying iterator. 
         * 
         * @param it Underlying iterator. 
         */ 
        public Modifier(Iterator<? extends E> it) { 
            mIt = it; 
        } 
 
        /** 
         * Remove the next element by delegating the call to the the 
         * underlying iterator. 
         */ 
        public void remove() { 
            mIt.remove(); 
        } 
 
        /** 
         * Returns <code>true</code> if the underlying iterator has 
         * more elements.  This method is simply delegated to the 
         * underlying iterator. 
         * 
         * @return <code>true</code> if this iterator has more 
         * elements. 
         */ 
        public boolean hasNext() { 
            return mIt.hasNext(); 
        } 
 
        /** 
         * Returns the next element for this iterator, which is 
         * the object returned by the underlying iterator after 
         * undergoing modification by {@link #modify(Object)}. 
         * 
         * @return The modified next element from the underlying 
         * iterator. 
         */ 
        public E next() { 
            return modify(mIt.next()); 
        } 
 
        /** 
         * This abstract method is applied to objects returned by the 
         * underlying iterator to create the object returned by this 
         * iterator. This method is called once for each call to 
         * {@link #next()}. 
         * 
         * @param next Object returned by underlying iterator. 
         * @return Object returned by this iterator. 
         */ 
        public abstract E modify(E next); 
 
    } 
 
    /** 
     * An <code>Iterators.Buffered</code> uses a single method to return 
     * objects, buffering the result and returning it as the next element 
     * if it is non-<code>null</code>.  This class does not support 
     * <code>null</code> return values for {@link #next()}.  The {@link 
     * #remove()} operation is unsupported, but may be overridden. 
     * 
     * @author  Bob Carpenter 
     * @version 3.0 
     * @since   LingPipe1.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    public static abstract class Buffered<E> implements Iterator<E> { 
 
        private E mNext; 
 
        /** 
         * Construct a buffered iterator.  This constructor does not 
         * do anything. 
         */ 
        protected Buffered() { 
            // do nothing 
        } 
 
        /** 
         * Returns the next object for this iterator, or <code>null</code> 
         * if there are no more objects. 
         * 
         * @return Next object for this iterator. 
         */ 
        protected abstract E bufferNext(); 
 
        /** 
         * Returns <code>true</code> if the next call to {@link #next()} 
         * will return a non-<code>null</code> value. 
         * 
         * @return <code>true</code> if the next call to {@link #next()} 
         * will return a non-<code>null</code> value. 
         */ 
        public boolean hasNext() { 
            return mNext != null 
                || (mNext = bufferNext()) != null; 
        } 
 
        /** 
         * Returns the next object for this iterator. 
         * 
         * @return The next object for this iterator. 
         * @throws NoSuchElementException If there are no more elements. 
         */ 
        public E next() { 
            if (!hasNext()) 
                throw new NoSuchElementException(); 
            E result = mNext; 
            mNext = null; 
            return result; 
        } 
 
        /** 
         * Throws an unsupported operation exception unless overridden by 
         * a subclass. 
         * 
         * @throws UnsupportedOperationException Always. 
         */ 
        public void remove() { 
            throw new UnsupportedOperationException(); 
        } 
 
    } 
 
 
    /** 
     * An <code>Iterators.Sequence</code> iterates over the elements of an 
     * ordered sequence of iterators in turn.  Each iterator is exhausted 
     * before moving to the next.  These iterators may be supplied as a 
     * pair of iterators, as an array of iterators, or as an iterator of 
     * iterators.  The sequence iterator delegates calls to {@link 
     * #next()} and {@link #remove()} to the relevant iterator in the 
     * underlying sequence of iterators.  For <code>next()</code>, this is 
     * the current underlying iterator.  For <code>remove()</code>, it's 
     * the last iterator whose <code>next()</code> element was called, and 
     * it throws an illegal state exception if there isn't one. 
     * 
     * <P><I>Implementation Note:</I> Because of the requirements of 
     * {@link Iterator#remove()}, a reference to the last iterator is 
     * kept, as well as to the current iterator.  Otherwise, the sequence 
     * iterator will release resources as soon as possible.  If the 
     * supplied sequence is an array, the elements will not be 
     * automatically returned from that array; it is simply wrapped in an 
     * instance of {@link Iterators.Array}. 
     * 
     * @author  Bob Carpenter 
     * @version 3.8 
     * @since   LingPipe1.0 
     * @param <E> the type of objects returned by the iterator 
     */ 
    static class Sequence<E> implements Iterator<E> { 
 
        private final Iterator<? extends Iterator<? extends E>> mIterators; 
        private Iterator<? extends E> mCurrentIterator; 
        private Iterator<? extends E> mLastIteratorNextCalled; 
 
        /** 
         * Construct a sequenc iterator that calls the pair of 
         * iterators specified in turn. 
         * 
         * @param iterator1 First iterator. 
         * @param iterator2 Second iterator. 
         */ 
        public Sequence(Iterator<? extends E> iterator1, 
                        Iterator<? extends E> iterator2) { 
            this(toIteratorIterator(iterator1,iterator2)); 
        } 
 
 
        /** 
         * Construct a sequence iterator that calls the iterators in the 
         * specified array in the order they are given in the array. 
         * 
         * @param iterators Sequence of iterators. 
         */ 
        public Sequence(Iterator<? extends E>[] iterators) { 
            this(new Iterators.Array<Iterator<? extends E>>(iterators)); 
        } 
 
        /** 
         * Construct a sequence iterator that calls the iterators returned 
         * by the iterator of iterators specified.  If one of the elements 
         * is not an iterator, <code>hasNext()</code> and 
         * <code>next()</code> will throw a 
         * <code>ClassCastException</code>. 
         * 
         * @param iteratorOfIterators Iterator of iterators. 
         */ 
        public Sequence(Iterator<? extends Iterator<? extends E>> iteratorOfIterators) { 
            mIterators = iteratorOfIterators; 
        } 
 
        /** 
         * Returns <code>true</code> if this iterator has another element. 
         * This sequence of iterators has another element if it has 
         * another iterator that has another element. 
         * 
         * @return <code>true</code> if this sequence of iterators 
         * has another iterator with another element. 
         * @throws ClassCastException If an object is returned by 
         * the iterator of iterators specified at construction time 
         * that is not an iterator. 
         */ 
        public boolean hasNext() { 
            if (mCurrentIterator == null) 
                nextIterator(); // get started 
            for (; mCurrentIterator != null; nextIterator()) 
                if (mCurrentIterator.hasNext()) 
                    return true; 
            return false; 
        } 
 
        /** 
         * Return the next element returned by the next iterator in the 
         * iterator sequence. 
         * 
         * @return The next object in the iteration. 
         * @throws ClassCastException If an object is returned by 
         * the iterator of iterators specified at construction time 
         * that is not an iterator. 
         */ 
        public E next() { 
            if (!hasNext()) 
                throw new NoSuchElementException(); 
            mLastIteratorNextCalled = mCurrentIterator; 
            return mCurrentIterator.next(); 
        } 
 
        /** 
         * Removes the last element returned by this iterator from the 
         * collection underlying the iterator from which it was returned. 
         * The method can only be called once per call to 
         * <code>next()</code>. 
 
         * @throws IllegalStateException If <code>next()</code> has not 
         * yet been called, or <code>remove()</code> method has 
         * been called after the last call to <code>next()</code>. 
         */ 
        public void remove() { 
            if (mLastIteratorNextCalled == null) 
                throw new IllegalStateException("next() not yet called."); 
            mLastIteratorNextCalled.remove(); 
            mLastIteratorNextCalled = null; 
        } 
 
        private void nextIterator() { 
            // possible cast exception 
            mCurrentIterator = 
                mIterators.hasNext() 
                ? mIterators.next() 
                : null; 
        } 
 
 
        static <E> Iterator<? extends Iterator<? extends E>> 
            toIteratorIterator(Iterator<? extends E> it1, 
                               Iterator<? extends E> it2) { 
                ArrayList<Iterator<? extends E>> list 
                    = new ArrayList<Iterator<? extends E>>(2); 
                list.add(it1); 
                list.add(it2); 
                return list.iterator(); 
        } 
 
    } 
 
    /** 
     * A {@code Iterators.PrimitiveInt} is an integer iterator that 
     * also allows objects to be accessed as primitive {@code int} 
     * values. 
     * 
     * <p>The method {@link #next()} returns an {@code Integer}, 
     * whereas {@link #nextPrimitive()} returns a primitive {@code 
     * int} value.  Using either one will advanced the iterator to the 
     * next element. 
     * 
     * <p><i>Implementation Note:</i> Using the standard iterator 
     * implementation as {@code Integer} requires boxing of the 
     * primitive values as objects.  Therefore, use the method 
     * {@code nextPrimitive()} wherever possible. 
     * 
     * @author Mike Ross 
     * @author Bob Carpenter 
     * @version 3.8 
     * @since Lingpipe3.8 
     */ 
    public static abstract class PrimitiveInt 
        implements Iterator<Integer> { 
 
        /** 
         * Returns the next primitive integer. 
         * 
         * @return The next primitive integer. 
         */ 
        abstract public int nextPrimitive(); 
 
        /** 
         * Returns {@code true} if there is another integer in the 
         * iteration. 
         * 
         * @return {@code true} if there is another integer in the 
         * iteration. 
         */ 
        abstract public boolean hasNext(); 
 
        /** 
         * Throws unsupported operation exception. 
         * 
         * @throws UnsupportedOperationException Always. 
         */ 
        public void remove() { 
            String msg = "Iterators.PrimitiveInt does not support remove."; 
            throw new UnsupportedOperationException(msg); 
        } 
 
        /** 
         * Returns the next integer result. 
         * 
         * <p><i>Implementation Note:</i> Requires boxing the 
         * primitive {@code int} returned by {@link #nextPrimitive()}. 
         * 
         * @return The next integer. 
         */ 
        public Integer next() { 
            return nextPrimitive(); 
        } 
    } 
 
 
    /** 
     * Construct an Integer iterator from 0 (inclusive) the specified 
     * end point (exclusive).  The returned iterator does not support 
     * {@code remove()}. 
     * 
     * @param end One plus the last integer returned. 
     */ 
    public static PrimitiveInt intRange(int end) { 
        return new IntRange(0,end); 
    } 
 
 
    /** 
     * Returns a newly constructed primitive integer iterator that 
     * iterates from the start (inclusive) to end (exclusive). 
     * 
     * <p>The returned iterator does not support {@code remove()}. 
     * 
     * @param start The first and lowest value to return. 
     * @param end One plus the last integer returned. 
     * @throws IllegalArgumentException If {@code start > end}. 
     */ 
    public static PrimitiveInt intRange(int start, int end) { 
        return new IntRange(start,end); 
    } 
 
    /** 
     * Returns an iterator over the array of primitive integers 
     * specified.   
     * 
     * <p>There are no order restrictions on the array -- its elements 
     * may be in any order and may contain duplicates. 
     * 
     * <p>The returned iterator does not support {@code remove()}. 
     * 
     * @param members Array of members to iterate. 
     */ 
    public static PrimitiveInt intArray(int[] members) { 
        return new IntArray(members); 
    } 
 
 
    /** 
     * See {@link #intRange(int,int)} for usage. 
     * 
     * @author  Mike Ross 
     * @version 3.8 
     * @since   Lingpipe3.8 
     */ 
    static class IntRange extends PrimitiveInt { 
        private int mCur; 
        private final int mEnd; 
        public IntRange(int start, int end) { 
            if (end < start) { 
                String msg = "End point must be >= start point." 
                    + " Found start=" + start 
                    + " end=" + end; 
                throw new IllegalArgumentException(msg); 
            } 
            mCur = start; 
            mEnd = end; 
        } 
        public boolean hasNext() { 
            return mCur < mEnd; 
        } 
        public int nextPrimitive() { 
            if (!hasNext()) 
                throw new NoSuchElementException(); 
            return mCur++; 
        } 
    } 
 
    /** 
     * See {@link #intArray(int[])} for usage. 
     * 
     * @author  Mike Ross 
     * @version 3.8 
     * @since   Lingpipe3.8 
     */ 
    static class IntArray extends PrimitiveInt { 
        private final int[] mMembers; 
        private int mPosition; 
        public IntArray(int[] members) { 
            mMembers = members; 
        } 
        public boolean hasNext() { 
            return mPosition < mMembers.length; 
        } 
        public int nextPrimitive() { 
            if (!hasNext()) 
                throw new NoSuchElementException(); 
            return mMembers[mPosition++]; 
        } 
 
    } 
 
} 
 
    
     
     
     
     
     
     
  
  |