diff --git a/user/super/com/google/gwt/emul/java/lang/Iterable.java b/user/super/com/google/gwt/emul/java/lang/Iterable.java
index b68cb6b..cec56d3 100644
--- a/user/super/com/google/gwt/emul/java/lang/Iterable.java
+++ b/user/super/com/google/gwt/emul/java/lang/Iterable.java
@@ -18,6 +18,8 @@
 import static javaemul.internal.InternalPreconditions.checkNotNull;
 
 import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.function.Consumer;
 
 /**
@@ -37,4 +39,8 @@
       action.accept(t);
     }
   }
+
+  default Spliterator<T> spliterator() {
+    return Spliterators.spliteratorUnknownSize(iterator(), 0);
+  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/Arrays.java b/user/super/com/google/gwt/emul/java/util/Arrays.java
index 9ad9fc7..374a557 100644
--- a/user/super/com/google/gwt/emul/java/util/Arrays.java
+++ b/user/super/com/google/gwt/emul/java/util/Arrays.java
@@ -1043,6 +1043,43 @@
     mergeSort(x, fromIndex, toIndex, c);
   }
 
+  public static Spliterator.OfDouble spliterator(double[] array) {
+    return Spliterators.spliterator(array, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static Spliterator.OfDouble spliterator(double[] array,
+      int startInclusive, int endExclusive) {
+    return Spliterators.spliterator(array, startInclusive, endExclusive,
+        Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static Spliterator.OfInt spliterator(int[] array) {
+    return Spliterators.spliterator(array, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static Spliterator.OfInt spliterator(int[] array, int startInclusive, int endExclusive) {
+    return Spliterators.spliterator(array, startInclusive, endExclusive,
+        Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static Spliterator.OfLong spliterator(long[] array) {
+    return Spliterators.spliterator(array, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static Spliterator.OfLong spliterator(long[] array, int startInclusive, int endExclusive) {
+    return Spliterators.spliterator(array, startInclusive, endExclusive,
+        Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static <T> Spliterator<T> spliterator(T[] array) {
+    return Spliterators.spliterator(array, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
+  public static <T> Spliterator<T> spliterator(T[] array, int startInclusive, int endExclusive) {
+    return Spliterators.spliterator(array, startInclusive, endExclusive,
+        Spliterator.IMMUTABLE | Spliterator.ORDERED);
+  }
+
   public static String toString(boolean[] a) {
     if (a == null) {
       return "null";
diff --git a/user/super/com/google/gwt/emul/java/util/Collection.java b/user/super/com/google/gwt/emul/java/util/Collection.java
index 0204f64..45b4b37 100644
--- a/user/super/com/google/gwt/emul/java/util/Collection.java
+++ b/user/super/com/google/gwt/emul/java/util/Collection.java
@@ -53,6 +53,11 @@
 
   int size();
 
+  @Override
+  default Spliterator<E> spliterator() {
+    return Spliterators.spliterator(this, 0);
+  }
+
   Object[] toArray();
 
   <T> T[] toArray(T[] a);
diff --git a/user/super/com/google/gwt/emul/java/util/List.java b/user/super/com/google/gwt/emul/java/util/List.java
index a9212bf..b6bd629 100644
--- a/user/super/com/google/gwt/emul/java/util/List.java
+++ b/user/super/com/google/gwt/emul/java/util/List.java
@@ -80,6 +80,11 @@
   @Override
   int size();
 
+  @Override
+  default Spliterator<E> spliterator() {
+    return Spliterators.spliterator(this, Spliterator.ORDERED);
+  }
+
   List<E> subList(int fromIndex, int toIndex);
 
   @Override
diff --git a/user/super/com/google/gwt/emul/java/util/PriorityQueue.java b/user/super/com/google/gwt/emul/java/util/PriorityQueue.java
index 9a595c1..7fadc73 100644
--- a/user/super/com/google/gwt/emul/java/util/PriorityQueue.java
+++ b/user/super/com/google/gwt/emul/java/util/PriorityQueue.java
@@ -194,6 +194,11 @@
   }
 
   @Override
+  public Spliterator<E> spliterator() {
+    return Spliterators.spliterator(this, Spliterator.NONNULL);
+  }
+
+  @Override
   public Object[] toArray() {
     return heap.toArray();
   }
diff --git a/user/super/com/google/gwt/emul/java/util/Set.java b/user/super/com/google/gwt/emul/java/util/Set.java
index 8c20796..07e6c18 100644
--- a/user/super/com/google/gwt/emul/java/util/Set.java
+++ b/user/super/com/google/gwt/emul/java/util/Set.java
@@ -63,6 +63,11 @@
   int size();
 
   @Override
+  default Spliterator<E> spliterator() {
+    return Spliterators.spliterator(this, Spliterator.DISTINCT);
+  }
+
+  @Override
   Object[] toArray();
 
   @Override
diff --git a/user/super/com/google/gwt/emul/java/util/SortedSet.java b/user/super/com/google/gwt/emul/java/util/SortedSet.java
index bc7a064..95e8fc8 100644
--- a/user/super/com/google/gwt/emul/java/util/SortedSet.java
+++ b/user/super/com/google/gwt/emul/java/util/SortedSet.java
@@ -35,4 +35,16 @@
   SortedSet<E> subSet(E fromElement, E toElement);
 
   SortedSet<E> tailSet(E fromElement);
+
+  @Override
+  default Spliterator<E> spliterator() {
+    return new Spliterators.IteratorSpliterator<E>(this,
+        Spliterator.DISTINCT | Spliterator.ORDERED | Spliterator.SORTED) {
+
+      @Override
+      public Comparator<? super E> getComparator() {
+        return SortedSet.this.comparator();
+      }
+    };
+  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/Spliterator.java b/user/super/com/google/gwt/emul/java/util/Spliterator.java
new file mode 100644
index 0000000..365efd2
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/Spliterator.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package java.util;
+
+import static javaemul.internal.InternalPreconditions.checkCriticalNotNull;
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+/**
+ * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html">
+ * the official Java API doc</a> for details.
+ *
+ * @param <T> the type of elements returned by Spliterator.
+ */
+public interface Spliterator<T> {
+
+  int DISTINCT = 0x00000001;
+
+  int ORDERED = 0x00000010;
+
+  int NONNULL = 0x00000100;
+
+  int CONCURRENT = 0x00001000;
+
+  int SORTED = 0x00000004;
+
+  int SIZED = 0x00000040;
+
+  int IMMUTABLE = 0x00000400;
+
+  int SUBSIZED = 0x00004000;
+
+  int characteristics();
+
+  long estimateSize();
+
+  default void forEachRemaining(Consumer<? super T> consumer) {
+    checkNotNull(consumer);
+    while (tryAdvance(consumer)) { }
+  }
+
+  default Comparator<? super T> getComparator() {
+    throw new IllegalStateException();
+  }
+
+  default long getExactSizeIfKnown() {
+    return hasCharacteristics(SIZED) ? estimateSize() : -1L;
+  }
+
+  default boolean hasCharacteristics(int characteristics) {
+    return (characteristics() & characteristics) != 0;
+  }
+
+  boolean tryAdvance(Consumer<? super T> consumer);
+
+  Spliterator<T> trySplit();
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.OfPrimitive.html">
+   * the official Java API doc</a> for details.
+   *
+   * @param <T> the type of elements returned by this Spliterator.
+   * @param <C> the type of primitive Consumer.
+   * @param <S> the type of primitive Spliterator.
+   */
+  interface OfPrimitive<T, C, S extends OfPrimitive<T, C, S>> extends Spliterator<T> {
+
+    boolean tryAdvance(C consumer);
+
+    @Override
+    S trySplit();
+
+    default void forEachRemaining(C consumer) {
+      checkNotNull(consumer);
+      while (tryAdvance(consumer)) { }
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.OfDouble.html">
+   * the official Java API doc</a> for details.
+   */
+  interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> {
+    @Override
+    default boolean tryAdvance(Consumer<? super Double> consumer) {
+      if (consumer instanceof DoubleConsumer) {
+        return tryAdvance((DoubleConsumer) consumer);
+      } else {
+        checkCriticalNotNull(consumer);
+        return tryAdvance((DoubleConsumer) consumer::accept);
+      }
+    }
+
+    @Override
+    default void forEachRemaining(Consumer<? super Double> consumer) {
+      if (consumer instanceof DoubleConsumer) {
+        forEachRemaining((DoubleConsumer) consumer);
+      } else {
+        checkCriticalNotNull(consumer);
+        forEachRemaining((DoubleConsumer) consumer::accept);
+      }
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.OfInt.html">
+   * the official Java API doc</a> for details.
+   */
+  interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {
+    @Override
+    default boolean tryAdvance(Consumer<? super Integer> consumer) {
+      if (consumer instanceof IntConsumer) {
+        return tryAdvance((IntConsumer) consumer);
+      } else {
+        checkCriticalNotNull(consumer);
+        return tryAdvance((IntConsumer) consumer::accept);
+      }
+    }
+
+    @Override
+    default void forEachRemaining(Consumer<? super Integer> consumer) {
+      if (consumer instanceof IntConsumer) {
+        forEachRemaining((IntConsumer) consumer);
+      } else {
+        checkCriticalNotNull(consumer);
+        forEachRemaining((IntConsumer) consumer::accept);
+      }
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.OfLong.html">
+   * the official Java API doc</a> for details.
+   */
+  interface OfLong extends OfPrimitive<Long, LongConsumer, OfLong> {
+    @Override
+    default boolean tryAdvance(Consumer<? super Long> consumer) {
+      if (consumer instanceof LongConsumer) {
+        return tryAdvance((LongConsumer) consumer);
+      } else {
+        checkCriticalNotNull(consumer);
+        return tryAdvance((LongConsumer) consumer::accept);
+      }
+    }
+
+    @Override
+    default void forEachRemaining(Consumer<? super Long> consumer) {
+      if (consumer instanceof LongConsumer) {
+        forEachRemaining((LongConsumer) consumer);
+      } else {
+        checkCriticalNotNull(consumer);
+        forEachRemaining((LongConsumer) consumer::accept);
+      }
+    }
+  }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/Spliterators.java b/user/super/com/google/gwt/emul/java/util/Spliterators.java
new file mode 100644
index 0000000..7e44465
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/Spliterators.java
@@ -0,0 +1,736 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package java.util;
+
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+import static javaemul.internal.InternalPreconditions.checkCriticalPositionIndexes;
+import static javaemul.internal.InternalPreconditions.checkCriticalState;
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+/**
+ * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterators.html">
+ * the official Java API doc</a> for details.
+ *
+ * Since it's hard to implement parallel algorithms in the browser environment
+ * and to keep code simple, implementation does not provide splitting.
+ */
+public final class Spliterators {
+
+  private static class BaseSpliterator<T, S extends Spliterator<T>> {
+    private final int characteristics;
+    private long sizeEstimate;
+
+    BaseSpliterator(long size, int characteristics) {
+      this.sizeEstimate = size;
+      this.characteristics = (characteristics & Spliterator.SIZED) != 0 ?
+          characteristics | Spliterator.SUBSIZED : characteristics;
+    }
+
+    public int characteristics() {
+      return characteristics;
+    }
+
+    public long estimateSize() {
+      return sizeEstimate;
+    }
+
+    public S trySplit() {
+      // see javadoc for java.util.Spliterator
+      return null;
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterators.AbstractSpliterator.html">
+   * the official Java API doc</a> for details.
+   */
+  public abstract static class AbstractSpliterator<T>
+      extends BaseSpliterator<T, Spliterator<T>> implements Spliterator<T> {
+
+    protected AbstractSpliterator(long size, int characteristics) {
+      super(size, characteristics);
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterators.AbstractDoubleSpliterator.html">
+   * the official Java API doc</a> for details.
+   */
+  public abstract static class AbstractDoubleSpliterator
+      extends BaseSpliterator<Double, Spliterator.OfDouble> implements Spliterator.OfDouble {
+
+    protected AbstractDoubleSpliterator(long size, int characteristics) {
+      super(size, characteristics);
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterators.AbstractIntSpliterator.html">
+   * the official Java API doc</a> for details.
+   */
+  public abstract static class AbstractIntSpliterator
+      extends BaseSpliterator<Integer, Spliterator.OfInt> implements Spliterator.OfInt {
+
+    protected AbstractIntSpliterator(long size, int characteristics) {
+      super(size, characteristics);
+    }
+  }
+
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Spliterators.AbstractLongSpliterator.html">
+   * the official Java API doc</a> for details.
+   */
+  public abstract static class AbstractLongSpliterator
+      extends BaseSpliterator<Long, Spliterator.OfLong> implements Spliterator.OfLong {
+
+    protected AbstractLongSpliterator(long size, int characteristics) {
+      super(size, characteristics);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> Spliterator<T> emptySpliterator() {
+    return (Spliterator<T>) EmptySpliterator.OF_REF;
+  }
+
+  public static Spliterator.OfDouble emptyDoubleSpliterator() {
+    return EmptySpliterator.OF_DOUBLE;
+  }
+
+  public static Spliterator.OfInt emptyIntSpliterator() {
+    return EmptySpliterator.OF_INT;
+  }
+
+  public static Spliterator.OfLong emptyLongSpliterator() {
+    return EmptySpliterator.OF_LONG;
+  }
+
+  public static <T> Spliterator<T> spliterator(Object[] array, int characteristics) {
+    return new ArraySpliterator<>(array, characteristics);
+  }
+
+  public static <T> Spliterator<T> spliterator(Object[] array, int fromIndex, int toIndex,
+                                               int characteristics) {
+    return new ArraySpliterator<>(array, fromIndex, toIndex, characteristics);
+  }
+
+  public static Spliterator.OfInt spliterator(int[] array, int characteristics) {
+    return new IntArraySpliterator(array, characteristics);
+  }
+
+  public static Spliterator.OfInt spliterator(int[] array, int fromIndex, int toIndex,
+                                              int characteristics) {
+    return new IntArraySpliterator(array, fromIndex, toIndex, characteristics);
+  }
+
+  public static Spliterator.OfLong spliterator(long[] array, int characteristics) {
+    return new LongArraySpliterator(array, characteristics);
+  }
+
+  public static Spliterator.OfLong spliterator(long[] array, int fromIndex, int toIndex,
+                                               int characteristics) {
+    return new LongArraySpliterator(array, fromIndex, toIndex, characteristics);
+  }
+
+  public static Spliterator.OfDouble spliterator(double[] array, int characteristics) {
+    return new DoubleArraySpliterator(array, characteristics);
+  }
+
+  public static Spliterator.OfDouble spliterator(double[] array, int fromIndex, int toIndex,
+                                                 int characteristics) {
+    return new DoubleArraySpliterator(array, fromIndex, toIndex, characteristics);
+  }
+
+  public static <T> Spliterator<T> spliterator(Collection<? extends T> c, int characteristics) {
+    return new IteratorSpliterator<>(c, characteristics);
+  }
+
+  public static <T> Spliterator<T> spliterator(Iterator<? extends T> it, long size,
+                                               int characteristics) {
+    return new IteratorSpliterator<>(it, size, characteristics);
+  }
+
+  public static <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> it,
+                                                          int characteristics) {
+    return new IteratorSpliterator<>(it, characteristics);
+  }
+
+  public static Spliterator.OfInt spliterator(PrimitiveIterator.OfInt it, long size,
+                                              int characteristics) {
+    return new IntIteratorSpliterator(it, size, characteristics);
+  }
+
+  public static Spliterator.OfInt spliteratorUnknownSize(PrimitiveIterator.OfInt it,
+                                                         int characteristics) {
+    return new IntIteratorSpliterator(it, characteristics);
+  }
+
+  public static Spliterator.OfLong spliterator(PrimitiveIterator.OfLong it, long size,
+                                               int characteristics) {
+    return new LongIteratorSpliterator(it, size, characteristics);
+  }
+
+  public static Spliterator.OfLong spliteratorUnknownSize(PrimitiveIterator.OfLong it,
+                                                          int characteristics) {
+    return new LongIteratorSpliterator(it, characteristics);
+  }
+
+  public static Spliterator.OfDouble spliterator(PrimitiveIterator.OfDouble it, long size,
+                                                 int characteristics) {
+    return new DoubleIteratorSpliterator(it, size, characteristics);
+  }
+
+  public static Spliterator.OfDouble spliteratorUnknownSize(PrimitiveIterator.OfDouble it,
+                                                            int characteristics) {
+    return new DoubleIteratorSpliterator(it, characteristics);
+  }
+
+  public static <T> Iterator<T> iterator(Spliterator<? extends T> spliterator) {
+    return new ConsumerIterator<>(spliterator);
+  }
+
+  public static PrimitiveIterator.OfDouble iterator(Spliterator.OfDouble spliterator) {
+    return new DoubleConsumerIterator(spliterator);
+  }
+
+  public static PrimitiveIterator.OfInt iterator(Spliterator.OfInt spliterator) {
+    return new IntConsumerIterator(spliterator);
+  }
+
+  public static PrimitiveIterator.OfLong iterator(Spliterator.OfLong spliterator) {
+    return new LongConsumerIterator(spliterator);
+  }
+
+  private abstract static class EmptySpliterator<T, S extends Spliterator<T>, C> {
+
+    static final Spliterator<Object> OF_REF = new EmptySpliterator.OfRef<>();
+    static final Spliterator.OfDouble OF_DOUBLE = new EmptySpliterator.OfDouble();
+    static final Spliterator.OfInt OF_INT = new EmptySpliterator.OfInt();
+    static final Spliterator.OfLong OF_LONG = new EmptySpliterator.OfLong();
+
+    public int characteristics() {
+      return Spliterator.SIZED | Spliterator.SUBSIZED;
+    }
+
+    public long estimateSize() {
+      return 0;
+    }
+
+    public void forEachRemaining(C consumer) {
+      checkNotNull(consumer);
+    }
+
+    public boolean tryAdvance(C consumer) {
+      checkNotNull(consumer);
+      return false;
+    }
+
+    public S trySplit() {
+      return null;
+    }
+
+    private static final class OfRef<T>
+        extends EmptySpliterator<T, Spliterator<T>, Consumer<? super T>>
+        implements Spliterator<T> {
+
+      OfRef() { }
+    }
+
+    private static final class OfDouble
+        extends EmptySpliterator<Double, Spliterator.OfDouble, DoubleConsumer>
+        implements Spliterator.OfDouble {
+
+      OfDouble() { }
+    }
+
+    private static final class OfInt
+        extends EmptySpliterator<Integer, Spliterator.OfInt, IntConsumer>
+        implements Spliterator.OfInt {
+
+      OfInt() { }
+    }
+
+    private static final class OfLong
+        extends EmptySpliterator<Long, Spliterator.OfLong, LongConsumer>
+        implements Spliterator.OfLong {
+
+      OfLong() { }
+    }
+  }
+
+  private static final class ConsumerIterator<T> implements Consumer<T>, Iterator<T> {
+    private final Spliterator<? extends T> spliterator;
+    private T nextElement;
+    private boolean hasElement = false;
+
+    ConsumerIterator(Spliterator<? extends T> spliterator) {
+      this.spliterator = checkNotNull(spliterator);
+    }
+
+    @Override
+    public void accept(T element) {
+      nextElement = element;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (!hasElement) {
+        hasElement = spliterator.tryAdvance(this);
+      }
+      return hasElement;
+    }
+
+    @Override
+    public T next() {
+      checkCriticalElement(hasNext());
+      hasElement = false;
+      T element = nextElement;
+      nextElement = null;
+      return element;
+    }
+  }
+
+  private static final class DoubleConsumerIterator
+      implements DoubleConsumer, PrimitiveIterator.OfDouble {
+
+    private final Spliterator.OfDouble spliterator;
+    private double nextElement;
+    private boolean hasElement = false;
+
+    DoubleConsumerIterator(Spliterator.OfDouble spliterator) {
+      this.spliterator = checkNotNull(spliterator);
+    }
+
+    @Override
+    public void accept(double d) {
+      nextElement = d;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (!hasElement) {
+        hasElement = spliterator.tryAdvance(this);
+      }
+      return hasElement;
+    }
+
+    @Override
+    public double nextDouble() {
+      checkCriticalElement(hasNext());
+      hasElement = false;
+      return nextElement;
+    }
+  }
+
+  private static final class IntConsumerIterator
+      implements IntConsumer, PrimitiveIterator.OfInt {
+
+    private final Spliterator.OfInt spliterator;
+    private int nextElement;
+    private boolean hasElement = false;
+
+    IntConsumerIterator(Spliterator.OfInt spliterator) {
+      this.spliterator = checkNotNull(spliterator);
+    }
+
+    @Override
+    public void accept(int i) {
+      nextElement = i;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (!hasElement) {
+        hasElement = spliterator.tryAdvance(this);
+      }
+      return hasElement;
+    }
+
+    @Override
+    public int nextInt() {
+      checkCriticalElement(hasNext());
+      hasElement = false;
+      return nextElement;
+    }
+  }
+
+  private static final class LongConsumerIterator
+      implements LongConsumer, PrimitiveIterator.OfLong {
+
+    private final Spliterator.OfLong spliterator;
+    private long nextElement;
+    private boolean hasElement = false;
+
+    LongConsumerIterator(Spliterator.OfLong spliterator) {
+      this.spliterator = checkNotNull(spliterator);
+    }
+
+    @Override
+    public void accept(long l) {
+      nextElement = l;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (!hasElement) {
+        hasElement = spliterator.tryAdvance(this);
+      }
+      return hasElement;
+    }
+
+    @Override
+    public long nextLong() {
+      checkCriticalElement(hasNext());
+      hasElement = false;
+      return nextElement;
+    }
+  }
+
+  static class IteratorSpliterator<T> implements Spliterator<T> {
+    private Collection<? extends T> collection;
+    private Iterator<? extends T> it;
+    private final int characteristics;
+    private long estimateSize;
+
+    IteratorSpliterator(Collection<? extends T> collection, int characteristics) {
+      this.collection = checkNotNull(collection);
+      this.characteristics = sizeKnownIteratorSpliteratorCharacteristics(characteristics);
+    }
+
+    IteratorSpliterator(Iterator<? extends T> it, long size, int characteristics) {
+      this.it = checkNotNull(it);
+      this.characteristics = sizeKnownIteratorSpliteratorCharacteristics(characteristics);
+      this.estimateSize = size;
+    }
+
+    IteratorSpliterator(Iterator<? extends T> it, int characteristics) {
+      this.it = checkNotNull(it);
+      this.characteristics = sizeUnknownSpliteratorCharacteristics(characteristics);
+      this.estimateSize = Long.MAX_VALUE;
+    }
+
+    @Override
+    public int characteristics() {
+      return characteristics;
+    }
+
+    @Override
+    public long estimateSize() {
+      initIterator();
+      return estimateSize;
+    }
+
+    @Override
+    public void forEachRemaining(Consumer<? super T> consumer) {
+      initIterator();
+      it.forEachRemaining(consumer);
+    }
+
+    @Override
+    public Comparator<? super T> getComparator() {
+      checkSorted(characteristics);
+      return null;
+    }
+
+    @Override
+    public boolean tryAdvance(Consumer<? super T> consumer) {
+      checkNotNull(consumer);
+      initIterator();
+      if (it.hasNext()) {
+        consumer.accept(it.next());
+        return true;
+      }
+      return false;
+    }
+
+    @Override
+    public Spliterator<T> trySplit() {
+      // see javadoc for java.util.Spliterator
+      return null;
+    }
+
+    private void initIterator() {
+      if (it == null) {
+        it = collection.iterator();
+        estimateSize = (long) collection.size();
+      }
+    }
+  }
+
+  private static final class DoubleIteratorSpliterator extends AbstractDoubleSpliterator {
+    private final PrimitiveIterator.OfDouble it;
+
+    DoubleIteratorSpliterator(PrimitiveIterator.OfDouble it, long size, int characteristics) {
+      super(size, sizeKnownIteratorSpliteratorCharacteristics(characteristics));
+      this.it = checkNotNull(it);
+    }
+
+    DoubleIteratorSpliterator(PrimitiveIterator.OfDouble it, int characteristics) {
+      super(Long.MAX_VALUE, sizeUnknownSpliteratorCharacteristics(characteristics));
+      this.it = checkNotNull(it);
+    }
+
+    @Override
+    public void forEachRemaining(DoubleConsumer consumer) {
+      it.forEachRemaining(consumer);
+    }
+
+    @Override
+    public Comparator<? super Double> getComparator() {
+      checkSorted(characteristics());
+      return null;
+    }
+
+    @Override
+    public boolean tryAdvance(DoubleConsumer consumer) {
+      checkNotNull(consumer);
+      if (it.hasNext()) {
+        consumer.accept(it.nextDouble());
+        return true;
+      }
+      return false;
+    }
+  }
+
+  private static final class IntIteratorSpliterator extends AbstractIntSpliterator {
+    private final PrimitiveIterator.OfInt it;
+
+    IntIteratorSpliterator(PrimitiveIterator.OfInt it, long size, int characteristics) {
+      super(size, sizeKnownIteratorSpliteratorCharacteristics(characteristics));
+      this.it = checkNotNull(it);
+    }
+
+    IntIteratorSpliterator(PrimitiveIterator.OfInt it, int characteristics) {
+      super(Long.MAX_VALUE, sizeUnknownSpliteratorCharacteristics(characteristics));
+      this.it = checkNotNull(it);
+    }
+
+    @Override
+    public void forEachRemaining(IntConsumer consumer) {
+      it.forEachRemaining(consumer);
+    }
+
+    @Override
+    public Comparator<? super Integer> getComparator() {
+      checkSorted(characteristics());
+      return null;
+    }
+
+    @Override
+    public boolean tryAdvance(IntConsumer consumer) {
+      checkNotNull(consumer);
+      if (it.hasNext()) {
+        consumer.accept(it.nextInt());
+        return true;
+      }
+      return false;
+    }
+  }
+
+  private static final class LongIteratorSpliterator extends AbstractLongSpliterator {
+    private final PrimitiveIterator.OfLong it;
+
+    LongIteratorSpliterator(PrimitiveIterator.OfLong it, long size, int characteristics) {
+      super(size, sizeKnownIteratorSpliteratorCharacteristics(characteristics));
+      this.it = checkNotNull(it);
+    }
+
+    LongIteratorSpliterator(PrimitiveIterator.OfLong it, int characteristics) {
+      super(Long.MAX_VALUE, sizeUnknownSpliteratorCharacteristics(characteristics));
+      this.it = checkNotNull(it);
+    }
+
+    @Override
+    public void forEachRemaining(LongConsumer consumer) {
+      it.forEachRemaining(consumer);
+    }
+
+    @Override
+    public Comparator<? super Long> getComparator() {
+      checkSorted(characteristics());
+      return null;
+    }
+
+    @Override
+    public boolean tryAdvance(LongConsumer consumer) {
+      checkNotNull(consumer);
+      if (it.hasNext()) {
+        consumer.accept(it.nextLong());
+        return true;
+      }
+      return false;
+    }
+  }
+
+  private abstract static class BaseArraySpliterator<T, S extends Spliterator<T>, C> {
+    private int index;
+    private final int limit;
+    private final int characteristics;
+
+    BaseArraySpliterator(int from, int limit, int size, int characteristics) {
+      checkCriticalPositionIndexes(from, limit, size);
+      this.index = from;
+      this.limit = limit;
+      this.characteristics = sizeKnownSpliteratorCharacteristics(characteristics);
+    }
+
+    public int characteristics() {
+      return characteristics;
+    }
+
+    public long estimateSize() {
+      return limit - index;
+    }
+
+    public void forEachRemaining(C consumer) {
+      checkNotNull(consumer);
+      while (index < limit) {
+        consume(consumer, index++);
+      }
+    }
+
+    public Comparator<? super T> getComparator() {
+      checkSorted(characteristics);
+      return null;
+    }
+
+    public boolean tryAdvance(C consumer) {
+      checkNotNull(consumer);
+      if (index < limit) {
+        consume(consumer, index++);
+        return true;
+      }
+      return false;
+    }
+
+    public S trySplit() {
+      // see javadoc for java.util.Spliterator
+      return null;
+    }
+
+    protected abstract void consume(C consumer, int index);
+  }
+
+  private static final class ArraySpliterator<T>
+      extends BaseArraySpliterator<T, Spliterator<T>, Consumer<? super T>>
+      implements Spliterator<T> {
+
+    private final Object[] array;
+
+    ArraySpliterator(Object[] array, int characteristics) {
+      this(array, 0, array.length, characteristics);
+    }
+
+    ArraySpliterator(Object[] array, int from, int limit, int characteristics) {
+      super(from, limit, array.length, characteristics);
+      this.array = array;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void consume(Consumer<? super T> consumer, int index) {
+      consumer.accept((T) array[index]);
+    }
+  }
+
+  private static final class DoubleArraySpliterator
+      extends BaseArraySpliterator<Double, Spliterator.OfDouble, DoubleConsumer>
+      implements Spliterator.OfDouble {
+
+    private final double[] array;
+
+    DoubleArraySpliterator(double[] array, int characteristics) {
+      this(array, 0, array.length, characteristics);
+    }
+
+    DoubleArraySpliterator(double[] array, int from, int limit, int characteristics) {
+      super(from, limit, array.length, characteristics);
+      this.array = array;
+    }
+
+    @Override
+    protected void consume(DoubleConsumer consumer, int index) {
+      consumer.accept(array[index]);
+    }
+  }
+
+  private static final class IntArraySpliterator
+      extends BaseArraySpliterator<Integer, Spliterator.OfInt, IntConsumer>
+      implements Spliterator.OfInt {
+
+    private final int[] array;
+
+    IntArraySpliterator(int[] array, int characteristics) {
+      this(array, 0, array.length, characteristics);
+    }
+
+    IntArraySpliterator(int[] array, int from, int limit, int characteristics) {
+      super(from, limit, array.length, characteristics);
+      this.array = array;
+    }
+
+    @Override
+    protected void consume(IntConsumer consumer, int index) {
+      consumer.accept(array[index]);
+    }
+  }
+
+  private static final class LongArraySpliterator
+      extends BaseArraySpliterator<Long, Spliterator.OfLong, LongConsumer>
+      implements Spliterator.OfLong {
+
+    private final long[] array;
+
+    LongArraySpliterator(long[] array, int characteristics) {
+      this(array, 0, array.length, characteristics);
+    }
+
+    LongArraySpliterator(long[] array, int from, int limit, int characteristics) {
+      super(from, limit, array.length, characteristics);
+      this.array = array;
+    }
+
+    @Override
+    protected void consume(LongConsumer consumer, int index) {
+      consumer.accept(array[index]);
+    }
+  }
+
+  private static void checkSorted(int characteristics) {
+    checkCriticalState((characteristics & Spliterator.SORTED) != 0);
+  }
+
+  private static int sizeKnownSpliteratorCharacteristics(int characteristics) {
+    return characteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
+  }
+
+  private static int sizeKnownIteratorSpliteratorCharacteristics(int characteristics) {
+    return (characteristics & Spliterator.CONCURRENT) == 0 ?
+        sizeKnownSpliteratorCharacteristics(characteristics) : characteristics;
+  }
+
+  private static int sizeUnknownSpliteratorCharacteristics(int characteristics) {
+    return characteristics & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
+  }
+
+  private Spliterators() { }
+
+}
diff --git a/user/test/com/google/gwt/emultest/EmulJava8Suite.java b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
index 7b311b3..0d90d04 100644
--- a/user/test/com/google/gwt/emultest/EmulJava8Suite.java
+++ b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
@@ -24,6 +24,7 @@
 import com.google.gwt.emultest.java8.util.OptionalLongTest;
 import com.google.gwt.emultest.java8.util.OptionalTest;
 import com.google.gwt.emultest.java8.util.PrimitiveIteratorTest;
+import com.google.gwt.emultest.java8.util.SpliteratorsTest;
 import com.google.gwt.emultest.java8.util.StringJoinerTest;
 import com.google.gwt.junit.tools.GWTTestSuite;
 
@@ -44,6 +45,7 @@
     suite.addTestSuite(OptionalLongTest.class);
     suite.addTestSuite(OptionalDoubleTest.class);
     suite.addTestSuite(PrimitiveIteratorTest.class);
+    suite.addTestSuite(SpliteratorsTest.class);
     suite.addTestSuite(StringJoinerTest.class);
     suite.addTestSuite(DoubleSummaryStatisticsTest.class);
     suite.addTestSuite(IntSummaryStatisticsTest.class);
diff --git a/user/test/com/google/gwt/emultest/java8/util/SpliteratorsTest.java b/user/test/com/google/gwt/emultest/java8/util/SpliteratorsTest.java
new file mode 100644
index 0000000..4c5a23b
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/util/SpliteratorsTest.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.emultest.java8.util;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/**
+ * Tests for Spliterators JRE emulation.
+ */
+public class SpliteratorsTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.emultest.EmulSuite";
+  }
+
+  public void testEmptySpliterator() {
+    testSpliterator(new Object[0], Spliterators::emptySpliterator, true);
+  }
+
+  public void testEmptyDoubleSpliterator() {
+    testDoubleSpliterator(new double[0], Spliterators::emptyDoubleSpliterator, true);
+  }
+
+  public void testEmptyIntSpliterator() {
+    testIntSpliterator(new int[0], Spliterators::emptyIntSpliterator, true);
+  }
+
+  public void testEmptyLongSpliterator() {
+    testLongSpliterator(new long[0], Spliterators::emptyLongSpliterator, true);
+  }
+
+  public void testSpliterator() {
+    final String[] original = {"1", "2", "3", "4"};
+    testSpliterator(original, () -> Spliterators.spliterator(Arrays.asList(original), 0), true);
+    testSpliterator(original, () -> Spliterators.spliterator(Arrays.asList(original).iterator(), original.length, 0), true);
+    testSpliterator(original, () -> Spliterators.spliteratorUnknownSize(Arrays.asList(original).iterator(), 0), false);
+    testSpliterator(original, () -> Spliterators.spliterator(original, 0), true);
+    testSpliterator(Arrays.copyOfRange(original, 1, 3), () -> Spliterators.spliterator(original, 1, 3, 0), true);
+  }
+
+  public void testDoubleSpliterator() {
+    final double[] original = {1., 2., 3., 4.};
+    testDoubleSpliterator(original, () -> Spliterators.spliterator(original, 0), true);
+    testDoubleSpliterator(Arrays.copyOfRange(original, 1, 3), () -> Spliterators.spliterator(original, 1, 3, 0), true);
+    testDoubleSpliterator(original, () -> Spliterators.spliterator(createPrimitiveDoubleIterator(original), original.length, 0), true);
+  }
+
+  public void testIntSpliterator() {
+    final int[] original = {1, 2, 3, 4};
+    testIntSpliterator(original, () -> Spliterators.spliterator(original, 0), true);
+    testIntSpliterator(Arrays.copyOfRange(original, 1, 3), () -> Spliterators.spliterator(original, 1, 3, 0), true);
+    testIntSpliterator(original, () -> Spliterators.spliterator(createPrimitiveIntIterator(original), original.length, 0), true);
+  }
+
+  public void testLongSpliterator() {
+    final long[] original = {1, 2, 3, 4};
+    testLongSpliterator(original, () -> Spliterators.spliterator(original, 0), true);
+    testLongSpliterator(Arrays.copyOfRange(original, 1, 3), () -> Spliterators.spliterator(original, 1, 3, 0), true);
+    testLongSpliterator(original, () -> Spliterators.spliterator(createPrimitiveLongIterator(original), original.length, 0), true);
+  }
+
+  public void testIterator() {
+    final String[] original = {"1", "2", "3", "4"};
+    Spliterator<String> spliterator = Spliterators.spliterator(Arrays.asList(original), 0);
+    Iterator<String> it = Spliterators.iterator(spliterator);
+
+    try {
+      it.remove();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Deque<String> values = new LinkedList<>(Arrays.asList(original));
+    it.forEachRemaining(value -> assertEquals(values.pop(), value));
+    assertEquals(0, values.size());
+  }
+
+  public void testDoubleIterator() {
+    final double[] original = {1., 2., 3., 4.};
+    Spliterator.OfDouble spliterator = Spliterators.spliterator(original, 0);
+    PrimitiveIterator.OfDouble it = Spliterators.iterator(spliterator);
+
+    try {
+      it.remove();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Deque<Double> values = new LinkedList<>(toDoubleCollection(original));
+    it.forEachRemaining((double value) -> assertEquals((double) values.pop(), value));
+    assertEquals(0, values.size());
+  }
+
+  public void testIntIterator() {
+    final int[] original = {1, 2, 3, 4};
+    Spliterator.OfInt spliterator = Spliterators.spliterator(original, 0);
+    PrimitiveIterator.OfInt it = Spliterators.iterator(spliterator);
+
+    try {
+      it.remove();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Deque<Integer> values = new LinkedList<>(toIntCollection(original));
+    it.forEachRemaining((int value) -> assertEquals((int) values.pop(), value));
+    assertEquals(0, values.size());
+  }
+
+  public void testLongIterator() {
+    final long[] original = {1, 2, 3, 4};
+    Spliterator.OfLong spliterator = Spliterators.spliterator(original, 0);
+    PrimitiveIterator.OfLong it = Spliterators.iterator(spliterator);
+
+    try {
+      it.remove();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Deque<Long> values = new LinkedList<>(toLongCollection(original));
+    it.forEachRemaining((long value) -> assertEquals((long) values.pop(), value));
+    assertEquals(0, values.size());
+  }
+
+  private <T> void testSpliterator(T[] original, Supplier<Spliterator<T>> supplier, boolean sizeKnown) {
+    Spliterator<T> spliterator = supplier.get();
+    if (sizeKnown) {
+      assertEquals(original.length, spliterator.estimateSize());
+      assertEquals(original.length, spliterator.getExactSizeIfKnown());
+    } else {
+      assertEquals(Long.MAX_VALUE, spliterator.estimateSize());
+      assertEquals(-1L, spliterator.getExactSizeIfKnown());
+    }
+
+    Deque<T> values = new LinkedList<>(Arrays.asList(original));
+    spliterator.forEachRemaining(value -> assertEquals(values.pop(), value));
+    spliterator.forEachRemaining(value -> fail());
+    assertEquals(0, values.size());
+
+    spliterator = supplier.get();
+    for (T originalValue : original) {
+      assertTrue(spliterator.tryAdvance(value -> assertEquals(originalValue, value)));
+    }
+    assertFalse(spliterator.tryAdvance(value -> fail()));
+  }
+
+  private void testDoubleSpliterator(double[] original, Supplier<Spliterator.OfDouble> supplier, boolean sizeKnown) {
+    Spliterator.OfDouble spliterator = supplier.get();
+    if (sizeKnown) {
+      assertEquals(original.length, spliterator.estimateSize());
+      assertEquals(original.length, spliterator.getExactSizeIfKnown());
+    } else {
+      assertEquals(Long.MAX_VALUE, spliterator.estimateSize());
+      assertEquals(-1L, spliterator.getExactSizeIfKnown());
+    }
+
+    Deque<Double> values = new LinkedList<>(toDoubleCollection(original));
+    spliterator.forEachRemaining((double value) -> assertEquals((double) values.pop(), value));
+    spliterator.forEachRemaining((double value) -> fail());
+    assertEquals(0, values.size());
+
+    spliterator = supplier.get();
+    for (double originalValue : original) {
+      assertTrue(spliterator.tryAdvance((double value) -> assertEquals(originalValue, value)));
+    }
+    assertFalse(spliterator.tryAdvance((double value) -> fail()));
+  }
+
+  private void testIntSpliterator(int[] original, Supplier<Spliterator.OfInt> supplier, boolean sizeKnown) {
+    Spliterator.OfInt spliterator = supplier.get();
+    if (sizeKnown) {
+      assertEquals(original.length, spliterator.estimateSize());
+      assertEquals(original.length, spliterator.getExactSizeIfKnown());
+    } else {
+      assertEquals(Long.MAX_VALUE, spliterator.estimateSize());
+      assertEquals(-1L, spliterator.getExactSizeIfKnown());
+    }
+
+    Deque<Integer> values = new LinkedList<>(toIntCollection(original));
+    spliterator.forEachRemaining((int value) -> assertEquals((int) values.pop(), value));
+    spliterator.forEachRemaining((int value) -> fail());
+    assertEquals(0, values.size());
+
+    spliterator = supplier.get();
+    for (int originalValue : original) {
+      assertTrue(spliterator.tryAdvance((int value) -> assertEquals(originalValue, value)));
+    }
+    assertFalse(spliterator.tryAdvance((int value) -> fail()));
+  }
+
+  private void testLongSpliterator(long[] original, Supplier<Spliterator.OfLong> supplier, boolean sizeKnown) {
+    Spliterator.OfLong spliterator = supplier.get();
+    if (sizeKnown) {
+      assertEquals(original.length, spliterator.estimateSize());
+      assertEquals(original.length, spliterator.getExactSizeIfKnown());
+    } else {
+      assertEquals(Long.MAX_VALUE, spliterator.estimateSize());
+      assertEquals(-1L, spliterator.getExactSizeIfKnown());
+    }
+
+    Deque<Long> values = new LinkedList<>(toLongCollection(original));
+    spliterator.forEachRemaining((long value) -> assertEquals((long) values.pop(), value));
+    spliterator.forEachRemaining((long value) -> fail());
+    assertEquals(0, values.size());
+
+    spliterator = supplier.get();
+    for (long originalValue : original) {
+      assertTrue(spliterator.tryAdvance((long value) -> assertEquals(originalValue, value)));
+    }
+    assertFalse(spliterator.tryAdvance((long value) -> fail()));
+  }
+
+  private static Collection<Double> toDoubleCollection(double[] values) {
+    ArrayList<Double> c = new ArrayList<>();
+    for (double value : values) {
+      c.add(value);
+    }
+    return c;
+  }
+
+  private static Collection<Integer> toIntCollection(int[] values) {
+    ArrayList<Integer> c = new ArrayList<>();
+    for (int value : values) {
+      c.add(value);
+    }
+    return c;
+  }
+
+  private static Collection<Long> toLongCollection(long[] values) {
+    ArrayList<Long> c = new ArrayList<>();
+    for (long value : values) {
+      c.add(value);
+    }
+    return c;
+  }
+
+  private static PrimitiveIterator.OfDouble createPrimitiveDoubleIterator(double[] values) {
+    final Iterator<Double> it = toDoubleCollection(values).iterator();
+    return new PrimitiveIterator.OfDouble() {
+      @Override
+      public double nextDouble() {
+        return it.next();
+      }
+
+      @Override
+      public boolean hasNext() {
+        return it.hasNext();
+      }
+    };
+  }
+
+  private static PrimitiveIterator.OfInt createPrimitiveIntIterator(int[] values) {
+    final Iterator<Integer> it = toIntCollection(values).iterator();
+    return new PrimitiveIterator.OfInt() {
+      @Override
+      public int nextInt() {
+        return it.next();
+      }
+
+      @Override
+      public boolean hasNext() {
+        return it.hasNext();
+      }
+    };
+  }
+
+  private static PrimitiveIterator.OfLong createPrimitiveLongIterator(long[] values) {
+    final Iterator<Long> it = toLongCollection(values).iterator();
+    return new PrimitiveIterator.OfLong() {
+      @Override
+      public long nextLong() {
+        return it.next();
+      }
+
+      @Override
+      public boolean hasNext() {
+        return it.hasNext();
+      }
+    };
+  }
+
+}
