// Path: src/main/java/edu/berkeley/nlp/lm/util/Pair.java
// public class Pair<F, S> implements Serializable
// {
// 	static final long serialVersionUID = 42;
// 
// 	F first;
// 
// 	S second;
// 
// 	public F getFirst() {
// 		return first;
// 	}
// 
// 	public S getSecond() {
// 		return second;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "(" + getFirst() + ", " + getSecond() + ")";
// 	}
// 
// 	public Pair(final F first, final S second) {
// 		this.first = first;
// 		this.second = second;
// 	}
// 
// 	public static <S, T> Pair<S, T> newPair(final S first, final T second) {
// 		return new Pair<S, T>(first, second);
// 	}
// }


import java.util.Iterator;
import edu.berkeley.nlp.lm.util.Pair;
	 * Wraps a base iterator with a transformation function.
	 */
	public static abstract class Transform<S, T> implements Iterator<T>
	{

		private final Iterator<S> base;

		public Transform(final Iterator<S> base) {
			this.base = base;
		}

		@Override
		public boolean hasNext() {
			return base.hasNext();
		}

		@Override
		public T next() {
			return transform(base.next());
		}

		protected abstract T transform(S next);

		@Override
		public void remove() {
			base.remove();
		}

	}

// Path: src/main/java/edu/berkeley/nlp/lm/util/Pair.java
// public class Pair<F, S> implements Serializable
// {
// 	static final long serialVersionUID = 42;
// 
// 	F first;
// 
// 	S second;
// 
// 	public F getFirst() {
// 		return first;
// 	}
// 
// 	public S getSecond() {
// 		return second;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "(" + getFirst() + ", " + getSecond() + ")";
// 	}
// 
// 	public Pair(final F first, final S second) {
// 		this.first = first;
// 		this.second = second;
// 	}
// 
// 	public static <S, T> Pair<S, T> newPair(final S first, final T second) {
// 		return new Pair<S, T>(first, second);
// 	}
// }


// Path: src/main/java/edu/berkeley/nlp/lm/collections/Iterators.java
import java.util.Iterator;
import edu.berkeley.nlp.lm.util.Pair;

	 * Wraps a base iterator with a transformation function.
	 */
	public static abstract class Transform<S, T> implements Iterator<T>
	{

		private final Iterator<S> base;

		public Transform(final Iterator<S> base) {
			this.base = base;
		}

		@Override
		public boolean hasNext() {
			return base.hasNext();
		}

		@Override
		public T next() {
			return transform(base.next());
		}

		protected abstract T transform(S next);

		@Override
		public void remove() {
			base.remove();
		}

	}

	public static <S, T> Iterator<Pair<S, T>> zip(final Iterator<S> s, final Iterator<T> t) {