@Override
    public Iterator<T> iterator() {
        
        /*
         * We make a copy of the allResults list to iterate over in order to
         * avoid ConcurrentModificationExceptions caused by other methods
         * loading more results into the list while someone iterates over it.
         * This is a more severe problem than it might seem, because even
         * innocuous-seeming operations such as contains() can modify the
         * underlying result set.
         */
        final List<T> allResultsCopy = new ArrayList<T>();
        allResultsCopy.addAll(allResults);        
        final Iterator<T> iter = allResultsCopy.iterator();
        
        return new Iterator<T>() {
    
            Iterator<T> iterator = iter;
            int pos = 0;
            
            @Override
            public boolean hasNext() {
                return iterator.hasNext() || nextResultsAvailable();
            }
    
            @Override
            public T next() {
                if ( !iterator.hasNext() ) {
                    /*
                     * Our private copy of the result list may be out of date
                     * with the full one. If it is, we just need to update our
                     * private copy to get more results. If it's not, we need to
                     * fetch more results from the service.
                     */
                    if ( allResults.size() == allResultsCopy.size() ) {
                        if ( !nextResultsAvailable() ) {
                            throw new NoSuchElementException();
                        }
                        moveNextResults();
                    } 
                    
                    if ( allResults.size() > allResultsCopy.size() )
                        allResultsCopy.addAll(allResults.subList(allResultsCopy.size(), allResults.size()));
                    
                    iterator = allResultsCopy.listIterator(pos);
                }
                
                pos++;
                return iterator.next();
            }
            
            @Override
            public void remove() {
                throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE);
            }            
        };
    }
@ Override public Iterator < T > iterator ( ) { final List < T > allResultsCopy = new ArrayList < T > ( ) ; allResultsCopy . addAll ( allResults ) ; final Iterator < T > iter = allResultsCopy . iterator ( ) ; return new Iterator < T > ( ) { Iterator < T > iterator = iter ; int pos = 0 ; @ Override public boolean hasNext ( ) { return iterator . hasNext ( ) || nextResultsAvailable ( ) ; } @ Override public T next ( ) { if ( ! iterator . hasNext ( ) ) { if ( allResults . size ( ) == allResultsCopy . size ( ) ) { if ( ! nextResultsAvailable ( ) ) { throw new NoSuchElementException ( ) ; } moveNextResults ( ) ; } if ( allResults . size ( ) > allResultsCopy . size ( ) ) allResultsCopy . addAll ( allResults . subList ( allResultsCopy . size ( ) , allResults . size ( ) ) ) ; iterator = allResultsCopy . listIterator ( pos ) ; } pos ++ ; return iterator . next ( ) ; } @ Override public void remove ( ) { throw new UnsupportedOperationException ( UNMODIFIABLE_MESSAGE ) ; } } ; }
Returns an iterator over this list that lazily initializes results as
necessary.