package org.sugarj.common;

import java.util.Iterator;
import java.util.Objects;

public class AppendingIterator<T,E> implements Iterator<E> {

  private Iterator<T> mainIterator;
  private Iterator<E> currentIterator;
  private IteratorExtractor<T, E> iteratorExtractor;

  public static interface IteratorExtractor<T, E> {
    public Iterator<E> getIterator(T t);
  }
  
  private static class IterableIteratorExtractor<T extends Iterable<E>, E> implements IteratorExtractor<T, E> {
    
    @Override
    public Iterator<E> getIterator(T t) {
      return t.iterator();
    }
    
  }
  
  public static <T extends Iterable<E>, E> AppendingIterator<T,E> appendingIteratorFor(Iterator<T> mainIterator) {
    return new AppendingIterator<>(mainIterator, new IterableIteratorExtractor<T,E>());
  }
  
  public AppendingIterator(Iterator<T> mainIterator, IteratorExtractor<T, E> iteratorExtractor) {
    super();
    Objects.requireNonNull(iteratorExtractor);
    Objects.requireNonNull(mainIterator);
    this.mainIterator = mainIterator;
    this.iteratorExtractor = iteratorExtractor;
    if (this.mainIterator.hasNext()) {
      this.currentIterator = this.iteratorExtractor.getIterator(this.mainIterator.next());
    } else {
      this.currentIterator = null;
    }
  }
  

  @Override
  public boolean hasNext() {
    return this.mainIterator.hasNext() || (this.currentIterator != null && this.currentIterator.hasNext());
  }

  @Override
  public E next() {
    if (this.currentIterator.hasNext()) {
      return this.currentIterator.next();
    } else {
      this.currentIterator = this.iteratorExtractor.getIterator(this.mainIterator.next());
      return this.currentIterator.next();
    }
  }
  
  @Override
  public void remove() {
    throw new UnsupportedOperationException("remove"); 
  }

}

@@ -1313,31 +1313,130 @@
 ext() %7B%0A    
-return 
+if (this.currentIterator != null && this.currentIterator.hasNext()) %7B%0A      return true;%0A    %7D%0A    while (
 this.mainIte
@@ -1454,13 +1454,18 @@
 xt()
- %7C%7C (
+) %7B%0A      
 this
@@ -1485,50 +1485,167 @@
 tor 
-!
 = 
-null && this.currentIterator.hasNext())
+this.iteratorExtractor.getIterator(this.mainIterator.next());%0A      if (this.currentIterator.hasNext()) %7B%0A        return true;%0A      %7D%0A    %7D%0A    return false
 ;%0A  

Fix for iterator