diff --git a/user/super/com/google/gwt/emul/java/util/stream/Collector.java b/user/super/com/google/gwt/emul/java/util/stream/Collector.java
index ce41e92..c3907ef 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/Collector.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/Collector.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package java.util.stream;
 
 import static javaemul.internal.InternalPreconditions.checkNotNull;
@@ -90,73 +89,4 @@
   BinaryOperator<A> combiner();
 
   Function<A,R> finisher();
-
-  /**
-   * Simple internal implementation of a collector, holding each of the functions in a field.
-   */
-  final class CollectorImpl<T, A, R> implements Collector<T, A, R> {
-    private final Supplier<A> supplier;
-    private final BiConsumer<A, T> accumulator;
-    private final Set<Characteristics> characteristics;
-    private final BinaryOperator<A> combiner;
-    private final Function<A, R> finisher;
-
-    public CollectorImpl(
-        Supplier<A> supplier,
-        BiConsumer<A, T> accumulator,
-        BinaryOperator<A> combiner,
-        Function<A, R> finisher,
-        Characteristics... characteristics) {
-      this.supplier = supplier;
-      this.accumulator = accumulator;
-      if (characteristics.length == 0) {
-        this.characteristics = Collections.emptySet();
-      } else if (characteristics.length == 1) {
-        this.characteristics = Collections.singleton(characteristics[0]);
-      } else {
-        this.characteristics =
-            Collections.unmodifiableSet(EnumSet.of(characteristics[0], characteristics));
-      }
-      this.combiner = combiner;
-      this.finisher = finisher;
-    }
-
-    public CollectorImpl(
-        Supplier<A> supplier,
-        BiConsumer<A, T> accumulator,
-        BinaryOperator<A> combiner,
-        Function<A, R> finisher,
-        Set<Characteristics> characteristics) {
-      this.supplier = supplier;
-      this.accumulator = accumulator;
-      this.combiner = combiner;
-      this.finisher = finisher;
-      this.characteristics = characteristics;
-    }
-
-    @Override
-    public Supplier<A> supplier() {
-      return supplier;
-    }
-
-    @Override
-    public BiConsumer<A, T> accumulator() {
-      return accumulator;
-    }
-
-    @Override
-    public BinaryOperator<A> combiner() {
-      return combiner;
-    }
-
-    @Override
-    public Function<A, R> finisher() {
-      return finisher;
-    }
-
-    @Override
-    public Set<Characteristics> characteristics() {
-      return characteristics;
-    }
-  }
 }
\ No newline at end of file
diff --git a/user/super/com/google/gwt/emul/java/util/stream/CollectorImpl.java b/user/super/com/google/gwt/emul/java/util/stream/CollectorImpl.java
new file mode 100644
index 0000000..9202a28
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/stream/CollectorImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.stream;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * Simple internal implementation of a collector, holding each of the functions in a field.
+ */
+final class CollectorImpl<T, A, R> implements Collector<T, A, R> {
+  private final Supplier<A> supplier;
+  private final BiConsumer<A, T> accumulator;
+  private final Set<Characteristics> characteristics;
+  private final BinaryOperator<A> combiner;
+  private final Function<A, R> finisher;
+
+  public CollectorImpl(
+      Supplier<A> supplier,
+      BiConsumer<A, T> accumulator,
+      BinaryOperator<A> combiner,
+      Function<A, R> finisher,
+      Characteristics... characteristics) {
+    this.supplier = supplier;
+    this.accumulator = accumulator;
+    if (characteristics.length == 0) {
+      this.characteristics = Collections.emptySet();
+    } else if (characteristics.length == 1) {
+      this.characteristics = Collections.singleton(characteristics[0]);
+    } else {
+      this.characteristics =
+          Collections.unmodifiableSet(EnumSet.of(characteristics[0], characteristics));
+    }
+    this.combiner = combiner;
+    this.finisher = finisher;
+  }
+
+  public CollectorImpl(
+      Supplier<A> supplier,
+      BiConsumer<A, T> accumulator,
+      BinaryOperator<A> combiner,
+      Function<A, R> finisher,
+      Set<Characteristics> characteristics) {
+    this.supplier = supplier;
+    this.accumulator = accumulator;
+    this.combiner = combiner;
+    this.finisher = finisher;
+    this.characteristics = characteristics;
+  }
+
+  @Override
+  public Supplier<A> supplier() {
+    return supplier;
+  }
+
+  @Override
+  public BiConsumer<A, T> accumulator() {
+    return accumulator;
+  }
+
+  @Override
+  public BinaryOperator<A> combiner() {
+    return combiner;
+  }
+
+  @Override
+  public Function<A, R> finisher() {
+    return finisher;
+  }
+
+  @Override
+  public Set<Characteristics> characteristics() {
+    return characteristics;
+  }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/stream/Collectors.java b/user/super/com/google/gwt/emul/java/util/stream/Collectors.java
index c19dfef..65edfa5 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/Collectors.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/Collectors.java
@@ -64,7 +64,7 @@
 
   public static <T, A, R, RR> Collector<T, A, RR> collectingAndThen(
       Collector<T, A, R> downstream, Function<R, RR> finisher) {
-    return new Collector.CollectorImpl<>(
+    return new CollectorImpl<>(
         downstream.supplier(),
         downstream.accumulator(),
         downstream.combiner(),
@@ -163,15 +163,15 @@
 
   public static <T, U, A, R> Collector<T, ?, R> mapping(
       final Function<? super T, ? extends U> mapper, final Collector<? super U, A, R> downstream) {
-    return new Collector.CollectorImpl<>(
+    return new CollectorImpl<>(
         downstream.supplier(),
-        (BiConsumer<A, T>) (A a, T t) -> {
-          downstream.accumulator().accept(a, mapper.apply(t));
-        },
+        (BiConsumer<A, T>)
+            (A a, T t) -> {
+              downstream.accumulator().accept(a, mapper.apply(t));
+            },
         downstream.combiner(),
         downstream.finisher(),
-        downstream.characteristics()
-    );
+        downstream.characteristics());
   }
 
   public static <T> Collector<T,?,Optional<T>> maxBy(Comparator<? super T> comparator) {
diff --git a/user/super/com/google/gwt/emul/java/util/stream/DoubleStream.java b/user/super/com/google/gwt/emul/java/util/stream/DoubleStream.java
index bfe782c..75b0474 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/DoubleStream.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/DoubleStream.java
@@ -13,22 +13,17 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package java.util.stream;
 
-import static javaemul.internal.InternalPreconditions.checkNotNull;
 import static javaemul.internal.InternalPreconditions.checkState;
 
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.DoubleSummaryStatistics;
-import java.util.HashSet;
 import java.util.OptionalDouble;
 import java.util.PrimitiveIterator;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
 import java.util.function.DoubleBinaryOperator;
 import java.util.function.DoubleConsumer;
 import java.util.function.DoubleFunction;
@@ -37,8 +32,6 @@
 import java.util.function.DoubleToIntFunction;
 import java.util.function.DoubleToLongFunction;
 import java.util.function.DoubleUnaryOperator;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
 import java.util.function.ObjDoubleConsumer;
 import java.util.function.Supplier;
 
@@ -49,18 +42,23 @@
 public interface DoubleStream extends BaseStream<Double, DoubleStream> {
 
   /**
-   * Value holder for various stream operations.
+   * See <a
+   * href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/DoubleStream.Builder.html">the
+   * official Java API doc</a> for details.
    */
-  static final class ValueConsumer implements DoubleConsumer {
-    double value;
-
+  interface Builder extends DoubleConsumer {
     @Override
-    public void accept(double value) {
-      this.value = value;
+    void accept(double t);
+
+    default DoubleStream.Builder add(double t) {
+      accept(t);
+      return this;
     }
+
+    DoubleStream build();
   }
 
-  static DoubleStream.Builder builder() {
+  static Builder builder() {
     return new Builder() {
       private double[] items = new double[0];
 
@@ -124,7 +122,7 @@
           }
         };
 
-    DoubleStream result = new DoubleStreamSource(null, spliterator);
+    DoubleStream result = new DoubleStreamImpl(null, spliterator);
 
     result.onClose(a::close);
     result.onClose(b::close);
@@ -133,7 +131,7 @@
   }
 
   static DoubleStream empty() {
-    return new EmptyDoubleStreamSource(null);
+    return new DoubleStreamImpl.Empty(null);
   }
 
   static DoubleStream generate(DoubleSupplier s) {
@@ -176,23 +174,6 @@
     return of(new double[] {t});
   }
 
-  /**
-   * See
-   * <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/DoubleStream.Builder.html">
-   * the official Java API doc</a> for details.
-   */
-  public interface Builder extends DoubleConsumer {
-    @Override
-    void accept(double t);
-
-    default DoubleStream.Builder add(double t) {
-      accept(t);
-      return this;
-    }
-
-    DoubleStream build();
-  }
-
   boolean allMatch(DoublePredicate predicate);
 
   boolean anyMatch(DoublePredicate predicate);
@@ -262,763 +243,4 @@
   DoubleSummaryStatistics summaryStatistics();
 
   double[] toArray();
-
-  /**
-   * Represents an empty stream, doing nothing for all methods.
-   */
-  static class EmptyDoubleStreamSource extends TerminatableStream<EmptyDoubleStreamSource>
-      implements DoubleStream {
-    public EmptyDoubleStreamSource(TerminatableStream<?> previous) {
-      super(previous);
-    }
-
-    @Override
-    public DoubleStream filter(DoublePredicate predicate) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream map(DoubleUnaryOperator mapper) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
-      throwIfTerminated();
-      return new Stream.EmptyStreamSource<U>(this);
-    }
-
-    @Override
-    public IntStream mapToInt(DoubleToIntFunction mapper) {
-      throwIfTerminated();
-      return new IntStream.EmptyIntStreamSource(this);
-    }
-
-    @Override
-    public LongStream mapToLong(DoubleToLongFunction mapper) {
-      throwIfTerminated();
-      return new LongStream.EmptyLongStreamSource(this);
-    }
-
-    @Override
-    public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream distinct() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream sorted() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream peek(DoubleConsumer action) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return this;
-    }
-
-    @Override
-    public DoubleStream skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      return this;
-    }
-
-    @Override
-    public void forEach(DoubleConsumer action) {
-      terminate();
-      // do nothing
-    }
-
-    @Override
-    public void forEachOrdered(DoubleConsumer action) {
-      terminate();
-      // do nothing
-    }
-
-    @Override
-    public double[] toArray() {
-      terminate();
-      return new double[0];
-    }
-
-    @Override
-    public double reduce(double identity, DoubleBinaryOperator op) {
-      terminate();
-      return identity;
-    }
-
-    @Override
-    public OptionalDouble reduce(DoubleBinaryOperator op) {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      return supplier.get();
-    }
-
-    @Override
-    public double sum() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public OptionalDouble min() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public OptionalDouble max() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public OptionalDouble average() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public DoubleSummaryStatistics summaryStatistics() {
-      terminate();
-      return new DoubleSummaryStatistics();
-    }
-
-    @Override
-    public boolean anyMatch(DoublePredicate predicate) {
-      terminate();
-      return false;
-    }
-
-    @Override
-    public boolean allMatch(DoublePredicate predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public boolean noneMatch(DoublePredicate predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public OptionalDouble findFirst() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public OptionalDouble findAny() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public Stream<Double> boxed() {
-      throwIfTerminated();
-      return new Stream.EmptyStreamSource<Double>(this);
-    }
-
-    @Override
-    public DoubleStream sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public PrimitiveIterator.OfDouble iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public Spliterator.OfDouble spliterator() {
-      terminate();
-      return Spliterators.emptyDoubleSpliterator();
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public DoubleStream unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
-
-  /**
-   * Double to Int map spliterator.
-   */
-  static final class MapToIntSpliterator extends Spliterators.AbstractIntSpliterator {
-    private final DoubleToIntFunction map;
-    private final Spliterator.OfDouble original;
-
-    public MapToIntSpliterator(DoubleToIntFunction map, Spliterator.OfDouble original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final IntConsumer action) {
-      return original.tryAdvance((double u) -> action.accept(map.applyAsInt(u)));
-    }
-  }
-
-  /**
-   * Double to Object map spliterator.
-   * @param <T> the type of Object in the spliterator
-   */
-  static final class MapToObjSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
-    private final DoubleFunction<? extends T> map;
-    private final Spliterator.OfDouble original;
-
-    public MapToObjSpliterator(DoubleFunction<? extends T> map, Spliterator.OfDouble original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final Consumer<? super T> action) {
-      return original.tryAdvance((double u) -> action.accept(map.apply(u)));
-    }
-  }
-
-  /**
-   * Double to Long map spliterator.
-   */
-  static final class MapToLongSpliterator extends Spliterators.AbstractLongSpliterator {
-    private final DoubleToLongFunction map;
-    private final Spliterator.OfDouble original;
-
-    public MapToLongSpliterator(DoubleToLongFunction map, Spliterator.OfDouble original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final LongConsumer action) {
-      return original.tryAdvance((double u) -> action.accept(map.applyAsLong(u)));
-    }
-  }
-
-  /**
-   * Double to Double map spliterator.
-   */
-  static final class MapToDoubleSpliterator extends Spliterators.AbstractDoubleSpliterator {
-    private final DoubleUnaryOperator map;
-    private final Spliterator.OfDouble original;
-
-    public MapToDoubleSpliterator(DoubleUnaryOperator map, Spliterator.OfDouble original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final DoubleConsumer action) {
-      return original.tryAdvance((double u) -> action.accept(map.applyAsDouble(u)));
-    }
-  }
-
-  /**
-   * Double filter spliterator.
-   */
-  static final class FilterSpliterator extends Spliterators.AbstractDoubleSpliterator {
-    private final DoublePredicate filter;
-    private final Spliterator.OfDouble original;
-
-    private boolean found;
-
-    public FilterSpliterator(DoublePredicate filter, Spliterator.OfDouble original) {
-      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
-      checkNotNull(filter);
-      this.filter = filter;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Double> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(final DoubleConsumer action) {
-      found = false;
-      while (!found
-          && original.tryAdvance(
-              (double item) -> {
-                if (filter.test(item)) {
-                  found = true;
-                  action.accept(item);
-                }
-              })) {
-        // do nothing, work is done in tryAdvance
-      }
-
-      return found;
-    }
-  }
-
-  /**
-   * Double skip spliterator.
-   */
-  static final class SkipSpliterator extends Spliterators.AbstractDoubleSpliterator {
-    private long skip;
-    private final Spliterator.OfDouble original;
-
-    public SkipSpliterator(long skip, Spliterator.OfDouble original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.max(0, original.estimateSize() - skip)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.skip = skip;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Double> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(DoubleConsumer action) {
-      while (skip > 0) {
-        if (!original.tryAdvance((double ignore) -> { })) {
-          return false;
-        }
-        skip--;
-      }
-      return original.tryAdvance(action);
-    }
-  }
-
-  /**
-   * Double limit spliterator.
-   */
-  static final class LimitSpliterator extends Spliterators.AbstractDoubleSpliterator {
-    private final long limit;
-    private final Spliterator.OfDouble original;
-    private int position = 0;
-
-    public LimitSpliterator(long limit, Spliterator.OfDouble original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.min(original.estimateSize(), limit)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.limit = limit;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Double> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(DoubleConsumer action) {
-      if (position >= limit) {
-        return false;
-      }
-
-      boolean result = original.tryAdvance(action);
-      position++;
-      return result;
-    }
-  }
-
-  /**
-   * Main implementation of DoubleStream, wrapping a single spliterator, and an optional parent
-   * stream.
-   */
-  static class DoubleStreamSource extends TerminatableStream<DoubleStreamSource>
-      implements DoubleStream {
-    private final Spliterator.OfDouble spliterator;
-
-    public DoubleStreamSource(TerminatableStream<?> previous, Spliterator.OfDouble spliterator) {
-      super(previous);
-      this.spliterator = spliterator;
-    }
-
-    // terminals
-
-    @Override
-    public void forEach(DoubleConsumer action) {
-      forEachOrdered(action);
-    }
-
-    @Override
-    public void forEachOrdered(DoubleConsumer action) {
-      terminate();
-      spliterator.forEachRemaining(action);
-    }
-
-    @Override
-    public double[] toArray() {
-      terminate();
-      double[] entries = new double[0];
-      // this is legal in js, since the array will be backed by a JS array
-      spliterator.forEachRemaining((double value) -> entries[entries.length] = value);
-
-      return entries;
-    }
-
-    @Override
-    public double reduce(double identity, DoubleBinaryOperator op) {
-      terminate();
-      ValueConsumer holder = new ValueConsumer();
-      holder.value = identity;
-      spliterator.forEachRemaining(
-          (double value) -> {
-            holder.accept(op.applyAsDouble(holder.value, value));
-          });
-      return holder.value;
-    }
-
-    @Override
-    public OptionalDouble reduce(DoubleBinaryOperator op) {
-      ValueConsumer holder = new ValueConsumer();
-      if (spliterator.tryAdvance(holder)) {
-        return OptionalDouble.of(reduce(holder.value, op));
-      }
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      final R acc = supplier.get();
-      spliterator.forEachRemaining((double value) -> accumulator.accept(acc, value));
-      return acc;
-    }
-
-    @Override
-    public double sum() {
-      return summaryStatistics().getSum();
-    }
-
-    @Override
-    public OptionalDouble min() {
-      DoubleSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalDouble.empty();
-      }
-      return OptionalDouble.of(stats.getMin());
-    }
-
-    @Override
-    public OptionalDouble max() {
-      DoubleSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalDouble.empty();
-      }
-      return OptionalDouble.of(stats.getMax());
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      long count = 0;
-      while (spliterator.tryAdvance((double value) -> { })) {
-        count++;
-      }
-      return count;
-    }
-
-    @Override
-    public OptionalDouble average() {
-      DoubleSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalDouble.empty();
-      }
-      return OptionalDouble.of(stats.getAverage());
-    }
-
-    @Override
-    public DoubleSummaryStatistics summaryStatistics() {
-      return collect(
-          DoubleSummaryStatistics::new,
-          // TODO switch to a lambda reference once #9340 is fixed
-          (doubleSummaryStatistics, value) -> doubleSummaryStatistics.accept(value),
-          DoubleSummaryStatistics::combine);
-    }
-
-    @Override
-    public boolean anyMatch(DoublePredicate predicate) {
-      return filter(predicate).findFirst().isPresent();
-    }
-
-    @Override
-    public boolean allMatch(DoublePredicate predicate) {
-      return !anyMatch(predicate.negate());
-    }
-
-    @Override
-    public boolean noneMatch(DoublePredicate predicate) {
-      return !anyMatch(predicate);
-    }
-
-    @Override
-    public OptionalDouble findFirst() {
-      terminate();
-      ValueConsumer holder = new ValueConsumer();
-      if (spliterator.tryAdvance(holder)) {
-        return OptionalDouble.of(holder.value);
-      }
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public OptionalDouble findAny() {
-      return findFirst();
-    }
-
-    @Override
-    public PrimitiveIterator.OfDouble iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public Spliterator.OfDouble spliterator() {
-      terminate();
-      return spliterator;
-    }
-
-    // end terminals
-
-    // intermediates
-
-    @Override
-    public DoubleStream filter(DoublePredicate predicate) {
-      throwIfTerminated();
-      return new DoubleStreamSource(this, new FilterSpliterator(predicate, spliterator));
-    }
-
-    @Override
-    public DoubleStream map(DoubleUnaryOperator mapper) {
-      throwIfTerminated();
-      return new DoubleStreamSource(this, new MapToDoubleSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
-      throwIfTerminated();
-      return new Stream.StreamSource<U>(this, new MapToObjSpliterator<U>(mapper, spliterator));
-    }
-
-    @Override
-    public IntStream mapToInt(DoubleToIntFunction mapper) {
-      throwIfTerminated();
-      return new IntStream.IntStreamSource(this, new MapToIntSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public LongStream mapToLong(DoubleToLongFunction mapper) {
-      throwIfTerminated();
-      return new LongStream.LongStreamSource(this, new MapToLongSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends DoubleStream> spliteratorOfStreams =
-          new MapToObjSpliterator<DoubleStream>(mapper, spliterator);
-
-      Spliterator.OfDouble flatMapSpliterator =
-          new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE, 0) {
-            DoubleStream nextStream;
-            Spliterator.OfDouble next;
-
-            @Override
-            public boolean tryAdvance(DoubleConsumer action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new DoubleStreamSource(this, flatMapSpliterator);
-    }
-
-    @Override
-    public DoubleStream distinct() {
-      throwIfTerminated();
-      HashSet<Double> seen = new HashSet<>();
-      return filter(seen::add);
-    }
-
-    @Override
-    public DoubleStream sorted() {
-      throwIfTerminated();
-
-      Spliterator.OfDouble sortingSpliterator =
-          new Spliterators.AbstractDoubleSpliterator(
-              spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
-            Spliterator.OfDouble ordered = null;
-
-            @Override
-            public Comparator<? super Double> getComparator() {
-              return null;
-            }
-
-            @Override
-            public boolean tryAdvance(DoubleConsumer action) {
-              if (ordered == null) {
-                double[] list = new double[0];
-                spliterator.forEachRemaining((double item) -> list[list.length] = item);
-                Arrays.sort(list);
-                ordered = Spliterators.spliterator(list, characteristics());
-              }
-              return ordered.tryAdvance(action);
-            }
-          };
-
-      return new DoubleStreamSource(this, sortingSpliterator);
-    }
-
-    @Override
-    public DoubleStream peek(DoubleConsumer action) {
-      checkNotNull(action);
-      throwIfTerminated();
-
-      Spliterator.OfDouble peekSpliterator =
-          new Spliterators.AbstractDoubleSpliterator(
-              spliterator.estimateSize(), spliterator.characteristics()) {
-            @Override
-            public boolean tryAdvance(final DoubleConsumer innerAction) {
-              return spliterator.tryAdvance(action.andThen(innerAction));
-            }
-          };
-
-      return new DoubleStreamSource(this, peekSpliterator);
-    }
-
-    @Override
-    public DoubleStream limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return new DoubleStreamSource(this, new LimitSpliterator(maxSize, spliterator));
-    }
-
-    @Override
-    public DoubleStream skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      if (n == 0) {
-        return this;
-      }
-      return new DoubleStreamSource(this, new SkipSpliterator(n, spliterator));
-    }
-
-    @Override
-    public Stream<Double> boxed() {
-      return mapToObj(Double::valueOf);
-    }
-
-    @Override
-    public DoubleStream sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public DoubleStream parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public DoubleStream unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/stream/DoubleStreamImpl.java b/user/super/com/google/gwt/emul/java/util/stream/DoubleStreamImpl.java
new file mode 100644
index 0000000..5353a05
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/stream/DoubleStreamImpl.java
@@ -0,0 +1,812 @@
+/*
+ * 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.stream;
+
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+import static javaemul.internal.InternalPreconditions.checkState;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.DoubleSummaryStatistics;
+import java.util.HashSet;
+import java.util.OptionalDouble;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.DoubleConsumer;
+import java.util.function.DoubleFunction;
+import java.util.function.DoublePredicate;
+import java.util.function.DoubleToIntFunction;
+import java.util.function.DoubleToLongFunction;
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.ObjDoubleConsumer;
+import java.util.function.Supplier;
+
+/**
+ * Main implementation of DoubleStream, wrapping a single spliterator, and an optional parent
+ * stream.
+ */
+final class DoubleStreamImpl extends TerminatableStream<DoubleStreamImpl> implements DoubleStream {
+
+  /**
+   * Represents an empty stream, doing nothing for all methods.
+   */
+  static class Empty extends TerminatableStream<Empty> implements DoubleStream {
+    public Empty(TerminatableStream<?> previous) {
+      super(previous);
+    }
+
+    @Override
+    public DoubleStream filter(DoublePredicate predicate) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public DoubleStream map(DoubleUnaryOperator mapper) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
+      throwIfTerminated();
+      return new StreamImpl.Empty<U>(this);
+    }
+
+    @Override
+    public IntStream mapToInt(DoubleToIntFunction mapper) {
+      throwIfTerminated();
+      return new IntStreamImpl.Empty(this);
+    }
+
+    @Override
+    public LongStream mapToLong(DoubleToLongFunction mapper) {
+      throwIfTerminated();
+      return new LongStreamImpl.Empty(this);
+    }
+
+    @Override
+    public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public DoubleStream distinct() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public DoubleStream sorted() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public DoubleStream peek(DoubleConsumer action) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public DoubleStream limit(long maxSize) {
+      throwIfTerminated();
+      checkState(maxSize >= 0, "maxSize may not be negative");
+      return this;
+    }
+
+    @Override
+    public DoubleStream skip(long n) {
+      throwIfTerminated();
+      checkState(n >= 0, "n may not be negative");
+      return this;
+    }
+
+    @Override
+    public void forEach(DoubleConsumer action) {
+      terminate();
+      // do nothing
+    }
+
+    @Override
+    public void forEachOrdered(DoubleConsumer action) {
+      terminate();
+      // do nothing
+    }
+
+    @Override
+    public double[] toArray() {
+      terminate();
+      return new double[0];
+    }
+
+    @Override
+    public double reduce(double identity, DoubleBinaryOperator op) {
+      terminate();
+      return identity;
+    }
+
+    @Override
+    public OptionalDouble reduce(DoubleBinaryOperator op) {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public <R> R collect(
+        Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+      terminate();
+      return supplier.get();
+    }
+
+    @Override
+    public double sum() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public OptionalDouble min() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public OptionalDouble max() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public long count() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public OptionalDouble average() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public DoubleSummaryStatistics summaryStatistics() {
+      terminate();
+      return new DoubleSummaryStatistics();
+    }
+
+    @Override
+    public boolean anyMatch(DoublePredicate predicate) {
+      terminate();
+      return false;
+    }
+
+    @Override
+    public boolean allMatch(DoublePredicate predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public boolean noneMatch(DoublePredicate predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public OptionalDouble findFirst() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public OptionalDouble findAny() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public Stream<Double> boxed() {
+      throwIfTerminated();
+      return new StreamImpl.Empty<Double>(this);
+    }
+
+    @Override
+    public DoubleStream sequential() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public DoubleStream parallel() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public PrimitiveIterator.OfDouble iterator() {
+      return Spliterators.iterator(spliterator());
+    }
+
+    @Override
+    public Spliterator.OfDouble spliterator() {
+      terminate();
+      return Spliterators.emptyDoubleSpliterator();
+    }
+
+    @Override
+    public boolean isParallel() {
+      throwIfTerminated();
+      return false;
+    }
+
+    @Override
+    public DoubleStream unordered() {
+      throwIfTerminated();
+      return this;
+    }
+  }
+
+  /**
+   * Double to Int map spliterator.
+   */
+  private static final class MapToIntSpliterator extends Spliterators.AbstractIntSpliterator {
+    private final DoubleToIntFunction map;
+    private final Spliterator.OfDouble original;
+
+    public MapToIntSpliterator(DoubleToIntFunction map, Spliterator.OfDouble original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final IntConsumer action) {
+      return original.tryAdvance((double u) -> action.accept(map.applyAsInt(u)));
+    }
+  }
+
+  /**
+   * Double to Object map spliterator.
+   *
+   * @param <T> the type of Object in the spliterator
+   */
+  private static final class MapToObjSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
+    private final DoubleFunction<? extends T> map;
+    private final Spliterator.OfDouble original;
+
+    public MapToObjSpliterator(DoubleFunction<? extends T> map, Spliterator.OfDouble original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final Consumer<? super T> action) {
+      return original.tryAdvance((double u) -> action.accept(map.apply(u)));
+    }
+  }
+
+  /**
+   * Double to Long map spliterator.
+   */
+  private static final class MapToLongSpliterator extends Spliterators.AbstractLongSpliterator {
+    private final DoubleToLongFunction map;
+    private final Spliterator.OfDouble original;
+
+    public MapToLongSpliterator(DoubleToLongFunction map, Spliterator.OfDouble original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final LongConsumer action) {
+      return original.tryAdvance((double u) -> action.accept(map.applyAsLong(u)));
+    }
+  }
+
+  /**
+   * Double to Double map spliterator.
+   */
+  private static final class MapToDoubleSpliterator extends Spliterators.AbstractDoubleSpliterator {
+    private final DoubleUnaryOperator map;
+    private final Spliterator.OfDouble original;
+
+    public MapToDoubleSpliterator(DoubleUnaryOperator map, Spliterator.OfDouble original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final DoubleConsumer action) {
+      return original.tryAdvance((double u) -> action.accept(map.applyAsDouble(u)));
+    }
+  }
+
+  /**
+   * Double filter spliterator.
+   */
+  private static final class FilterSpliterator extends Spliterators.AbstractDoubleSpliterator {
+    private final DoublePredicate filter;
+    private final Spliterator.OfDouble original;
+
+    private boolean found;
+
+    public FilterSpliterator(DoublePredicate filter, Spliterator.OfDouble original) {
+      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
+      checkNotNull(filter);
+      this.filter = filter;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Double> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(final DoubleConsumer action) {
+      found = false;
+      while (!found
+          && original.tryAdvance(
+              (double item) -> {
+                if (filter.test(item)) {
+                  found = true;
+                  action.accept(item);
+                }
+              })) {
+        // do nothing, work is done in tryAdvance
+      }
+
+      return found;
+    }
+  }
+
+  /**
+   * Double skip spliterator.
+   */
+  private static final class SkipSpliterator extends Spliterators.AbstractDoubleSpliterator {
+    private long skip;
+    private final Spliterator.OfDouble original;
+
+    public SkipSpliterator(long skip, Spliterator.OfDouble original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.max(0, original.estimateSize() - skip)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.skip = skip;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Double> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(DoubleConsumer action) {
+      while (skip > 0) {
+        if (!original.tryAdvance((double ignore) -> { })) {
+          return false;
+        }
+        skip--;
+      }
+      return original.tryAdvance(action);
+    }
+  }
+
+  /**
+   * Double limit spliterator.
+   */
+  private static final class LimitSpliterator extends Spliterators.AbstractDoubleSpliterator {
+    private final long limit;
+    private final Spliterator.OfDouble original;
+    private int position = 0;
+
+    public LimitSpliterator(long limit, Spliterator.OfDouble original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.min(original.estimateSize(), limit)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.limit = limit;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Double> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(DoubleConsumer action) {
+      if (position >= limit) {
+        return false;
+      }
+
+      boolean result = original.tryAdvance(action);
+      position++;
+      return result;
+    }
+  }
+
+  /**
+   * Value holder for various stream operations.
+   */
+  private static class ValueConsumer implements DoubleConsumer {
+    double value;
+
+    @Override
+    public void accept(double value) {
+      this.value = value;
+    }
+  }
+
+  private final Spliterator.OfDouble spliterator;
+
+  public DoubleStreamImpl(TerminatableStream<?> previous, Spliterator.OfDouble spliterator) {
+    super(previous);
+    this.spliterator = spliterator;
+  }
+
+  // terminals
+
+  @Override
+  public void forEach(DoubleConsumer action) {
+    forEachOrdered(action);
+  }
+
+  @Override
+  public void forEachOrdered(DoubleConsumer action) {
+    terminate();
+    spliterator.forEachRemaining(action);
+  }
+
+  @Override
+  public double[] toArray() {
+    terminate();
+    double[] entries = new double[0];
+    // this is legal in js, since the array will be backed by a JS array
+    spliterator.forEachRemaining((double value) -> entries[entries.length] = value);
+
+    return entries;
+  }
+
+  @Override
+  public double reduce(double identity, DoubleBinaryOperator op) {
+    terminate();
+    ValueConsumer holder = new ValueConsumer();
+    holder.value = identity;
+    spliterator.forEachRemaining(
+        (double value) -> {
+          holder.accept(op.applyAsDouble(holder.value, value));
+        });
+    return holder.value;
+  }
+
+  @Override
+  public OptionalDouble reduce(DoubleBinaryOperator op) {
+    ValueConsumer holder = new ValueConsumer();
+    if (spliterator.tryAdvance(holder)) {
+      return OptionalDouble.of(reduce(holder.value, op));
+    }
+    terminate();
+    return OptionalDouble.empty();
+  }
+
+  @Override
+  public <R> R collect(
+      Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+    terminate();
+    final R acc = supplier.get();
+    spliterator.forEachRemaining((double value) -> accumulator.accept(acc, value));
+    return acc;
+  }
+
+  @Override
+  public double sum() {
+    return summaryStatistics().getSum();
+  }
+
+  @Override
+  public OptionalDouble min() {
+    DoubleSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalDouble.empty();
+    }
+    return OptionalDouble.of(stats.getMin());
+  }
+
+  @Override
+  public OptionalDouble max() {
+    DoubleSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalDouble.empty();
+    }
+    return OptionalDouble.of(stats.getMax());
+  }
+
+  @Override
+  public long count() {
+    terminate();
+    long count = 0;
+    while (spliterator.tryAdvance((double value) -> { })) {
+      count++;
+    }
+    return count;
+  }
+
+  @Override
+  public OptionalDouble average() {
+    DoubleSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalDouble.empty();
+    }
+    return OptionalDouble.of(stats.getAverage());
+  }
+
+  @Override
+  public DoubleSummaryStatistics summaryStatistics() {
+    return collect(
+        DoubleSummaryStatistics::new,
+        // TODO switch to a lambda reference once #9340 is fixed
+        (doubleSummaryStatistics, value) -> doubleSummaryStatistics.accept(value),
+        DoubleSummaryStatistics::combine);
+  }
+
+  @Override
+  public boolean anyMatch(DoublePredicate predicate) {
+    return filter(predicate).findFirst().isPresent();
+  }
+
+  @Override
+  public boolean allMatch(DoublePredicate predicate) {
+    return !anyMatch(predicate.negate());
+  }
+
+  @Override
+  public boolean noneMatch(DoublePredicate predicate) {
+    return !anyMatch(predicate);
+  }
+
+  @Override
+  public OptionalDouble findFirst() {
+    terminate();
+    ValueConsumer holder = new ValueConsumer();
+    if (spliterator.tryAdvance(holder)) {
+      return OptionalDouble.of(holder.value);
+    }
+    return OptionalDouble.empty();
+  }
+
+  @Override
+  public OptionalDouble findAny() {
+    return findFirst();
+  }
+
+  @Override
+  public PrimitiveIterator.OfDouble iterator() {
+    return Spliterators.iterator(spliterator());
+  }
+
+  @Override
+  public Spliterator.OfDouble spliterator() {
+    terminate();
+    return spliterator;
+  }
+
+  // end terminals
+
+  // intermediates
+
+  @Override
+  public DoubleStream filter(DoublePredicate predicate) {
+    throwIfTerminated();
+    return new DoubleStreamImpl(this, new FilterSpliterator(predicate, spliterator));
+  }
+
+  @Override
+  public DoubleStream map(DoubleUnaryOperator mapper) {
+    throwIfTerminated();
+    return new DoubleStreamImpl(this, new MapToDoubleSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
+    throwIfTerminated();
+    return new StreamImpl<U>(this, new MapToObjSpliterator<U>(mapper, spliterator));
+  }
+
+  @Override
+  public IntStream mapToInt(DoubleToIntFunction mapper) {
+    throwIfTerminated();
+    return new IntStreamImpl(this, new MapToIntSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public LongStream mapToLong(DoubleToLongFunction mapper) {
+    throwIfTerminated();
+    return new LongStreamImpl(this, new MapToLongSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends DoubleStream> spliteratorOfStreams =
+        new MapToObjSpliterator<DoubleStream>(mapper, spliterator);
+
+    Spliterator.OfDouble flatMapSpliterator =
+        new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE, 0) {
+          DoubleStream nextStream;
+          Spliterator.OfDouble next;
+
+          @Override
+          public boolean tryAdvance(DoubleConsumer action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new DoubleStreamImpl(this, flatMapSpliterator);
+  }
+
+  @Override
+  public DoubleStream distinct() {
+    throwIfTerminated();
+    HashSet<Double> seen = new HashSet<>();
+    return filter(seen::add);
+  }
+
+  @Override
+  public DoubleStream sorted() {
+    throwIfTerminated();
+
+    Spliterator.OfDouble sortingSpliterator =
+        new Spliterators.AbstractDoubleSpliterator(
+            spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
+          Spliterator.OfDouble ordered = null;
+
+          @Override
+          public Comparator<? super Double> getComparator() {
+            return null;
+          }
+
+          @Override
+          public boolean tryAdvance(DoubleConsumer action) {
+            if (ordered == null) {
+              double[] list = new double[0];
+              spliterator.forEachRemaining((double item) -> list[list.length] = item);
+              Arrays.sort(list);
+              ordered = Spliterators.spliterator(list, characteristics());
+            }
+            return ordered.tryAdvance(action);
+          }
+        };
+
+    return new DoubleStreamImpl(this, sortingSpliterator);
+  }
+
+  @Override
+  public DoubleStream peek(DoubleConsumer action) {
+    checkNotNull(action);
+    throwIfTerminated();
+
+    Spliterator.OfDouble peekSpliterator =
+        new Spliterators.AbstractDoubleSpliterator(
+            spliterator.estimateSize(), spliterator.characteristics()) {
+          @Override
+          public boolean tryAdvance(final DoubleConsumer innerAction) {
+            return spliterator.tryAdvance(action.andThen(innerAction));
+          }
+        };
+
+    return new DoubleStreamImpl(this, peekSpliterator);
+  }
+
+  @Override
+  public DoubleStream limit(long maxSize) {
+    throwIfTerminated();
+    checkState(maxSize >= 0, "maxSize may not be negative");
+    return new DoubleStreamImpl(this, new LimitSpliterator(maxSize, spliterator));
+  }
+
+  @Override
+  public DoubleStream skip(long n) {
+    throwIfTerminated();
+    checkState(n >= 0, "n may not be negative");
+    if (n == 0) {
+      return this;
+    }
+    return new DoubleStreamImpl(this, new SkipSpliterator(n, spliterator));
+  }
+
+  @Override
+  public Stream<Double> boxed() {
+    return mapToObj(Double::valueOf);
+  }
+
+  @Override
+  public DoubleStream sequential() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public DoubleStream parallel() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public boolean isParallel() {
+    throwIfTerminated();
+    return false;
+  }
+
+  @Override
+  public DoubleStream unordered() {
+    throwIfTerminated();
+    return this;
+  }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/stream/IntStream.java b/user/super/com/google/gwt/emul/java/util/stream/IntStream.java
index 1a2b3fd..efd9ef4 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/IntStream.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/IntStream.java
@@ -13,15 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package java.util.stream;
 
-import static javaemul.internal.InternalPreconditions.checkNotNull;
 import static javaemul.internal.InternalPreconditions.checkState;
 
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.HashSet;
 import java.util.IntSummaryStatistics;
 import java.util.OptionalDouble;
 import java.util.OptionalInt;
@@ -30,8 +27,6 @@
 import java.util.Spliterators;
 import java.util.Spliterators.AbstractIntSpliterator;
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.DoubleConsumer;
 import java.util.function.IntBinaryOperator;
 import java.util.function.IntConsumer;
 import java.util.function.IntFunction;
@@ -40,7 +35,6 @@
 import java.util.function.IntToDoubleFunction;
 import java.util.function.IntToLongFunction;
 import java.util.function.IntUnaryOperator;
-import java.util.function.LongConsumer;
 import java.util.function.ObjIntConsumer;
 import java.util.function.Supplier;
 
@@ -51,18 +45,23 @@
 public interface IntStream extends BaseStream<Integer, IntStream> {
 
   /**
-   * Value holder for various stream operations.
+   * See <a
+   * href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.Builder.html">the
+   * official Java API doc</a> for details.
    */
-  static final class ValueConsumer implements IntConsumer {
-    int value;
-
+  interface Builder extends IntConsumer {
     @Override
-    public void accept(int value) {
-      this.value = value;
+    void accept(int t);
+
+    default IntStream.Builder add(int t) {
+      accept(t);
+      return this;
     }
+
+    IntStream build();
   }
 
-  static IntStream.Builder builder() {
+  static Builder builder() {
     return new Builder() {
       private int[] items = new int[0];
 
@@ -126,7 +125,7 @@
           }
         };
 
-    IntStream result = new IntStreamSource(null, spliterator);
+    IntStream result = new IntStreamImpl(null, spliterator);
 
     result.onClose(a::close);
     result.onClose(b::close);
@@ -135,7 +134,7 @@
   }
 
   static IntStream empty() {
-    return new EmptyIntStreamSource(null);
+    return new IntStreamImpl.Empty(null);
   }
 
   static IntStream generate(final IntSupplier s) {
@@ -221,23 +220,6 @@
     return StreamSupport.intStream(spliterator, false);
   }
 
-  /**
-   * See
-   * <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.Builder.html">
-   * the official Java API doc</a> for details.
-   */
-  public interface Builder extends IntConsumer {
-    @Override
-    void accept(int t);
-
-    default IntStream.Builder add(int t) {
-      accept(t);
-      return this;
-    }
-
-    IntStream build();
-  }
-
   boolean allMatch(IntPredicate predicate);
 
   boolean anyMatch(IntPredicate predicate);
@@ -311,781 +293,4 @@
   IntSummaryStatistics summaryStatistics();
 
   int[] toArray();
-
-  /**
-   * Represents an empty stream, doing nothing for all methods.
-   */
-  static class EmptyIntStreamSource extends TerminatableStream<EmptyIntStreamSource>
-      implements IntStream {
-    public EmptyIntStreamSource(TerminatableStream<?> previous) {
-      super(previous);
-    }
-
-    @Override
-    public IntStream filter(IntPredicate predicate) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream map(IntUnaryOperator mapper) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
-      throwIfTerminated();
-      return new Stream.EmptyStreamSource<U>(this);
-    }
-
-    @Override
-    public LongStream mapToLong(IntToLongFunction mapper) {
-      throwIfTerminated();
-      return new LongStream.EmptyLongStreamSource(this);
-    }
-
-    @Override
-    public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
-      throwIfTerminated();
-      return new DoubleStream.EmptyDoubleStreamSource(this);
-    }
-
-    @Override
-    public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream distinct() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream sorted() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream peek(IntConsumer action) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return this;
-    }
-
-    @Override
-    public IntStream skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      return this;
-    }
-
-    @Override
-    public void forEach(IntConsumer action) {
-      terminate();
-      // do nothing
-    }
-
-    @Override
-    public void forEachOrdered(IntConsumer action) {
-      terminate();
-      // do nothing
-    }
-
-    @Override
-    public int[] toArray() {
-      terminate();
-      return new int[0];
-    }
-
-    @Override
-    public int reduce(int identity, IntBinaryOperator op) {
-      terminate();
-      return identity;
-    }
-
-    @Override
-    public OptionalInt reduce(IntBinaryOperator op) {
-      terminate();
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      return supplier.get();
-    }
-
-    @Override
-    public int sum() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public OptionalInt min() {
-      terminate();
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public OptionalInt max() {
-      terminate();
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public OptionalDouble average() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public IntSummaryStatistics summaryStatistics() {
-      terminate();
-      return new IntSummaryStatistics();
-    }
-
-    @Override
-    public boolean anyMatch(IntPredicate predicate) {
-      terminate();
-      return false;
-    }
-
-    @Override
-    public boolean allMatch(IntPredicate predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public boolean noneMatch(IntPredicate predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public OptionalInt findFirst() {
-      terminate();
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public OptionalInt findAny() {
-      terminate();
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public LongStream asLongStream() {
-      throwIfTerminated();
-      return new LongStream.EmptyLongStreamSource(this);
-    }
-
-    @Override
-    public DoubleStream asDoubleStream() {
-      throwIfTerminated();
-      return new DoubleStream.EmptyDoubleStreamSource(this);
-    }
-
-    @Override
-    public Stream<Integer> boxed() {
-      throwIfTerminated();
-      return new Stream.EmptyStreamSource<Integer>(this);
-    }
-
-    @Override
-    public IntStream sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public PrimitiveIterator.OfInt iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public Spliterator.OfInt spliterator() {
-      terminate();
-      return Spliterators.emptyIntSpliterator();
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public IntStream unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
-
-  /**
-   * Int to Int map spliterator.
-   */
-  static final class MapToIntSpliterator extends Spliterators.AbstractIntSpliterator {
-    private final IntUnaryOperator map;
-    private final Spliterator.OfInt original;
-
-    public MapToIntSpliterator(IntUnaryOperator map, Spliterator.OfInt original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final IntConsumer action) {
-      return original.tryAdvance((int u) -> action.accept(map.applyAsInt(u)));
-    }
-  }
-
-  /**
-   * Int to Object map spliterator.
-   * @param <T> the type of data in the object spliterator
-   */
-  static final class MapToObjSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
-    private final IntFunction<? extends T> map;
-    private final Spliterator.OfInt original;
-
-    public MapToObjSpliterator(IntFunction<? extends T> map, Spliterator.OfInt original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final Consumer<? super T> action) {
-      return original.tryAdvance((int u) -> action.accept(map.apply(u)));
-    }
-  }
-
-  /**
-   * Int to Long map spliterator.
-   */
-  static final class MapToLongSpliterator extends Spliterators.AbstractLongSpliterator {
-    private final IntToLongFunction map;
-    private final Spliterator.OfInt original;
-
-    public MapToLongSpliterator(IntToLongFunction map, Spliterator.OfInt original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final LongConsumer action) {
-      return original.tryAdvance((int u) -> action.accept(map.applyAsLong(u)));
-    }
-  }
-
-  /**
-   * Int to Double map spliterator.
-   */
-  static final class MapToDoubleSpliterator extends Spliterators.AbstractDoubleSpliterator {
-    private final IntToDoubleFunction map;
-    private final Spliterator.OfInt original;
-
-    public MapToDoubleSpliterator(IntToDoubleFunction map, Spliterator.OfInt original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final DoubleConsumer action) {
-      return original.tryAdvance((int u) -> action.accept(map.applyAsDouble(u)));
-    }
-  }
-
-  /**
-   * Int filter spliterator.
-   */
-  static final class FilterSpliterator extends Spliterators.AbstractIntSpliterator {
-    private final IntPredicate filter;
-    private final Spliterator.OfInt original;
-
-    private boolean found;
-
-    public FilterSpliterator(IntPredicate filter, Spliterator.OfInt original) {
-      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
-      checkNotNull(filter);
-      this.filter = filter;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Integer> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(final IntConsumer action) {
-      found = false;
-      while (!found
-          && original.tryAdvance(
-              (int item) -> {
-                if (filter.test(item)) {
-                  found = true;
-                  action.accept(item);
-                }
-              })) {
-        // do nothing, work is done in tryAdvance
-      }
-
-      return found;
-    }
-  }
-
-  /**
-   * Int skip spliterator.
-   */
-  static final class SkipSpliterator extends Spliterators.AbstractIntSpliterator {
-    private long skip;
-    private final Spliterator.OfInt original;
-
-    public SkipSpliterator(long skip, Spliterator.OfInt original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.max(0, original.estimateSize() - skip)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.skip = skip;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Integer> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(IntConsumer action) {
-      while (skip > 0) {
-        if (!original.tryAdvance((int ignore) -> { })) {
-          return false;
-        }
-        skip--;
-      }
-      return original.tryAdvance(action);
-    }
-  }
-
-  /**
-   * Int limit spliterator.
-   */
-  static final class LimitSpliterator extends Spliterators.AbstractIntSpliterator {
-    private final long limit;
-    private final Spliterator.OfInt original;
-    private int position = 0;
-
-    public LimitSpliterator(long limit, Spliterator.OfInt original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.min(original.estimateSize(), limit)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.limit = limit;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Integer> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(IntConsumer action) {
-      if (position >= limit) {
-        return false;
-      }
-      boolean result = original.tryAdvance(action);
-      position++;
-      return result;
-    }
-  }
-
-  /**
-   * Main implementation of IntStream, wrapping a single spliterator, and an optional parent stream.
-   */
-  static class IntStreamSource extends TerminatableStream<IntStreamSource> implements IntStream {
-    private final Spliterator.OfInt spliterator;
-
-    public IntStreamSource(TerminatableStream<?> previous, Spliterator.OfInt spliterator) {
-      super(previous);
-      this.spliterator = spliterator;
-    }
-
-    // terminals
-    @Override
-    public Spliterator.OfInt spliterator() {
-      terminate();
-      return spliterator;
-    }
-
-    @Override
-    public PrimitiveIterator.OfInt iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public OptionalInt findFirst() {
-      terminate();
-      ValueConsumer holder = new ValueConsumer();
-      if (spliterator.tryAdvance(holder)) {
-        return OptionalInt.of(holder.value);
-      }
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public OptionalInt findAny() {
-      return findFirst();
-    }
-
-    @Override
-    public boolean noneMatch(IntPredicate predicate) {
-      return !anyMatch(predicate);
-    }
-
-    @Override
-    public boolean allMatch(IntPredicate predicate) {
-      return !anyMatch(predicate.negate());
-    }
-
-    @Override
-    public boolean anyMatch(IntPredicate predicate) {
-      return filter(predicate).findFirst().isPresent();
-    }
-
-    @Override
-    public IntSummaryStatistics summaryStatistics() {
-      return collect(
-          IntSummaryStatistics::new,
-          // TODO switch to a lambda reference once #9340 is fixed
-          (intSummaryStatistics, value) -> intSummaryStatistics.accept(value),
-          IntSummaryStatistics::combine);
-    }
-
-    @Override
-    public OptionalDouble average() {
-      IntSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalDouble.empty();
-      }
-      return OptionalDouble.of(stats.getAverage());
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      long count = 0;
-      while (spliterator.tryAdvance((int value) -> { })) {
-        count++;
-      }
-      return count;
-    }
-
-    @Override
-    public OptionalInt max() {
-      IntSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalInt.empty();
-      }
-      return OptionalInt.of(stats.getMax());
-    }
-
-    @Override
-    public OptionalInt min() {
-      IntSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalInt.empty();
-      }
-      return OptionalInt.of(stats.getMin());
-    }
-
-    @Override
-    public int sum() {
-      return (int) summaryStatistics().getSum();
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, final ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      final R acc = supplier.get();
-      spliterator.forEachRemaining((int value) -> accumulator.accept(acc, value));
-      return acc;
-    }
-
-    @Override
-    public OptionalInt reduce(IntBinaryOperator op) {
-      ValueConsumer holder = new ValueConsumer();
-      if (spliterator.tryAdvance(holder)) {
-        return OptionalInt.of(reduce(holder.value, op));
-      }
-      terminate();
-      return OptionalInt.empty();
-    }
-
-    @Override
-    public int reduce(int identity, IntBinaryOperator op) {
-      terminate();
-      ValueConsumer holder = new ValueConsumer();
-      holder.value = identity;
-      spliterator.forEachRemaining(
-          (int value) -> {
-            holder.accept(op.applyAsInt(holder.value, value));
-          });
-      return holder.value;
-    }
-
-    @Override
-    public int[] toArray() {
-      terminate();
-      int[] entries = new int[0];
-      // this is legal in js, since the array will be backed by a JS array
-      spliterator.forEachRemaining((int value) -> entries[entries.length] = value);
-
-      return entries;
-    }
-
-    @Override
-    public void forEachOrdered(IntConsumer action) {
-      terminate();
-      spliterator.forEachRemaining(action);
-    }
-
-    @Override
-    public void forEach(IntConsumer action) {
-      forEachOrdered(action);
-    }
-    // end terminals
-
-    // intermediates
-
-    @Override
-    public IntStream filter(IntPredicate predicate) {
-      throwIfTerminated();
-      return new IntStreamSource(this, new FilterSpliterator(predicate, spliterator));
-    }
-
-    @Override
-    public IntStream map(IntUnaryOperator mapper) {
-      throwIfTerminated();
-      return new IntStreamSource(this, new MapToIntSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
-      throwIfTerminated();
-      return new Stream.StreamSource<U>(this, new MapToObjSpliterator<U>(mapper, spliterator));
-    }
-
-    @Override
-    public LongStream mapToLong(IntToLongFunction mapper) {
-      throwIfTerminated();
-      return new LongStream.LongStreamSource(this, new MapToLongSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
-      throwIfTerminated();
-      return new DoubleStream.DoubleStreamSource(
-          this, new MapToDoubleSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends IntStream> spliteratorOfStreams =
-          new MapToObjSpliterator<>(mapper, spliterator);
-
-      Spliterator.OfInt flatMapSpliterator =
-          new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE, 0) {
-            IntStream nextStream;
-            Spliterator.OfInt next;
-
-            @Override
-            public boolean tryAdvance(IntConsumer action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new IntStreamSource(this, flatMapSpliterator);
-    }
-
-    @Override
-    public IntStream distinct() {
-      throwIfTerminated();
-      HashSet<Integer> seen = new HashSet<>();
-      return filter(seen::add);
-    }
-
-    @Override
-    public IntStream sorted() {
-      throwIfTerminated();
-
-      AbstractIntSpliterator sortedSpliterator =
-          new Spliterators.AbstractIntSpliterator(
-              spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
-            Spliterator.OfInt ordered = null;
-
-            @Override
-            public Comparator<? super Integer> getComparator() {
-              return null;
-            }
-
-            @Override
-            public boolean tryAdvance(IntConsumer action) {
-              if (ordered == null) {
-                int[] list = new int[0];
-                spliterator.forEachRemaining((int item) -> list[list.length] = item);
-                Arrays.sort(list);
-                ordered = Spliterators.spliterator(list, characteristics());
-              }
-              return ordered.tryAdvance(action);
-            }
-          };
-
-      return new IntStreamSource(this, sortedSpliterator);
-    }
-
-    @Override
-    public IntStream peek(IntConsumer action) {
-      checkNotNull(action);
-      throwIfTerminated();
-
-      AbstractIntSpliterator peekSpliterator =
-          new Spliterators.AbstractIntSpliterator(
-              spliterator.estimateSize(), spliterator.characteristics()) {
-            @Override
-            public boolean tryAdvance(final IntConsumer innerAction) {
-              return spliterator.tryAdvance(action.andThen(innerAction));
-            }
-          };
-
-      return new IntStreamSource(this, peekSpliterator);
-    }
-
-    @Override
-    public IntStream limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return new IntStreamSource(this, new LimitSpliterator(maxSize, spliterator));
-    }
-
-    @Override
-    public IntStream skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      if (n == 0) {
-        return this;
-      }
-      return new IntStreamSource(this, new SkipSpliterator(n, spliterator));
-    }
-
-    @Override
-    public LongStream asLongStream() {
-      return mapToLong(i -> (long) i);
-    }
-
-    @Override
-    public DoubleStream asDoubleStream() {
-      return mapToDouble(i -> (double) i);
-    }
-
-    @Override
-    public Stream<Integer> boxed() {
-      return mapToObj(Integer::valueOf);
-    }
-
-    @Override
-    public IntStream sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public IntStream parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public IntStream unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/stream/IntStreamImpl.java b/user/super/com/google/gwt/emul/java/util/stream/IntStreamImpl.java
new file mode 100644
index 0000000..6839314
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/stream/IntStreamImpl.java
@@ -0,0 +1,832 @@
+/*
+ * 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.stream;
+
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+import static javaemul.internal.InternalPreconditions.checkState;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.IntSummaryStatistics;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.Spliterators.AbstractIntSpliterator;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.ObjIntConsumer;
+import java.util.function.Supplier;
+
+/**
+ * Main implementation of IntStream, wrapping a single spliterator, and an optional parent stream.
+ */
+final class IntStreamImpl extends TerminatableStream<IntStreamImpl> implements IntStream {
+
+  /**
+   * Represents an empty stream, doing nothing for all methods.
+   */
+  static class Empty extends TerminatableStream<Empty> implements IntStream {
+    public Empty(TerminatableStream<?> previous) {
+      super(previous);
+    }
+
+    @Override
+    public IntStream filter(IntPredicate predicate) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public IntStream map(IntUnaryOperator mapper) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
+      throwIfTerminated();
+      return new StreamImpl.Empty<U>(this);
+    }
+
+    @Override
+    public LongStream mapToLong(IntToLongFunction mapper) {
+      throwIfTerminated();
+      return new LongStreamImpl.Empty(this);
+    }
+
+    @Override
+    public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
+      throwIfTerminated();
+      return new DoubleStreamImpl.Empty(this);
+    }
+
+    @Override
+    public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public IntStream distinct() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public IntStream sorted() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public IntStream peek(IntConsumer action) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public IntStream limit(long maxSize) {
+      throwIfTerminated();
+      checkState(maxSize >= 0, "maxSize may not be negative");
+      return this;
+    }
+
+    @Override
+    public IntStream skip(long n) {
+      throwIfTerminated();
+      checkState(n >= 0, "n may not be negative");
+      return this;
+    }
+
+    @Override
+    public void forEach(IntConsumer action) {
+      terminate();
+      // do nothing
+    }
+
+    @Override
+    public void forEachOrdered(IntConsumer action) {
+      terminate();
+      // do nothing
+    }
+
+    @Override
+    public int[] toArray() {
+      terminate();
+      return new int[0];
+    }
+
+    @Override
+    public int reduce(int identity, IntBinaryOperator op) {
+      terminate();
+      return identity;
+    }
+
+    @Override
+    public OptionalInt reduce(IntBinaryOperator op) {
+      terminate();
+      return OptionalInt.empty();
+    }
+
+    @Override
+    public <R> R collect(
+        Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+      terminate();
+      return supplier.get();
+    }
+
+    @Override
+    public int sum() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public OptionalInt min() {
+      terminate();
+      return OptionalInt.empty();
+    }
+
+    @Override
+    public OptionalInt max() {
+      terminate();
+      return OptionalInt.empty();
+    }
+
+    @Override
+    public long count() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public OptionalDouble average() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public IntSummaryStatistics summaryStatistics() {
+      terminate();
+      return new IntSummaryStatistics();
+    }
+
+    @Override
+    public boolean anyMatch(IntPredicate predicate) {
+      terminate();
+      return false;
+    }
+
+    @Override
+    public boolean allMatch(IntPredicate predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public boolean noneMatch(IntPredicate predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public OptionalInt findFirst() {
+      terminate();
+      return OptionalInt.empty();
+    }
+
+    @Override
+    public OptionalInt findAny() {
+      terminate();
+      return OptionalInt.empty();
+    }
+
+    @Override
+    public LongStream asLongStream() {
+      throwIfTerminated();
+      return new LongStreamImpl.Empty(this);
+    }
+
+    @Override
+    public DoubleStream asDoubleStream() {
+      throwIfTerminated();
+      return new DoubleStreamImpl.Empty(this);
+    }
+
+    @Override
+    public Stream<Integer> boxed() {
+      throwIfTerminated();
+      return new StreamImpl.Empty<Integer>(this);
+    }
+
+    @Override
+    public IntStream sequential() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public IntStream parallel() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public PrimitiveIterator.OfInt iterator() {
+      return Spliterators.iterator(spliterator());
+    }
+
+    @Override
+    public Spliterator.OfInt spliterator() {
+      terminate();
+      return Spliterators.emptyIntSpliterator();
+    }
+
+    @Override
+    public boolean isParallel() {
+      throwIfTerminated();
+      return false;
+    }
+
+    @Override
+    public IntStream unordered() {
+      throwIfTerminated();
+      return this;
+    }
+  }
+
+  /**
+   * Int to Int map spliterator.
+   */
+  private static final class MapToIntSpliterator extends Spliterators.AbstractIntSpliterator {
+    private final IntUnaryOperator map;
+    private final Spliterator.OfInt original;
+
+    public MapToIntSpliterator(IntUnaryOperator map, Spliterator.OfInt original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final IntConsumer action) {
+      return original.tryAdvance((int u) -> action.accept(map.applyAsInt(u)));
+    }
+  }
+
+  /**
+   * Int to Object map spliterator.
+   *
+   * @param <T> the type of data in the object spliterator
+   */
+  private static final class MapToObjSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
+    private final IntFunction<? extends T> map;
+    private final Spliterator.OfInt original;
+
+    public MapToObjSpliterator(IntFunction<? extends T> map, Spliterator.OfInt original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final Consumer<? super T> action) {
+      return original.tryAdvance((int u) -> action.accept(map.apply(u)));
+    }
+  }
+
+  /**
+   * Int to Long map spliterator.
+   */
+  private static final class MapToLongSpliterator extends Spliterators.AbstractLongSpliterator {
+    private final IntToLongFunction map;
+    private final Spliterator.OfInt original;
+
+    public MapToLongSpliterator(IntToLongFunction map, Spliterator.OfInt original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final LongConsumer action) {
+      return original.tryAdvance((int u) -> action.accept(map.applyAsLong(u)));
+    }
+  }
+
+  /**
+   * Int to Double map spliterator.
+   */
+  private static final class MapToDoubleSpliterator extends Spliterators.AbstractDoubleSpliterator {
+    private final IntToDoubleFunction map;
+    private final Spliterator.OfInt original;
+
+    public MapToDoubleSpliterator(IntToDoubleFunction map, Spliterator.OfInt original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final DoubleConsumer action) {
+      return original.tryAdvance((int u) -> action.accept(map.applyAsDouble(u)));
+    }
+  }
+
+  /**
+   * Int filter spliterator.
+   */
+  private static final class FilterSpliterator extends Spliterators.AbstractIntSpliterator {
+    private final IntPredicate filter;
+    private final Spliterator.OfInt original;
+
+    private boolean found;
+
+    public FilterSpliterator(IntPredicate filter, Spliterator.OfInt original) {
+      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
+      checkNotNull(filter);
+      this.filter = filter;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Integer> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(final IntConsumer action) {
+      found = false;
+      while (!found
+          && original.tryAdvance(
+              (int item) -> {
+                if (filter.test(item)) {
+                  found = true;
+                  action.accept(item);
+                }
+              })) {
+        // do nothing, work is done in tryAdvance
+      }
+
+      return found;
+    }
+  }
+
+  /**
+   * Int skip spliterator.
+   */
+  private static final class SkipSpliterator extends Spliterators.AbstractIntSpliterator {
+    private long skip;
+    private final Spliterator.OfInt original;
+
+    public SkipSpliterator(long skip, Spliterator.OfInt original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.max(0, original.estimateSize() - skip)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.skip = skip;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Integer> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(IntConsumer action) {
+      while (skip > 0) {
+        if (!original.tryAdvance((int ignore) -> { })) {
+          return false;
+        }
+        skip--;
+      }
+      return original.tryAdvance(action);
+    }
+  }
+
+  /**
+   * Int limit spliterator.
+   */
+  private static final class LimitSpliterator extends Spliterators.AbstractIntSpliterator {
+    private final long limit;
+    private final Spliterator.OfInt original;
+    private int position = 0;
+
+    public LimitSpliterator(long limit, Spliterator.OfInt original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.min(original.estimateSize(), limit)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.limit = limit;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Integer> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(IntConsumer action) {
+      if (position >= limit) {
+        return false;
+      }
+      boolean result = original.tryAdvance(action);
+      position++;
+      return result;
+    }
+  }
+
+  /**
+   * Value holder for various stream operations.
+   */
+  private static final class ValueConsumer implements IntConsumer {
+    int value;
+
+    @Override
+    public void accept(int value) {
+      this.value = value;
+    }
+  }
+
+  private final Spliterator.OfInt spliterator;
+
+  public IntStreamImpl(TerminatableStream<?> previous, Spliterator.OfInt spliterator) {
+    super(previous);
+    this.spliterator = spliterator;
+  }
+
+  // terminals
+  @Override
+  public Spliterator.OfInt spliterator() {
+    terminate();
+    return spliterator;
+  }
+
+  @Override
+  public PrimitiveIterator.OfInt iterator() {
+    return Spliterators.iterator(spliterator());
+  }
+
+  @Override
+  public OptionalInt findFirst() {
+    terminate();
+    ValueConsumer holder = new ValueConsumer();
+    if (spliterator.tryAdvance(holder)) {
+      return OptionalInt.of(holder.value);
+    }
+    return OptionalInt.empty();
+  }
+
+  @Override
+  public OptionalInt findAny() {
+    return findFirst();
+  }
+
+  @Override
+  public boolean noneMatch(IntPredicate predicate) {
+    return !anyMatch(predicate);
+  }
+
+  @Override
+  public boolean allMatch(IntPredicate predicate) {
+    return !anyMatch(predicate.negate());
+  }
+
+  @Override
+  public boolean anyMatch(IntPredicate predicate) {
+    return filter(predicate).findFirst().isPresent();
+  }
+
+  @Override
+  public IntSummaryStatistics summaryStatistics() {
+    return collect(
+        IntSummaryStatistics::new,
+        // TODO switch to a lambda reference once #9340 is fixed
+        (intSummaryStatistics, value) -> intSummaryStatistics.accept(value),
+        IntSummaryStatistics::combine);
+  }
+
+  @Override
+  public OptionalDouble average() {
+    IntSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalDouble.empty();
+    }
+    return OptionalDouble.of(stats.getAverage());
+  }
+
+  @Override
+  public long count() {
+    terminate();
+    long count = 0;
+    while (spliterator.tryAdvance((int value) -> { })) {
+      count++;
+    }
+    return count;
+  }
+
+  @Override
+  public OptionalInt max() {
+    IntSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalInt.empty();
+    }
+    return OptionalInt.of(stats.getMax());
+  }
+
+  @Override
+  public OptionalInt min() {
+    IntSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalInt.empty();
+    }
+    return OptionalInt.of(stats.getMin());
+  }
+
+  @Override
+  public int sum() {
+    return (int) summaryStatistics().getSum();
+  }
+
+  @Override
+  public <R> R collect(
+      Supplier<R> supplier, final ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+    terminate();
+    final R acc = supplier.get();
+    spliterator.forEachRemaining((int value) -> accumulator.accept(acc, value));
+    return acc;
+  }
+
+  @Override
+  public OptionalInt reduce(IntBinaryOperator op) {
+    ValueConsumer holder = new ValueConsumer();
+    if (spliterator.tryAdvance(holder)) {
+      return OptionalInt.of(reduce(holder.value, op));
+    }
+    terminate();
+    return OptionalInt.empty();
+  }
+
+  @Override
+  public int reduce(int identity, IntBinaryOperator op) {
+    terminate();
+    ValueConsumer holder = new ValueConsumer();
+    holder.value = identity;
+    spliterator.forEachRemaining(
+        (int value) -> {
+          holder.accept(op.applyAsInt(holder.value, value));
+        });
+    return holder.value;
+  }
+
+  @Override
+  public int[] toArray() {
+    terminate();
+    int[] entries = new int[0];
+    // this is legal in js, since the array will be backed by a JS array
+    spliterator.forEachRemaining((int value) -> entries[entries.length] = value);
+
+    return entries;
+  }
+
+  @Override
+  public void forEachOrdered(IntConsumer action) {
+    terminate();
+    spliterator.forEachRemaining(action);
+  }
+
+  @Override
+  public void forEach(IntConsumer action) {
+    forEachOrdered(action);
+  }
+  // end terminals
+
+  // intermediates
+
+  @Override
+  public IntStream filter(IntPredicate predicate) {
+    throwIfTerminated();
+    return new IntStreamImpl(this, new FilterSpliterator(predicate, spliterator));
+  }
+
+  @Override
+  public IntStream map(IntUnaryOperator mapper) {
+    throwIfTerminated();
+    return new IntStreamImpl(this, new MapToIntSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
+    throwIfTerminated();
+    return new StreamImpl<U>(this, new MapToObjSpliterator<U>(mapper, spliterator));
+  }
+
+  @Override
+  public LongStream mapToLong(IntToLongFunction mapper) {
+    throwIfTerminated();
+    return new LongStreamImpl(this, new MapToLongSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
+    throwIfTerminated();
+    return new DoubleStreamImpl(this, new MapToDoubleSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends IntStream> spliteratorOfStreams =
+        new MapToObjSpliterator<>(mapper, spliterator);
+
+    Spliterator.OfInt flatMapSpliterator =
+        new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE, 0) {
+          IntStream nextStream;
+          Spliterator.OfInt next;
+
+          @Override
+          public boolean tryAdvance(IntConsumer action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new IntStreamImpl(this, flatMapSpliterator);
+  }
+
+  @Override
+  public IntStream distinct() {
+    throwIfTerminated();
+    HashSet<Integer> seen = new HashSet<>();
+    return filter(seen::add);
+  }
+
+  @Override
+  public IntStream sorted() {
+    throwIfTerminated();
+
+    AbstractIntSpliterator sortedSpliterator =
+        new Spliterators.AbstractIntSpliterator(
+            spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
+          Spliterator.OfInt ordered = null;
+
+          @Override
+          public Comparator<? super Integer> getComparator() {
+            return null;
+          }
+
+          @Override
+          public boolean tryAdvance(IntConsumer action) {
+            if (ordered == null) {
+              int[] list = new int[0];
+              spliterator.forEachRemaining((int item) -> list[list.length] = item);
+              Arrays.sort(list);
+              ordered = Spliterators.spliterator(list, characteristics());
+            }
+            return ordered.tryAdvance(action);
+          }
+        };
+
+    return new IntStreamImpl(this, sortedSpliterator);
+  }
+
+  @Override
+  public IntStream peek(IntConsumer action) {
+    checkNotNull(action);
+    throwIfTerminated();
+
+    AbstractIntSpliterator peekSpliterator =
+        new Spliterators.AbstractIntSpliterator(
+            spliterator.estimateSize(), spliterator.characteristics()) {
+          @Override
+          public boolean tryAdvance(final IntConsumer innerAction) {
+            return spliterator.tryAdvance(action.andThen(innerAction));
+          }
+        };
+
+    return new IntStreamImpl(this, peekSpliterator);
+  }
+
+  @Override
+  public IntStream limit(long maxSize) {
+    throwIfTerminated();
+    checkState(maxSize >= 0, "maxSize may not be negative");
+    return new IntStreamImpl(this, new LimitSpliterator(maxSize, spliterator));
+  }
+
+  @Override
+  public IntStream skip(long n) {
+    throwIfTerminated();
+    checkState(n >= 0, "n may not be negative");
+    if (n == 0) {
+      return this;
+    }
+    return new IntStreamImpl(this, new SkipSpliterator(n, spliterator));
+  }
+
+  @Override
+  public LongStream asLongStream() {
+    return mapToLong(i -> (long) i);
+  }
+
+  @Override
+  public DoubleStream asDoubleStream() {
+    return mapToDouble(i -> (double) i);
+  }
+
+  @Override
+  public Stream<Integer> boxed() {
+    return mapToObj(Integer::valueOf);
+  }
+
+  @Override
+  public IntStream sequential() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public IntStream parallel() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public boolean isParallel() {
+    throwIfTerminated();
+    return false;
+  }
+
+  @Override
+  public IntStream unordered() {
+    throwIfTerminated();
+    return this;
+  }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/stream/LongStream.java b/user/super/com/google/gwt/emul/java/util/stream/LongStream.java
index 6981225..611ef9b 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/LongStream.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/LongStream.java
@@ -13,15 +13,12 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package java.util.stream;
 
-import static javaemul.internal.InternalPreconditions.checkNotNull;
 import static javaemul.internal.InternalPreconditions.checkState;
 
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.HashSet;
 import java.util.LongSummaryStatistics;
 import java.util.OptionalDouble;
 import java.util.OptionalLong;
@@ -30,9 +27,6 @@
 import java.util.Spliterators;
 import java.util.Spliterators.AbstractLongSpliterator;
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.DoubleConsumer;
-import java.util.function.IntConsumer;
 import java.util.function.LongBinaryOperator;
 import java.util.function.LongConsumer;
 import java.util.function.LongFunction;
@@ -51,18 +45,23 @@
 public interface LongStream extends BaseStream<Long, LongStream> {
 
   /**
-   * Value holder for various stream operations.
+   * See <a
+   * href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/LongStream.Builder.html">the
+   * official Java API doc</a> for details.
    */
-  static final class ValueConsumer implements LongConsumer {
-    long value;
-
+  interface Builder extends LongConsumer {
     @Override
-    public void accept(long value) {
-      this.value = value;
+    void accept(long t);
+
+    default LongStream.Builder add(long t) {
+      accept(t);
+      return this;
     }
+
+    LongStream build();
   }
 
-  static LongStream.Builder builder() {
+  static Builder builder() {
     return new Builder() {
       private long[] items = new long[0];
 
@@ -126,7 +125,7 @@
           }
         };
 
-    LongStream result = new LongStreamSource(null, spliterator);
+    LongStream result = new LongStreamImpl(null, spliterator);
 
     result.onClose(a::close);
     result.onClose(b::close);
@@ -135,7 +134,7 @@
   }
 
   static LongStream empty() {
-    return new EmptyLongStreamSource(null);
+    return new LongStreamImpl.Empty(null);
   }
 
   static LongStream generate(LongSupplier s) {
@@ -219,23 +218,6 @@
     return StreamSupport.longStream(spliterator, false);
   }
 
-  /**
-   * See
-   * <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/LongStream.Builder.html">
-   * the official Java API doc</a> for details.
-   */
-  public interface Builder extends LongConsumer {
-    @Override
-    void accept(long t);
-
-    default LongStream.Builder add(long t) {
-      accept(t);
-      return this;
-    }
-
-    LongStream build();
-  }
-
   boolean allMatch(LongPredicate predicate);
 
   boolean anyMatch(LongPredicate predicate);
@@ -307,769 +289,4 @@
   LongSummaryStatistics summaryStatistics();
 
   long[] toArray();
-
-  /**
-   * Represents an empty stream, doing nothing for all methods.
-   */
-  static class EmptyLongStreamSource extends TerminatableStream<EmptyLongStreamSource>
-      implements LongStream {
-    public EmptyLongStreamSource(TerminatableStream<?> previous) {
-      super(previous);
-    }
-
-    @Override
-    public LongStream filter(LongPredicate predicate) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream map(LongUnaryOperator mapper) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
-      throwIfTerminated();
-      return new Stream.EmptyStreamSource<U>(this);
-    }
-
-    @Override
-    public IntStream mapToInt(LongToIntFunction mapper) {
-      throwIfTerminated();
-      return new IntStream.EmptyIntStreamSource(this);
-    }
-
-    @Override
-    public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
-      throwIfTerminated();
-      return new DoubleStream.EmptyDoubleStreamSource(this);
-    }
-
-    @Override
-    public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream distinct() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream sorted() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream peek(LongConsumer action) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return this;
-    }
-
-    @Override
-    public LongStream skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      return this;
-    }
-
-    @Override
-    public void forEach(LongConsumer action) {
-      terminate();
-    }
-
-    @Override
-    public void forEachOrdered(LongConsumer action) {
-      terminate();
-    }
-
-    @Override
-    public long[] toArray() {
-      terminate();
-      return new long[0];
-    }
-
-    @Override
-    public long reduce(long identity, LongBinaryOperator op) {
-      terminate();
-      return identity;
-    }
-
-    @Override
-    public OptionalLong reduce(LongBinaryOperator op) {
-      terminate();
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      return supplier.get();
-    }
-
-    @Override
-    public long sum() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public OptionalLong min() {
-      terminate();
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public OptionalLong max() {
-      terminate();
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public OptionalDouble average() {
-      terminate();
-      return OptionalDouble.empty();
-    }
-
-    @Override
-    public LongSummaryStatistics summaryStatistics() {
-      terminate();
-      return new LongSummaryStatistics();
-    }
-
-    @Override
-    public boolean anyMatch(LongPredicate predicate) {
-      terminate();
-      return false;
-    }
-
-    @Override
-    public boolean allMatch(LongPredicate predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public boolean noneMatch(LongPredicate predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public OptionalLong findFirst() {
-      terminate();
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public OptionalLong findAny() {
-      terminate();
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public DoubleStream asDoubleStream() {
-      throwIfTerminated();
-      return new DoubleStream.EmptyDoubleStreamSource(this);
-    }
-
-    @Override
-    public Stream<Long> boxed() {
-      throwIfTerminated();
-      return new Stream.EmptyStreamSource<Long>(this);
-    }
-
-    @Override
-    public LongStream sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public PrimitiveIterator.OfLong iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public Spliterator.OfLong spliterator() {
-      terminate();
-      return Spliterators.emptyLongSpliterator();
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public LongStream unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
-
-  /**
-   * Long to Int map spliterator.
-   */
-  static final class MapToIntSpliterator extends Spliterators.AbstractIntSpliterator {
-    private final LongToIntFunction map;
-    private final Spliterator.OfLong original;
-
-    public MapToIntSpliterator(LongToIntFunction map, Spliterator.OfLong original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final IntConsumer action) {
-      return original.tryAdvance((long u) -> action.accept(map.applyAsInt(u)));
-    }
-  }
-
-  /**
-   * Long to Object map spliterator.
-   * @param <T> the type of data in the object spliterator
-   */
-  static final class MapToObjSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
-    private final LongFunction<? extends T> map;
-    private final Spliterator.OfLong original;
-
-    public MapToObjSpliterator(LongFunction<? extends T> map, Spliterator.OfLong original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final Consumer<? super T> action) {
-      return original.tryAdvance((long u) -> action.accept(map.apply(u)));
-    }
-  }
-
-  /**
-   * Long to Long map spliterator.
-   */
-  static final class MapToLongSpliterator extends Spliterators.AbstractLongSpliterator {
-    private final LongUnaryOperator map;
-    private final Spliterator.OfLong original;
-
-    public MapToLongSpliterator(LongUnaryOperator map, Spliterator.OfLong original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final LongConsumer action) {
-      return original.tryAdvance((long u) -> action.accept(map.applyAsLong(u)));
-    }
-  }
-
-  /**
-   * Long to Double map Spliterator.
-   */
-  static final class MapToDoubleSpliterator extends Spliterators.AbstractDoubleSpliterator {
-    private final LongToDoubleFunction map;
-    private final Spliterator.OfLong original;
-
-    public MapToDoubleSpliterator(LongToDoubleFunction map, Spliterator.OfLong original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final DoubleConsumer action) {
-      return original.tryAdvance((long u) -> action.accept(map.applyAsDouble(u)));
-    }
-  }
-
-  /**
-   * Long filter spliterator.
-   */
-  static final class FilterSpliterator extends Spliterators.AbstractLongSpliterator {
-    private final LongPredicate filter;
-    private final Spliterator.OfLong original;
-
-    private boolean found;
-
-    public FilterSpliterator(LongPredicate filter, Spliterator.OfLong original) {
-      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
-      checkNotNull(filter);
-      this.filter = filter;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Long> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(final LongConsumer action) {
-      found = false;
-      while (!found
-          && original.tryAdvance(
-              (long item) -> {
-                if (filter.test(item)) {
-                  found = true;
-                  action.accept(item);
-                }
-              })) {
-        // do nothing, work is done in tryAdvance
-      }
-
-      return found;
-    }
-  }
-
-  /**
-   * Long skip spliterator.
-   */
-  static final class SkipSpliterator extends Spliterators.AbstractLongSpliterator {
-    private long skip;
-    private final Spliterator.OfLong original;
-
-    public SkipSpliterator(long skip, Spliterator.OfLong original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.max(0, original.estimateSize() - skip)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.skip = skip;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Long> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(LongConsumer action) {
-      while (skip > 0) {
-        if (!original.tryAdvance((long ignore) -> { })) {
-          return false;
-        }
-        skip--;
-      }
-      return original.tryAdvance(action);
-    }
-  }
-
-  /**
-   * Long limit spliterator.
-   */
-  static final class LimitSpliterator extends Spliterators.AbstractLongSpliterator {
-    private final long limit;
-    private final Spliterator.OfLong original;
-    private int position = 0;
-
-    public LimitSpliterator(long limit, Spliterator.OfLong original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.min(original.estimateSize(), limit)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.limit = limit;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super Long> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(LongConsumer action) {
-      if (position >= limit) {
-        return false;
-      }
-      boolean result = original.tryAdvance(action);
-      position++;
-      return result;
-    }
-  }
-
-  /**
-   * Main implementation of LongStream, wrapping a single spliterator, and an optional parent
-   * stream.
-   */
-  static class LongStreamSource extends TerminatableStream<LongStreamSource> implements LongStream {
-    private final Spliterator.OfLong spliterator;
-
-    public LongStreamSource(TerminatableStream<?> previous, Spliterator.OfLong spliterator) {
-      super(previous);
-      this.spliterator = spliterator;
-    }
-
-    // terminals
-
-    @Override
-    public void forEach(LongConsumer action) {
-      forEachOrdered(action);
-    }
-
-    @Override
-    public void forEachOrdered(LongConsumer action) {
-      terminate();
-      spliterator.forEachRemaining(action);
-    }
-
-    @Override
-    public long[] toArray() {
-      terminate();
-      long[] entries = new long[0];
-      // this is legal in js, since the array will be backed by a JS array
-      spliterator.forEachRemaining((long value) -> entries[entries.length] = value);
-
-      return entries;
-    }
-
-    @Override
-    public long reduce(long identity, LongBinaryOperator op) {
-      terminate();
-      ValueConsumer holder = new ValueConsumer();
-      holder.value = identity;
-      spliterator.forEachRemaining(
-          (long value) -> {
-            holder.accept(op.applyAsLong(holder.value, value));
-          });
-      return holder.value;
-    }
-
-    @Override
-    public OptionalLong reduce(LongBinaryOperator op) {
-      ValueConsumer holder = new ValueConsumer();
-      if (spliterator.tryAdvance(holder)) {
-        return OptionalLong.of(reduce(holder.value, op));
-      }
-      terminate();
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      final R acc = supplier.get();
-      spliterator.forEachRemaining((long value) -> accumulator.accept(acc, value));
-      return acc;
-    }
-
-    @Override
-    public long sum() {
-      return summaryStatistics().getSum();
-    }
-
-    @Override
-    public OptionalLong min() {
-      LongSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalLong.empty();
-      }
-      return OptionalLong.of(stats.getMin());
-    }
-
-    @Override
-    public OptionalLong max() {
-      LongSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalLong.empty();
-      }
-      return OptionalLong.of(stats.getMax());
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      long count = 0;
-      while (spliterator.tryAdvance((long value) -> { })) {
-        count++;
-      }
-      return count;
-    }
-
-    @Override
-    public OptionalDouble average() {
-      LongSummaryStatistics stats = summaryStatistics();
-      if (stats.getCount() == 0) {
-        return OptionalDouble.empty();
-      }
-      return OptionalDouble.of(stats.getAverage());
-    }
-
-    @Override
-    public LongSummaryStatistics summaryStatistics() {
-      return collect(
-          LongSummaryStatistics::new,
-          // TODO switch to a lambda reference once #9340 is fixed
-          (longSummaryStatistics, value) -> longSummaryStatistics.accept(value),
-          LongSummaryStatistics::combine);
-    }
-
-    @Override
-    public boolean anyMatch(LongPredicate predicate) {
-      return filter(predicate).findFirst().isPresent();
-    }
-
-    @Override
-    public boolean allMatch(LongPredicate predicate) {
-      return !anyMatch(predicate.negate());
-    }
-
-    @Override
-    public boolean noneMatch(LongPredicate predicate) {
-      return !anyMatch(predicate);
-    }
-
-    @Override
-    public OptionalLong findFirst() {
-      terminate();
-      ValueConsumer holder = new ValueConsumer();
-      if (spliterator.tryAdvance(holder)) {
-        return OptionalLong.of(holder.value);
-      }
-      return OptionalLong.empty();
-    }
-
-    @Override
-    public OptionalLong findAny() {
-      return findFirst();
-    }
-
-    @Override
-    public PrimitiveIterator.OfLong iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public Spliterator.OfLong spliterator() {
-      terminate();
-      return spliterator;
-    }
-    // end terminals
-
-    // intermediates
-    @Override
-    public LongStream filter(LongPredicate predicate) {
-      throwIfTerminated();
-      return new LongStreamSource(this, new FilterSpliterator(predicate, spliterator));
-    }
-
-    @Override
-    public LongStream map(LongUnaryOperator mapper) {
-      throwIfTerminated();
-      return new LongStream.LongStreamSource(this, new MapToLongSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
-      throwIfTerminated();
-      return new Stream.StreamSource<U>(this, new MapToObjSpliterator<U>(mapper, spliterator));
-    }
-
-    @Override
-    public IntStream mapToInt(LongToIntFunction mapper) {
-      throwIfTerminated();
-      return new IntStream.IntStreamSource(this, new MapToIntSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
-      throwIfTerminated();
-      return new DoubleStream.DoubleStreamSource(
-          this, new MapToDoubleSpliterator(mapper, spliterator));
-    }
-
-    @Override
-    public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends LongStream> spliteratorOfStreams =
-          new MapToObjSpliterator<>(mapper, spliterator);
-
-      AbstractLongSpliterator flatMapSpliterator =
-          new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE, 0) {
-            LongStream nextStream;
-            Spliterator.OfLong next;
-
-            @Override
-            public boolean tryAdvance(LongConsumer action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new LongStreamSource(this, flatMapSpliterator);
-    }
-
-    @Override
-    public LongStream distinct() {
-      throwIfTerminated();
-      HashSet<Long> seen = new HashSet<>();
-      return filter(seen::add);
-    }
-
-    @Override
-    public LongStream sorted() {
-      throwIfTerminated();
-
-      AbstractLongSpliterator sortedSpliterator =
-          new Spliterators.AbstractLongSpliterator(
-              spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
-            Spliterator.OfLong ordered = null;
-
-            @Override
-            public Comparator<? super Long> getComparator() {
-              return null;
-            }
-
-            @Override
-            public boolean tryAdvance(LongConsumer action) {
-              if (ordered == null) {
-                long[] list = new long[0];
-                spliterator.forEachRemaining((long item) -> list[list.length] = item);
-                Arrays.sort(list);
-                ordered = Spliterators.spliterator(list, characteristics());
-              }
-              return ordered.tryAdvance(action);
-            }
-          };
-
-      return new LongStreamSource(this, sortedSpliterator);
-    }
-
-    @Override
-    public LongStream peek(LongConsumer action) {
-      checkNotNull(action);
-      throwIfTerminated();
-
-      AbstractLongSpliterator peekSpliterator =
-          new Spliterators.AbstractLongSpliterator(
-              spliterator.estimateSize(), spliterator.characteristics()) {
-            @Override
-            public boolean tryAdvance(final LongConsumer innerAction) {
-              return spliterator.tryAdvance(action.andThen(innerAction));
-            }
-          };
-
-      return new LongStreamSource(this, peekSpliterator);
-    }
-
-    @Override
-    public LongStream limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return new LongStreamSource(this, new LimitSpliterator(maxSize, spliterator));
-    }
-
-    @Override
-    public LongStream skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      if (n == 0) {
-        return this;
-      }
-      return new LongStreamSource(this, new SkipSpliterator(n, spliterator));
-    }
-
-    @Override
-    public DoubleStream asDoubleStream() {
-      return mapToDouble(x -> (double) x);
-    }
-
-    @Override
-    public Stream<Long> boxed() {
-      return mapToObj(Long::valueOf);
-    }
-
-    @Override
-    public LongStream sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public LongStream parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public LongStream unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/stream/LongStreamImpl.java b/user/super/com/google/gwt/emul/java/util/stream/LongStreamImpl.java
new file mode 100644
index 0000000..ee9a379
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/stream/LongStreamImpl.java
@@ -0,0 +1,819 @@
+/*
+ * 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.stream;
+
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+import static javaemul.internal.InternalPreconditions.checkState;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LongSummaryStatistics;
+import java.util.OptionalDouble;
+import java.util.OptionalLong;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.Spliterators.AbstractLongSpliterator;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.LongFunction;
+import java.util.function.LongPredicate;
+import java.util.function.LongToDoubleFunction;
+import java.util.function.LongToIntFunction;
+import java.util.function.LongUnaryOperator;
+import java.util.function.ObjLongConsumer;
+import java.util.function.Supplier;
+
+/**
+ * Main implementation of LongStream, wrapping a single spliterator, and an optional parent stream.
+ */
+final class LongStreamImpl extends TerminatableStream<LongStreamImpl> implements LongStream {
+
+  /**
+   * Represents an empty stream, doing nothing for all methods.
+   */
+  static class Empty extends TerminatableStream<Empty> implements LongStream {
+    public Empty(TerminatableStream<?> previous) {
+      super(previous);
+    }
+
+    @Override
+    public LongStream filter(LongPredicate predicate) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public LongStream map(LongUnaryOperator mapper) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
+      throwIfTerminated();
+      return new StreamImpl.Empty<U>(this);
+    }
+
+    @Override
+    public IntStream mapToInt(LongToIntFunction mapper) {
+      throwIfTerminated();
+      return new IntStreamImpl.Empty(this);
+    }
+
+    @Override
+    public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
+      throwIfTerminated();
+      return new DoubleStreamImpl.Empty(this);
+    }
+
+    @Override
+    public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public LongStream distinct() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public LongStream sorted() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public LongStream peek(LongConsumer action) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public LongStream limit(long maxSize) {
+      throwIfTerminated();
+      checkState(maxSize >= 0, "maxSize may not be negative");
+      return this;
+    }
+
+    @Override
+    public LongStream skip(long n) {
+      throwIfTerminated();
+      checkState(n >= 0, "n may not be negative");
+      return this;
+    }
+
+    @Override
+    public void forEach(LongConsumer action) {
+      terminate();
+    }
+
+    @Override
+    public void forEachOrdered(LongConsumer action) {
+      terminate();
+    }
+
+    @Override
+    public long[] toArray() {
+      terminate();
+      return new long[0];
+    }
+
+    @Override
+    public long reduce(long identity, LongBinaryOperator op) {
+      terminate();
+      return identity;
+    }
+
+    @Override
+    public OptionalLong reduce(LongBinaryOperator op) {
+      terminate();
+      return OptionalLong.empty();
+    }
+
+    @Override
+    public <R> R collect(
+        Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+      terminate();
+      return supplier.get();
+    }
+
+    @Override
+    public long sum() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public OptionalLong min() {
+      terminate();
+      return OptionalLong.empty();
+    }
+
+    @Override
+    public OptionalLong max() {
+      terminate();
+      return OptionalLong.empty();
+    }
+
+    @Override
+    public long count() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public OptionalDouble average() {
+      terminate();
+      return OptionalDouble.empty();
+    }
+
+    @Override
+    public LongSummaryStatistics summaryStatistics() {
+      terminate();
+      return new LongSummaryStatistics();
+    }
+
+    @Override
+    public boolean anyMatch(LongPredicate predicate) {
+      terminate();
+      return false;
+    }
+
+    @Override
+    public boolean allMatch(LongPredicate predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public boolean noneMatch(LongPredicate predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public OptionalLong findFirst() {
+      terminate();
+      return OptionalLong.empty();
+    }
+
+    @Override
+    public OptionalLong findAny() {
+      terminate();
+      return OptionalLong.empty();
+    }
+
+    @Override
+    public DoubleStream asDoubleStream() {
+      throwIfTerminated();
+      return new DoubleStreamImpl.Empty(this);
+    }
+
+    @Override
+    public Stream<Long> boxed() {
+      throwIfTerminated();
+      return new StreamImpl.Empty<Long>(this);
+    }
+
+    @Override
+    public LongStream sequential() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public LongStream parallel() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public PrimitiveIterator.OfLong iterator() {
+      return Spliterators.iterator(spliterator());
+    }
+
+    @Override
+    public Spliterator.OfLong spliterator() {
+      terminate();
+      return Spliterators.emptyLongSpliterator();
+    }
+
+    @Override
+    public boolean isParallel() {
+      throwIfTerminated();
+      return false;
+    }
+
+    @Override
+    public LongStream unordered() {
+      throwIfTerminated();
+      return this;
+    }
+  }
+
+  /**
+   * Long to Int map spliterator.
+   */
+  private static final class MapToIntSpliterator extends Spliterators.AbstractIntSpliterator {
+    private final LongToIntFunction map;
+    private final Spliterator.OfLong original;
+
+    public MapToIntSpliterator(LongToIntFunction map, Spliterator.OfLong original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final IntConsumer action) {
+      return original.tryAdvance((long u) -> action.accept(map.applyAsInt(u)));
+    }
+  }
+
+  /**
+   * Long to Object map spliterator.
+   *
+   * @param <T> the type of data in the object spliterator
+   */
+  private static final class MapToObjSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
+    private final LongFunction<? extends T> map;
+    private final Spliterator.OfLong original;
+
+    public MapToObjSpliterator(LongFunction<? extends T> map, Spliterator.OfLong original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final Consumer<? super T> action) {
+      return original.tryAdvance((long u) -> action.accept(map.apply(u)));
+    }
+  }
+
+  /**
+   * Long to Long map spliterator.
+   */
+  private static final class MapToLongSpliterator extends Spliterators.AbstractLongSpliterator {
+    private final LongUnaryOperator map;
+    private final Spliterator.OfLong original;
+
+    public MapToLongSpliterator(LongUnaryOperator map, Spliterator.OfLong original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final LongConsumer action) {
+      return original.tryAdvance((long u) -> action.accept(map.applyAsLong(u)));
+    }
+  }
+
+  /**
+   * Long to Double map Spliterator.
+   */
+  private static final class MapToDoubleSpliterator extends Spliterators.AbstractDoubleSpliterator {
+    private final LongToDoubleFunction map;
+    private final Spliterator.OfLong original;
+
+    public MapToDoubleSpliterator(LongToDoubleFunction map, Spliterator.OfLong original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final DoubleConsumer action) {
+      return original.tryAdvance((long u) -> action.accept(map.applyAsDouble(u)));
+    }
+  }
+
+  /**
+   * Long filter spliterator.
+   */
+  private static final class FilterSpliterator extends Spliterators.AbstractLongSpliterator {
+    private final LongPredicate filter;
+    private final Spliterator.OfLong original;
+
+    private boolean found;
+
+    public FilterSpliterator(LongPredicate filter, Spliterator.OfLong original) {
+      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
+      checkNotNull(filter);
+      this.filter = filter;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Long> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(final LongConsumer action) {
+      found = false;
+      while (!found
+          && original.tryAdvance(
+              (long item) -> {
+                if (filter.test(item)) {
+                  found = true;
+                  action.accept(item);
+                }
+              })) {
+        // do nothing, work is done in tryAdvance
+      }
+
+      return found;
+    }
+  }
+
+  /**
+   * Long skip spliterator.
+   */
+  private static final class SkipSpliterator extends Spliterators.AbstractLongSpliterator {
+    private long skip;
+    private final Spliterator.OfLong original;
+
+    public SkipSpliterator(long skip, Spliterator.OfLong original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.max(0, original.estimateSize() - skip)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.skip = skip;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Long> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(LongConsumer action) {
+      while (skip > 0) {
+        if (!original.tryAdvance((long ignore) -> { })) {
+          return false;
+        }
+        skip--;
+      }
+      return original.tryAdvance(action);
+    }
+  }
+
+  /**
+   * Long limit spliterator.
+   */
+  private static final class LimitSpliterator extends Spliterators.AbstractLongSpliterator {
+    private final long limit;
+    private final Spliterator.OfLong original;
+    private int position = 0;
+
+    public LimitSpliterator(long limit, Spliterator.OfLong original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.min(original.estimateSize(), limit)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.limit = limit;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super Long> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(LongConsumer action) {
+      if (position >= limit) {
+        return false;
+      }
+      boolean result = original.tryAdvance(action);
+      position++;
+      return result;
+    }
+  }
+
+  /**
+   * Value holder for various stream operations.
+   */
+  private static final class ValueConsumer implements LongConsumer {
+    long value;
+
+    @Override
+    public void accept(long value) {
+      this.value = value;
+    }
+  }
+
+  private final Spliterator.OfLong spliterator;
+
+  public LongStreamImpl(TerminatableStream<?> previous, Spliterator.OfLong spliterator) {
+    super(previous);
+    this.spliterator = spliterator;
+  }
+
+  // terminals
+
+  @Override
+  public void forEach(LongConsumer action) {
+    forEachOrdered(action);
+  }
+
+  @Override
+  public void forEachOrdered(LongConsumer action) {
+    terminate();
+    spliterator.forEachRemaining(action);
+  }
+
+  @Override
+  public long[] toArray() {
+    terminate();
+    long[] entries = new long[0];
+    // this is legal in js, since the array will be backed by a JS array
+    spliterator.forEachRemaining((long value) -> entries[entries.length] = value);
+
+    return entries;
+  }
+
+  @Override
+  public long reduce(long identity, LongBinaryOperator op) {
+    terminate();
+    ValueConsumer holder = new ValueConsumer();
+    holder.value = identity;
+    spliterator.forEachRemaining(
+        (long value) -> {
+          holder.accept(op.applyAsLong(holder.value, value));
+        });
+    return holder.value;
+  }
+
+  @Override
+  public OptionalLong reduce(LongBinaryOperator op) {
+    ValueConsumer holder = new ValueConsumer();
+    if (spliterator.tryAdvance(holder)) {
+      return OptionalLong.of(reduce(holder.value, op));
+    }
+    terminate();
+    return OptionalLong.empty();
+  }
+
+  @Override
+  public <R> R collect(
+      Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+    terminate();
+    final R acc = supplier.get();
+    spliterator.forEachRemaining((long value) -> accumulator.accept(acc, value));
+    return acc;
+  }
+
+  @Override
+  public long sum() {
+    return summaryStatistics().getSum();
+  }
+
+  @Override
+  public OptionalLong min() {
+    LongSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalLong.empty();
+    }
+    return OptionalLong.of(stats.getMin());
+  }
+
+  @Override
+  public OptionalLong max() {
+    LongSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalLong.empty();
+    }
+    return OptionalLong.of(stats.getMax());
+  }
+
+  @Override
+  public long count() {
+    terminate();
+    long count = 0;
+    while (spliterator.tryAdvance((long value) -> { })) {
+      count++;
+    }
+    return count;
+  }
+
+  @Override
+  public OptionalDouble average() {
+    LongSummaryStatistics stats = summaryStatistics();
+    if (stats.getCount() == 0) {
+      return OptionalDouble.empty();
+    }
+    return OptionalDouble.of(stats.getAverage());
+  }
+
+  @Override
+  public LongSummaryStatistics summaryStatistics() {
+    return collect(
+        LongSummaryStatistics::new,
+        // TODO switch to a lambda reference once #9340 is fixed
+        (longSummaryStatistics, value) -> longSummaryStatistics.accept(value),
+        LongSummaryStatistics::combine);
+  }
+
+  @Override
+  public boolean anyMatch(LongPredicate predicate) {
+    return filter(predicate).findFirst().isPresent();
+  }
+
+  @Override
+  public boolean allMatch(LongPredicate predicate) {
+    return !anyMatch(predicate.negate());
+  }
+
+  @Override
+  public boolean noneMatch(LongPredicate predicate) {
+    return !anyMatch(predicate);
+  }
+
+  @Override
+  public OptionalLong findFirst() {
+    terminate();
+    ValueConsumer holder = new ValueConsumer();
+    if (spliterator.tryAdvance(holder)) {
+      return OptionalLong.of(holder.value);
+    }
+    return OptionalLong.empty();
+  }
+
+  @Override
+  public OptionalLong findAny() {
+    return findFirst();
+  }
+
+  @Override
+  public PrimitiveIterator.OfLong iterator() {
+    return Spliterators.iterator(spliterator());
+  }
+
+  @Override
+  public Spliterator.OfLong spliterator() {
+    terminate();
+    return spliterator;
+  }
+  // end terminals
+
+  // intermediates
+  @Override
+  public LongStream filter(LongPredicate predicate) {
+    throwIfTerminated();
+    return new LongStreamImpl(this, new FilterSpliterator(predicate, spliterator));
+  }
+
+  @Override
+  public LongStream map(LongUnaryOperator mapper) {
+    throwIfTerminated();
+    return new LongStreamImpl(this, new MapToLongSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
+    throwIfTerminated();
+    return new StreamImpl<U>(this, new MapToObjSpliterator<U>(mapper, spliterator));
+  }
+
+  @Override
+  public IntStream mapToInt(LongToIntFunction mapper) {
+    throwIfTerminated();
+    return new IntStreamImpl(this, new MapToIntSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
+    throwIfTerminated();
+    return new DoubleStreamImpl(this, new MapToDoubleSpliterator(mapper, spliterator));
+  }
+
+  @Override
+  public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends LongStream> spliteratorOfStreams =
+        new MapToObjSpliterator<>(mapper, spliterator);
+
+    AbstractLongSpliterator flatMapSpliterator =
+        new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE, 0) {
+          LongStream nextStream;
+          Spliterator.OfLong next;
+
+          @Override
+          public boolean tryAdvance(LongConsumer action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new LongStreamImpl(this, flatMapSpliterator);
+  }
+
+  @Override
+  public LongStream distinct() {
+    throwIfTerminated();
+    HashSet<Long> seen = new HashSet<>();
+    return filter(seen::add);
+  }
+
+  @Override
+  public LongStream sorted() {
+    throwIfTerminated();
+
+    AbstractLongSpliterator sortedSpliterator =
+        new Spliterators.AbstractLongSpliterator(
+            spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
+          Spliterator.OfLong ordered = null;
+
+          @Override
+          public Comparator<? super Long> getComparator() {
+            return null;
+          }
+
+          @Override
+          public boolean tryAdvance(LongConsumer action) {
+            if (ordered == null) {
+              long[] list = new long[0];
+              spliterator.forEachRemaining((long item) -> list[list.length] = item);
+              Arrays.sort(list);
+              ordered = Spliterators.spliterator(list, characteristics());
+            }
+            return ordered.tryAdvance(action);
+          }
+        };
+
+    return new LongStreamImpl(this, sortedSpliterator);
+  }
+
+  @Override
+  public LongStream peek(LongConsumer action) {
+    checkNotNull(action);
+    throwIfTerminated();
+
+    AbstractLongSpliterator peekSpliterator =
+        new Spliterators.AbstractLongSpliterator(
+            spliterator.estimateSize(), spliterator.characteristics()) {
+          @Override
+          public boolean tryAdvance(final LongConsumer innerAction) {
+            return spliterator.tryAdvance(action.andThen(innerAction));
+          }
+        };
+
+    return new LongStreamImpl(this, peekSpliterator);
+  }
+
+  @Override
+  public LongStream limit(long maxSize) {
+    throwIfTerminated();
+    checkState(maxSize >= 0, "maxSize may not be negative");
+    return new LongStreamImpl(this, new LimitSpliterator(maxSize, spliterator));
+  }
+
+  @Override
+  public LongStream skip(long n) {
+    throwIfTerminated();
+    checkState(n >= 0, "n may not be negative");
+    if (n == 0) {
+      return this;
+    }
+    return new LongStreamImpl(this, new SkipSpliterator(n, spliterator));
+  }
+
+  @Override
+  public DoubleStream asDoubleStream() {
+    return mapToDouble(x -> (double) x);
+  }
+
+  @Override
+  public Stream<Long> boxed() {
+    return mapToObj(Long::valueOf);
+  }
+
+  @Override
+  public LongStream sequential() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public LongStream parallel() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public boolean isParallel() {
+    throwIfTerminated();
+    return false;
+  }
+
+  @Override
+  public LongStream unordered() {
+    throwIfTerminated();
+    return this;
+  }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/stream/Stream.java b/user/super/com/google/gwt/emul/java/util/stream/Stream.java
index a313f4a..a963279 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/Stream.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/Stream.java
@@ -13,35 +13,23 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package java.util.stream;
 
-import static javaemul.internal.InternalPreconditions.checkNotNull;
 import static javaemul.internal.InternalPreconditions.checkState;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Optional;
 import java.util.Spliterator;
 import java.util.Spliterators;
-import java.util.Spliterators.AbstractDoubleSpliterator;
-import java.util.Spliterators.AbstractIntSpliterator;
-import java.util.Spliterators.AbstractLongSpliterator;
 import java.util.Spliterators.AbstractSpliterator;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.BinaryOperator;
 import java.util.function.Consumer;
-import java.util.function.DoubleConsumer;
 import java.util.function.Function;
-import java.util.function.IntConsumer;
 import java.util.function.IntFunction;
-import java.util.function.LongConsumer;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.function.ToDoubleFunction;
@@ -56,16 +44,21 @@
  * @param <T> the type of data being streamed
  */
 public interface Stream<T> extends BaseStream<T, Stream<T>> {
-  /**
-   * Value holder for various stream operations.
-   */
-  static final class ValueConsumer<T> implements Consumer<T> {
-    T value;
 
+  /**
+   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.Builder.html">
+   * the official Java API doc</a> for details.
+   */
+  interface Builder<T> extends Consumer<T> {
     @Override
-    public void accept(T value) {
-      this.value = value;
+    void accept(T t);
+
+    default Stream.Builder<T> add(T t) {
+      accept(t);
+      return this;
     }
+
+    Stream<T> build();
   }
 
   static <T> Stream.Builder<T> builder() {
@@ -134,7 +127,7 @@
           }
         };
 
-    Stream<T> result = new StreamSource<T>(null, spliterator);
+    Stream<T> result = new StreamImpl<T>(null, spliterator);
 
     result.onClose(a::close);
     result.onClose(b::close);
@@ -143,7 +136,7 @@
   }
 
   static <T> Stream<T> empty() {
-    return new EmptyStreamSource<T>(null);
+    return new StreamImpl.Empty<T>(null);
   }
 
   static <T> Stream<T> generate(Supplier<T> s) {
@@ -185,22 +178,6 @@
     return Arrays.stream(values);
   }
 
-  /**
-   * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.Builder.html">
-   * the official Java API doc</a> for details.
-   */
-  public interface Builder<T> extends Consumer<T> {
-    @Override
-    void accept(T t);
-
-    default Stream.Builder<T> add(T t) {
-      accept(t);
-      return this;
-    }
-
-    Stream<T> build();
-  }
-
   boolean allMatch(Predicate<? super T> predicate);
 
   boolean anyMatch(Predicate<? super T> predicate);
@@ -265,930 +242,4 @@
   Object[] toArray();
 
   <A> A[] toArray(IntFunction<A[]> generator);
-
-  /**
-   * Represents an empty stream, doing nothing for all methods.
-   */
-  static class EmptyStreamSource<T> extends TerminatableStream<EmptyStreamSource<T>>
-      implements Stream<T> {
-
-    public EmptyStreamSource(TerminatableStream<?> previous) {
-      super(previous);
-    }
-
-    @Override
-    public Stream<T> filter(Predicate<? super T> predicate) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
-      throwIfTerminated();
-      return (Stream) this;
-    }
-
-    @Override
-    public IntStream mapToInt(ToIntFunction<? super T> mapper) {
-      throwIfTerminated();
-      return new IntStream.EmptyIntStreamSource(this);
-    }
-
-    @Override
-    public LongStream mapToLong(ToLongFunction<? super T> mapper) {
-      throwIfTerminated();
-      return new LongStream.EmptyLongStreamSource(this);
-    }
-
-    @Override
-    public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
-      throwIfTerminated();
-      return new DoubleStream.EmptyDoubleStreamSource(this);
-    }
-
-    @Override
-    public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
-      throwIfTerminated();
-      return (Stream) this;
-    }
-
-    @Override
-    public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
-      throwIfTerminated();
-      return new IntStream.EmptyIntStreamSource(this);
-    }
-
-    @Override
-    public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
-      throwIfTerminated();
-      return new LongStream.EmptyLongStreamSource(this);
-    }
-
-    @Override
-    public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
-      throwIfTerminated();
-      return new DoubleStream.EmptyDoubleStreamSource(this);
-    }
-
-    @Override
-    public Stream<T> distinct() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> sorted() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> sorted(Comparator<? super T> comparator) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> peek(Consumer<? super T> action) {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return this;
-    }
-
-    @Override
-    public Stream<T> skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      return this;
-    }
-
-    @Override
-    public void forEach(Consumer<? super T> action) {
-      terminate();
-      // nothing to do
-    }
-
-    @Override
-    public void forEachOrdered(Consumer<? super T> action) {
-      terminate();
-      // nothing to do
-    }
-
-    @Override
-    public Object[] toArray() {
-      terminate();
-      return new Object[0];
-    }
-
-    @Override
-    public <A> A[] toArray(IntFunction<A[]> generator) {
-      terminate();
-      return generator.apply(0);
-    }
-
-    @Override
-    public T reduce(T identity, BinaryOperator<T> accumulator) {
-      terminate();
-      return identity;
-    }
-
-    @Override
-    public Optional<T> reduce(BinaryOperator<T> accumulator) {
-      terminate();
-      return Optional.empty();
-    }
-
-    @Override
-    public <U> U reduce(
-        U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
-      terminate();
-      return identity;
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
-      terminate();
-      return supplier.get();
-    }
-
-    @Override
-    public <R, A> R collect(Collector<? super T, A, R> collector) {
-      terminate();
-      return collector.finisher().apply(collector.supplier().get());
-    }
-
-    @Override
-    public Optional<T> min(Comparator<? super T> comparator) {
-      terminate();
-      return Optional.empty();
-    }
-
-    @Override
-    public Optional<T> max(Comparator<? super T> comparator) {
-      terminate();
-      return Optional.empty();
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      return 0;
-    }
-
-    @Override
-    public boolean anyMatch(Predicate<? super T> predicate) {
-      terminate();
-      return false;
-    }
-
-    @Override
-    public boolean allMatch(Predicate<? super T> predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public boolean noneMatch(Predicate<? super T> predicate) {
-      terminate();
-      return true;
-    }
-
-    @Override
-    public Optional<T> findFirst() {
-      terminate();
-      return Optional.empty();
-    }
-
-    @Override
-    public Optional<T> findAny() {
-      terminate();
-      return Optional.empty();
-    }
-
-    @Override
-    public Iterator<T> iterator() {
-      terminate();
-      return Collections.emptyIterator();
-    }
-
-    @Override
-    public Spliterator<T> spliterator() {
-      terminate();
-      return Spliterators.emptySpliterator();
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public Stream<T> sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> parallel() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
-
-  /**
-   * Object to Object map spliterator.
-   * @param <U> the input type
-   * @param <T> the output type
-   */
-  static final class MapToObjSpliterator<U, T> extends Spliterators.AbstractSpliterator<T> {
-    private final Function<? super U, ? extends T> map;
-    private final Spliterator<U> original;
-
-    public MapToObjSpliterator(Function<? super U, ? extends T> map, Spliterator<U> original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final Consumer<? super T> action) {
-      return original.tryAdvance(u -> action.accept(map.apply(u)));
-    }
-  }
-
-  /**
-   * Object to Int map spliterator.
-   * @param <T> the input type
-   */
-  static final class MapToIntSpliterator<T> extends Spliterators.AbstractIntSpliterator {
-    private final ToIntFunction<? super T> map;
-    private final Spliterator<T> original;
-
-    public MapToIntSpliterator(ToIntFunction<? super T> map, Spliterator<T> original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final IntConsumer action) {
-      return original.tryAdvance(u -> action.accept(map.applyAsInt(u)));
-    }
-  }
-
-  /**
-   * Object to Long map spliterator.
-   * @param <T> the input type
-   */
-  static final class MapToLongSpliterator<T> extends Spliterators.AbstractLongSpliterator {
-    private final ToLongFunction<? super T> map;
-    private final Spliterator<T> original;
-
-    public MapToLongSpliterator(ToLongFunction<? super T> map, Spliterator<T> original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final LongConsumer action) {
-      return original.tryAdvance(u -> action.accept(map.applyAsLong(u)));
-    }
-  }
-
-  /**
-   * Object to Double map spliterator.
-   * @param <T> the input type
-   */
-  static final class MapToDoubleSpliterator<T> extends Spliterators.AbstractDoubleSpliterator {
-    private final ToDoubleFunction<? super T> map;
-    private final Spliterator<T> original;
-
-    public MapToDoubleSpliterator(ToDoubleFunction<? super T> map, Spliterator<T> original) {
-      super(
-          original.estimateSize(),
-          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
-      checkNotNull(map);
-      this.map = map;
-      this.original = original;
-    }
-
-    @Override
-    public boolean tryAdvance(final DoubleConsumer action) {
-      return original.tryAdvance(u -> action.accept(map.applyAsDouble(u)));
-    }
-  }
-
-  /**
-   * Object filter spliterator.
-   * @param <T> the type of data to iterate over
-   */
-  static final class FilterSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
-    private final Predicate<? super T> filter;
-    private final Spliterator<T> original;
-
-    private boolean found;
-
-    public FilterSpliterator(Predicate<? super T> filter, Spliterator<T> original) {
-      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
-      checkNotNull(filter);
-      this.filter = filter;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super T> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(final Consumer<? super T> action) {
-      found = false;
-      while (!found
-          && original.tryAdvance(
-              item -> {
-                if (filter.test(item)) {
-                  found = true;
-                  action.accept(item);
-                }
-              })) {
-        // do nothing, work is done in tryAdvance
-      }
-
-      return found;
-    }
-  }
-
-  /**
-   * Object skip spliterator.
-   * @param <T> the type of data to iterate over
-   */
-  static final class SkipSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
-    private long skip;
-    private final Spliterator<T> original;
-
-    public SkipSpliterator(long skip, Spliterator<T> original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.max(0, original.estimateSize() - skip)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.skip = skip;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super T> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(Consumer<? super T> action) {
-      while (skip > 0) {
-        if (!original.tryAdvance(ignore -> { })) {
-          return false;
-        }
-        skip--;
-      }
-      return original.tryAdvance(action);
-    }
-  }
-
-  /**
-   * Object limit spliterator.
-   * @param <T> the type of data to iterate over
-   */
-  static final class LimitSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
-    private final long limit;
-    private final Spliterator<T> original;
-    private int position = 0;
-
-    public LimitSpliterator(long limit, Spliterator<T> original) {
-      super(
-          original.hasCharacteristics(Spliterator.SIZED)
-              ? Math.min(original.estimateSize(), limit)
-              : Long.MAX_VALUE,
-          original.characteristics());
-      this.limit = limit;
-      this.original = original;
-    }
-
-    @Override
-    public Comparator<? super T> getComparator() {
-      return original.getComparator();
-    }
-
-    @Override
-    public boolean tryAdvance(Consumer<? super T> action) {
-      if (position >= limit) {
-        return false;
-      }
-      boolean result = original.tryAdvance(action);
-      position++;
-      return result;
-    }
-  }
-
-  /**
-   * Main implementation of Stream, wrapping a single spliterator and an optional parent stream.
-   * @param <T>
-   */
-  static class StreamSource<T> extends TerminatableStream<StreamSource<T>> implements Stream<T> {
-    private final Spliterator<T> spliterator;
-
-    public StreamSource(TerminatableStream<?> prev, Spliterator<T> spliterator) {
-      super(prev);
-      this.spliterator = spliterator;
-    }
-
-    // terminal
-    @Override
-    public Spliterator<T> spliterator() {
-      terminate();
-      return spliterator;
-    }
-
-    @Override
-    public Iterator<T> iterator() {
-      return Spliterators.iterator(spliterator());
-    }
-
-    @Override
-    public long count() {
-      terminate();
-      long count = 0;
-      while (spliterator.tryAdvance(a -> { })) {
-        count++;
-      }
-      return count;
-    }
-
-    @Override
-    public void forEach(Consumer<? super T> action) {
-      forEachOrdered(action);
-    }
-
-    @Override
-    public void forEachOrdered(Consumer<? super T> action) {
-      terminate();
-      spliterator.forEachRemaining(action);
-    }
-
-    @Override
-    public Object[] toArray() {
-      return toArray(Object[]::new);
-    }
-
-    @Override
-    public <A> A[] toArray(IntFunction<A[]> generator) {
-      List<T> collected = collect(Collectors.toList());
-      return collected.toArray(generator.apply(collected.size()));
-    }
-
-    @Override
-    public <R> R collect(
-        Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
-      return collect(
-          Collector.of(
-              supplier,
-              accumulator,
-              (a, b) -> {
-                combiner.accept(a, b);
-                return a;
-              }));
-    }
-
-    @Override
-    public <R, A> R collect(final Collector<? super T, A, R> collector) {
-      return collector
-          .finisher()
-          .apply(
-              reduce(
-                  collector.supplier().get(),
-                  (a, t) -> {
-                    collector.accumulator().accept(a, t);
-                    return a;
-                  },
-                  collector.combiner()));
-    }
-
-    @Override
-    public Optional<T> findFirst() {
-      terminate();
-      ValueConsumer<T> holder = new ValueConsumer<T>();
-      if (spliterator.tryAdvance(holder)) {
-        return Optional.of(holder.value);
-      }
-      return Optional.empty();
-    }
-
-    @Override
-    public Optional<T> findAny() {
-      return findFirst();
-    }
-
-    @Override
-    public boolean anyMatch(Predicate<? super T> predicate) {
-      return filter(predicate).findFirst().isPresent();
-    }
-
-    @Override
-    public boolean allMatch(final Predicate<? super T> predicate) {
-      return !anyMatch(predicate.negate());
-    }
-
-    @Override
-    public boolean noneMatch(final Predicate<? super T> predicate) {
-      return !anyMatch(predicate);
-    }
-
-    @Override
-    public Optional<T> min(final Comparator<? super T> comparator) {
-      return reduce(BinaryOperator.minBy(comparator));
-    }
-
-    @Override
-    public Optional<T> max(final Comparator<? super T> comparator) {
-      return reduce(BinaryOperator.maxBy(comparator));
-    }
-
-    @Override
-    public T reduce(T identity, BinaryOperator<T> accumulator) {
-      return reduce(identity, accumulator, accumulator);
-    }
-
-    @Override
-    public Optional<T> reduce(BinaryOperator<T> accumulator) {
-      ValueConsumer<T> consumer = new ValueConsumer<T>();
-      if (!spliterator.tryAdvance(consumer)) {
-        terminate();
-        return Optional.empty();
-      }
-      return Optional.of(reduce(consumer.value, accumulator));
-    }
-
-    // combiner is ignored, since we don't parallelize
-    @Override
-    public <U> U reduce(
-        U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
-      terminate();
-      final ValueConsumer<U> consumer = new ValueConsumer<U>();
-      consumer.value = identity;
-      spliterator.forEachRemaining(
-          item -> {
-            consumer.accept(accumulator.apply(consumer.value, item));
-          });
-      return consumer.value;
-    }
-    // end terminal
-
-    // intermediate
-    @Override
-    public Stream<T> filter(Predicate<? super T> predicate) {
-      throwIfTerminated();
-      return new StreamSource<>(this, new FilterSpliterator<>(predicate, spliterator));
-    }
-
-    @Override
-    public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
-      throwIfTerminated();
-      return new StreamSource<>(this, new MapToObjSpliterator<>(mapper, spliterator));
-    }
-
-    @Override
-    public IntStream mapToInt(ToIntFunction<? super T> mapper) {
-      throwIfTerminated();
-      return new IntStream.IntStreamSource(this, new MapToIntSpliterator<>(mapper, spliterator));
-    }
-
-    @Override
-    public LongStream mapToLong(ToLongFunction<? super T> mapper) {
-      throwIfTerminated();
-      return new LongStream.LongStreamSource(this, new MapToLongSpliterator<>(mapper, spliterator));
-    }
-
-    @Override
-    public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
-      throwIfTerminated();
-      return new DoubleStream.DoubleStreamSource(
-          this, new MapToDoubleSpliterator<>(mapper, spliterator));
-    }
-
-    @Override
-    public <R> Stream<R> flatMap(final Function<? super T, ? extends Stream<? extends R>> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends Stream<? extends R>> spliteratorOfStreams =
-          new MapToObjSpliterator<>(mapper, spliterator);
-
-      AbstractSpliterator<R> flatMapSpliterator =
-          new Spliterators.AbstractSpliterator<R>(Long.MAX_VALUE, 0) {
-            Stream<? extends R> nextStream;
-            Spliterator<? extends R> next;
-
-            @Override
-            public boolean tryAdvance(Consumer<? super R> action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new StreamSource<R>(this, flatMapSpliterator);
-    }
-
-    @Override
-    public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends IntStream> spliteratorOfStreams =
-          new MapToObjSpliterator<>(mapper, spliterator);
-
-      AbstractIntSpliterator flatMapSpliterator =
-          new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE, 0) {
-            IntStream nextStream;
-            Spliterator.OfInt next;
-
-            @Override
-            public boolean tryAdvance(IntConsumer action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new IntStream.IntStreamSource(this, flatMapSpliterator);
-    }
-
-    @Override
-    public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends LongStream> spliteratorOfStreams =
-          new MapToObjSpliterator<>(mapper, spliterator);
-
-      AbstractLongSpliterator flatMapSpliterator =
-          new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE, 0) {
-            LongStream nextStream;
-            Spliterator.OfLong next;
-
-            @Override
-            public boolean tryAdvance(LongConsumer action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new LongStream.LongStreamSource(this, flatMapSpliterator);
-    }
-
-    @Override
-    public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
-      throwIfTerminated();
-      final Spliterator<? extends DoubleStream> spliteratorOfStreams =
-          new MapToObjSpliterator<>(mapper, spliterator);
-
-      AbstractDoubleSpliterator flatMapSpliterator =
-          new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE, 0) {
-            DoubleStream nextStream;
-            Spliterator.OfDouble next;
-
-            @Override
-            public boolean tryAdvance(DoubleConsumer action) {
-              // look for a new spliterator
-              while (advanceToNextSpliterator()) {
-                // if we have one, try to read and use it
-                if (next.tryAdvance(action)) {
-                  return true;
-                } else {
-                  nextStream.close();
-                  nextStream = null;
-                  // failed, null it out so we can find another
-                  next = null;
-                }
-              }
-              return false;
-            }
-
-            private boolean advanceToNextSpliterator() {
-              while (next == null) {
-                if (!spliteratorOfStreams.tryAdvance(
-                    n -> {
-                      if (n != null) {
-                        nextStream = n;
-                        next = n.spliterator();
-                      }
-                    })) {
-                  return false;
-                }
-              }
-              return true;
-            }
-          };
-
-      return new DoubleStream.DoubleStreamSource(this, flatMapSpliterator);
-    }
-
-    @Override
-    public Stream<T> distinct() {
-      throwIfTerminated();
-      HashSet<T> seen = new HashSet<>();
-      return filter(seen::add);
-    }
-
-    @Override
-    public Stream<T> sorted() {
-      throwIfTerminated();
-      Comparator<T> c = (Comparator) Comparator.naturalOrder();
-      return sorted(c);
-    }
-
-    @Override
-    public Stream<T> sorted(final Comparator<? super T> comparator) {
-      throwIfTerminated();
-
-      AbstractSpliterator<T> sortedSpliterator =
-          new Spliterators.AbstractSpliterator<T>(
-              spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
-            Spliterator<T> ordered = null;
-
-            @Override
-            public Comparator<? super T> getComparator() {
-              return comparator == Comparator.naturalOrder() ? null : comparator;
-            }
-
-            @Override
-            public boolean tryAdvance(Consumer<? super T> action) {
-              if (ordered == null) {
-                List<T> list = new ArrayList<>();
-                spliterator.forEachRemaining(list::add);
-                Collections.sort(list, comparator);
-                ordered = list.spliterator();
-              }
-              return ordered.tryAdvance(action);
-            }
-          };
-
-      return new StreamSource<>(this, sortedSpliterator);
-    }
-
-    @Override
-    public Stream<T> peek(final Consumer<? super T> action) {
-      checkNotNull(action);
-      throwIfTerminated();
-
-      AbstractSpliterator<T> peekSpliterator =
-          new Spliterators.AbstractSpliterator<T>(
-              spliterator.estimateSize(), spliterator.characteristics()) {
-            @Override
-            public boolean tryAdvance(final Consumer<? super T> innerAction) {
-              return spliterator.tryAdvance(
-                  item -> {
-                    action.accept(item);
-                    innerAction.accept(item);
-                  });
-            }
-          };
-
-      return new StreamSource<>(this, peekSpliterator);
-    }
-
-    @Override
-    public Stream<T> limit(long maxSize) {
-      throwIfTerminated();
-      checkState(maxSize >= 0, "maxSize may not be negative");
-      return new StreamSource<>(this, new LimitSpliterator<>(maxSize, spliterator));
-    }
-
-    @Override
-    public Stream<T> skip(long n) {
-      throwIfTerminated();
-      checkState(n >= 0, "n may not be negative");
-      if (n == 0) {
-        return this;
-      }
-      return new StreamSource<>(this, new SkipSpliterator<>(n, spliterator));
-    }
-
-    @Override
-    public boolean isParallel() {
-      throwIfTerminated();
-      return false;
-    }
-
-    @Override
-    public Stream<T> sequential() {
-      throwIfTerminated();
-      return this;
-    }
-
-    @Override
-    public Stream<T> parallel() {
-      throwIfTerminated();
-      // do nothing, no such thing as gwt+parallel
-      return this;
-    }
-
-    @Override
-    public Stream<T> unordered() {
-      throwIfTerminated();
-      return this;
-    }
-  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/stream/StreamImpl.java b/user/super/com/google/gwt/emul/java/util/stream/StreamImpl.java
new file mode 100644
index 0000000..bb5bc94
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/stream/StreamImpl.java
@@ -0,0 +1,991 @@
+/*
+ * 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.stream;
+
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+import static javaemul.internal.InternalPreconditions.checkState;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.Spliterators.AbstractDoubleSpliterator;
+import java.util.Spliterators.AbstractIntSpliterator;
+import java.util.Spliterators.AbstractLongSpliterator;
+import java.util.Spliterators.AbstractSpliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.LongConsumer;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+/**
+ * Main implementation of Stream, wrapping a single spliterator and an optional parent stream.
+ */
+final class StreamImpl<T> extends TerminatableStream<StreamImpl<T>> implements Stream<T> {
+
+  /**
+   * Represents an empty stream, doing nothing for all methods.
+   */
+  static class Empty<T> extends TerminatableStream<Empty<T>> implements Stream<T> {
+
+    public Empty(TerminatableStream<?> previous) {
+      super(previous);
+    }
+
+    @Override
+    public Stream<T> filter(Predicate<? super T> predicate) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
+      throwIfTerminated();
+      return (Stream) this;
+    }
+
+    @Override
+    public IntStream mapToInt(ToIntFunction<? super T> mapper) {
+      throwIfTerminated();
+      return new IntStreamImpl.Empty(this);
+    }
+
+    @Override
+    public LongStream mapToLong(ToLongFunction<? super T> mapper) {
+      throwIfTerminated();
+      return new LongStreamImpl.Empty(this);
+    }
+
+    @Override
+    public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
+      throwIfTerminated();
+      return new DoubleStreamImpl.Empty(this);
+    }
+
+    @Override
+    public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
+      throwIfTerminated();
+      return (Stream) this;
+    }
+
+    @Override
+    public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
+      throwIfTerminated();
+      return new IntStreamImpl.Empty(this);
+    }
+
+    @Override
+    public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
+      throwIfTerminated();
+      return new LongStreamImpl.Empty(this);
+    }
+
+    @Override
+    public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
+      throwIfTerminated();
+      return new DoubleStreamImpl.Empty(this);
+    }
+
+    @Override
+    public Stream<T> distinct() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public Stream<T> sorted() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public Stream<T> sorted(Comparator<? super T> comparator) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public Stream<T> peek(Consumer<? super T> action) {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public Stream<T> limit(long maxSize) {
+      throwIfTerminated();
+      checkState(maxSize >= 0, "maxSize may not be negative");
+      return this;
+    }
+
+    @Override
+    public Stream<T> skip(long n) {
+      throwIfTerminated();
+      checkState(n >= 0, "n may not be negative");
+      return this;
+    }
+
+    @Override
+    public void forEach(Consumer<? super T> action) {
+      terminate();
+      // nothing to do
+    }
+
+    @Override
+    public void forEachOrdered(Consumer<? super T> action) {
+      terminate();
+      // nothing to do
+    }
+
+    @Override
+    public Object[] toArray() {
+      terminate();
+      return new Object[0];
+    }
+
+    @Override
+    public <A> A[] toArray(IntFunction<A[]> generator) {
+      terminate();
+      return generator.apply(0);
+    }
+
+    @Override
+    public T reduce(T identity, BinaryOperator<T> accumulator) {
+      terminate();
+      return identity;
+    }
+
+    @Override
+    public Optional<T> reduce(BinaryOperator<T> accumulator) {
+      terminate();
+      return Optional.empty();
+    }
+
+    @Override
+    public <U> U reduce(
+        U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
+      terminate();
+      return identity;
+    }
+
+    @Override
+    public <R> R collect(
+        Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
+      terminate();
+      return supplier.get();
+    }
+
+    @Override
+    public <R, A> R collect(Collector<? super T, A, R> collector) {
+      terminate();
+      return collector.finisher().apply(collector.supplier().get());
+    }
+
+    @Override
+    public Optional<T> min(Comparator<? super T> comparator) {
+      terminate();
+      return Optional.empty();
+    }
+
+    @Override
+    public Optional<T> max(Comparator<? super T> comparator) {
+      terminate();
+      return Optional.empty();
+    }
+
+    @Override
+    public long count() {
+      terminate();
+      return 0;
+    }
+
+    @Override
+    public boolean anyMatch(Predicate<? super T> predicate) {
+      terminate();
+      return false;
+    }
+
+    @Override
+    public boolean allMatch(Predicate<? super T> predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public boolean noneMatch(Predicate<? super T> predicate) {
+      terminate();
+      return true;
+    }
+
+    @Override
+    public Optional<T> findFirst() {
+      terminate();
+      return Optional.empty();
+    }
+
+    @Override
+    public Optional<T> findAny() {
+      terminate();
+      return Optional.empty();
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+      terminate();
+      return Collections.emptyIterator();
+    }
+
+    @Override
+    public Spliterator<T> spliterator() {
+      terminate();
+      return Spliterators.emptySpliterator();
+    }
+
+    @Override
+    public boolean isParallel() {
+      throwIfTerminated();
+      return false;
+    }
+
+    @Override
+    public Stream<T> sequential() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public Stream<T> parallel() {
+      throwIfTerminated();
+      return this;
+    }
+
+    @Override
+    public Stream<T> unordered() {
+      throwIfTerminated();
+      return this;
+    }
+  }
+
+  /**
+   * Object to Object map spliterator.
+   *
+   * @param <U> the input type
+   * @param <T> the output type
+   */
+  private static final class MapToObjSpliterator<U, T> extends Spliterators.AbstractSpliterator<T> {
+    private final Function<? super U, ? extends T> map;
+    private final Spliterator<U> original;
+
+    public MapToObjSpliterator(Function<? super U, ? extends T> map, Spliterator<U> original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final Consumer<? super T> action) {
+      return original.tryAdvance(u -> action.accept(map.apply(u)));
+    }
+  }
+
+  /**
+   * Object to Int map spliterator.
+   *
+   * @param <T> the input type
+   */
+  private static final class MapToIntSpliterator<T> extends Spliterators.AbstractIntSpliterator {
+    private final ToIntFunction<? super T> map;
+    private final Spliterator<T> original;
+
+    public MapToIntSpliterator(ToIntFunction<? super T> map, Spliterator<T> original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final IntConsumer action) {
+      return original.tryAdvance(u -> action.accept(map.applyAsInt(u)));
+    }
+  }
+
+  /**
+   * Object to Long map spliterator.
+   *
+   * @param <T> the input type
+   */
+  private static final class MapToLongSpliterator<T> extends Spliterators.AbstractLongSpliterator {
+    private final ToLongFunction<? super T> map;
+    private final Spliterator<T> original;
+
+    public MapToLongSpliterator(ToLongFunction<? super T> map, Spliterator<T> original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final LongConsumer action) {
+      return original.tryAdvance(u -> action.accept(map.applyAsLong(u)));
+    }
+  }
+
+  /**
+   * Object to Double map spliterator.
+   *
+   * @param <T> the input type
+   */
+  private static final class MapToDoubleSpliterator<T>
+      extends Spliterators.AbstractDoubleSpliterator {
+    private final ToDoubleFunction<? super T> map;
+    private final Spliterator<T> original;
+
+    public MapToDoubleSpliterator(ToDoubleFunction<? super T> map, Spliterator<T> original) {
+      super(
+          original.estimateSize(),
+          original.characteristics() & ~(Spliterator.SORTED | Spliterator.DISTINCT));
+      checkNotNull(map);
+      this.map = map;
+      this.original = original;
+    }
+
+    @Override
+    public boolean tryAdvance(final DoubleConsumer action) {
+      return original.tryAdvance(u -> action.accept(map.applyAsDouble(u)));
+    }
+  }
+
+  /**
+   * Object filter spliterator.
+   *
+   * @param <T> the type of data to iterate over
+   */
+  private static final class FilterSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
+    private final Predicate<? super T> filter;
+    private final Spliterator<T> original;
+
+    private boolean found;
+
+    public FilterSpliterator(Predicate<? super T> filter, Spliterator<T> original) {
+      super(original.estimateSize(), original.characteristics() & ~Spliterator.SIZED);
+      checkNotNull(filter);
+      this.filter = filter;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super T> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(final Consumer<? super T> action) {
+      found = false;
+      while (!found
+          && original.tryAdvance(
+              item -> {
+                if (filter.test(item)) {
+                  found = true;
+                  action.accept(item);
+                }
+              })) {
+        // do nothing, work is done in tryAdvance
+      }
+
+      return found;
+    }
+  }
+
+  /**
+   * Object skip spliterator.
+   *
+   * @param <T> the type of data to iterate over
+   */
+  private static final class SkipSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
+    private long skip;
+    private final Spliterator<T> original;
+
+    public SkipSpliterator(long skip, Spliterator<T> original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.max(0, original.estimateSize() - skip)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.skip = skip;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super T> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(Consumer<? super T> action) {
+      while (skip > 0) {
+        if (!original.tryAdvance(ignore -> { })) {
+          return false;
+        }
+        skip--;
+      }
+      return original.tryAdvance(action);
+    }
+  }
+
+  /**
+   * Object limit spliterator.
+   *
+   * @param <T> the type of data to iterate over
+   */
+  private static final class LimitSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
+    private final long limit;
+    private final Spliterator<T> original;
+    private int position = 0;
+
+    public LimitSpliterator(long limit, Spliterator<T> original) {
+      super(
+          original.hasCharacteristics(Spliterator.SIZED)
+              ? Math.min(original.estimateSize(), limit)
+              : Long.MAX_VALUE,
+          original.characteristics());
+      this.limit = limit;
+      this.original = original;
+    }
+
+    @Override
+    public Comparator<? super T> getComparator() {
+      return original.getComparator();
+    }
+
+    @Override
+    public boolean tryAdvance(Consumer<? super T> action) {
+      if (position >= limit) {
+        return false;
+      }
+      boolean result = original.tryAdvance(action);
+      position++;
+      return result;
+    }
+  }
+
+  /**
+   * Value holder for various stream operations.
+   */
+  private static final class ValueConsumer<T> implements Consumer<T> {
+    T value;
+
+    @Override
+    public void accept(T value) {
+      this.value = value;
+    }
+  }
+
+  private final Spliterator<T> spliterator;
+
+  public StreamImpl(TerminatableStream<?> prev, Spliterator<T> spliterator) {
+    super(prev);
+    this.spliterator = spliterator;
+  }
+
+  // terminal
+  @Override
+  public Spliterator<T> spliterator() {
+    terminate();
+    return spliterator;
+  }
+
+  @Override
+  public Iterator<T> iterator() {
+    return Spliterators.iterator(spliterator());
+  }
+
+  @Override
+  public long count() {
+    terminate();
+    long count = 0;
+    while (spliterator.tryAdvance(a -> { })) {
+      count++;
+    }
+    return count;
+  }
+
+  @Override
+  public void forEach(Consumer<? super T> action) {
+    forEachOrdered(action);
+  }
+
+  @Override
+  public void forEachOrdered(Consumer<? super T> action) {
+    terminate();
+    spliterator.forEachRemaining(action);
+  }
+
+  @Override
+  public Object[] toArray() {
+    return toArray(Object[]::new);
+  }
+
+  @Override
+  public <A> A[] toArray(IntFunction<A[]> generator) {
+    List<T> collected = collect(Collectors.toList());
+    return collected.toArray(generator.apply(collected.size()));
+  }
+
+  @Override
+  public <R> R collect(
+      Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
+    return collect(
+        Collector.of(
+            supplier,
+            accumulator,
+            (a, b) -> {
+              combiner.accept(a, b);
+              return a;
+            }));
+  }
+
+  @Override
+  public <R, A> R collect(final Collector<? super T, A, R> collector) {
+    return collector
+        .finisher()
+        .apply(
+            reduce(
+                collector.supplier().get(),
+                (a, t) -> {
+                  collector.accumulator().accept(a, t);
+                  return a;
+                },
+                collector.combiner()));
+  }
+
+  @Override
+  public Optional<T> findFirst() {
+    terminate();
+    ValueConsumer<T> holder = new ValueConsumer<T>();
+    if (spliterator.tryAdvance(holder)) {
+      return Optional.of(holder.value);
+    }
+    return Optional.empty();
+  }
+
+  @Override
+  public Optional<T> findAny() {
+    return findFirst();
+  }
+
+  @Override
+  public boolean anyMatch(Predicate<? super T> predicate) {
+    return filter(predicate).findFirst().isPresent();
+  }
+
+  @Override
+  public boolean allMatch(final Predicate<? super T> predicate) {
+    return !anyMatch(predicate.negate());
+  }
+
+  @Override
+  public boolean noneMatch(final Predicate<? super T> predicate) {
+    return !anyMatch(predicate);
+  }
+
+  @Override
+  public Optional<T> min(final Comparator<? super T> comparator) {
+    return reduce(BinaryOperator.minBy(comparator));
+  }
+
+  @Override
+  public Optional<T> max(final Comparator<? super T> comparator) {
+    return reduce(BinaryOperator.maxBy(comparator));
+  }
+
+  @Override
+  public T reduce(T identity, BinaryOperator<T> accumulator) {
+    return reduce(identity, accumulator, accumulator);
+  }
+
+  @Override
+  public Optional<T> reduce(BinaryOperator<T> accumulator) {
+    ValueConsumer<T> consumer = new ValueConsumer<T>();
+    if (!spliterator.tryAdvance(consumer)) {
+      terminate();
+      return Optional.empty();
+    }
+    return Optional.of(reduce(consumer.value, accumulator));
+  }
+
+  // combiner is ignored, since we don't parallelize
+  @Override
+  public <U> U reduce(
+      U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
+    terminate();
+    final ValueConsumer<U> consumer = new ValueConsumer<U>();
+    consumer.value = identity;
+    spliterator.forEachRemaining(
+        item -> {
+          consumer.accept(accumulator.apply(consumer.value, item));
+        });
+    return consumer.value;
+  }
+  // end terminal
+
+  // intermediate
+  @Override
+  public Stream<T> filter(Predicate<? super T> predicate) {
+    throwIfTerminated();
+    return new StreamImpl<>(this, new FilterSpliterator<>(predicate, spliterator));
+  }
+
+  @Override
+  public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
+    throwIfTerminated();
+    return new StreamImpl<>(this, new MapToObjSpliterator<>(mapper, spliterator));
+  }
+
+  @Override
+  public IntStream mapToInt(ToIntFunction<? super T> mapper) {
+    throwIfTerminated();
+    return new IntStreamImpl(this, new MapToIntSpliterator<>(mapper, spliterator));
+  }
+
+  @Override
+  public LongStream mapToLong(ToLongFunction<? super T> mapper) {
+    throwIfTerminated();
+    return new LongStreamImpl(this, new MapToLongSpliterator<>(mapper, spliterator));
+  }
+
+  @Override
+  public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
+    throwIfTerminated();
+    return new DoubleStreamImpl(this, new MapToDoubleSpliterator<>(mapper, spliterator));
+  }
+
+  @Override
+  public <R> Stream<R> flatMap(final Function<? super T, ? extends Stream<? extends R>> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends Stream<? extends R>> spliteratorOfStreams =
+        new MapToObjSpliterator<>(mapper, spliterator);
+
+    AbstractSpliterator<R> flatMapSpliterator =
+        new Spliterators.AbstractSpliterator<R>(Long.MAX_VALUE, 0) {
+          Stream<? extends R> nextStream;
+          Spliterator<? extends R> next;
+
+          @Override
+          public boolean tryAdvance(Consumer<? super R> action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new StreamImpl<R>(this, flatMapSpliterator);
+  }
+
+  @Override
+  public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends IntStream> spliteratorOfStreams =
+        new MapToObjSpliterator<>(mapper, spliterator);
+
+    AbstractIntSpliterator flatMapSpliterator =
+        new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE, 0) {
+          IntStream nextStream;
+          Spliterator.OfInt next;
+
+          @Override
+          public boolean tryAdvance(IntConsumer action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new IntStreamImpl(this, flatMapSpliterator);
+  }
+
+  @Override
+  public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends LongStream> spliteratorOfStreams =
+        new MapToObjSpliterator<>(mapper, spliterator);
+
+    AbstractLongSpliterator flatMapSpliterator =
+        new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE, 0) {
+          LongStream nextStream;
+          Spliterator.OfLong next;
+
+          @Override
+          public boolean tryAdvance(LongConsumer action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new LongStreamImpl(this, flatMapSpliterator);
+  }
+
+  @Override
+  public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
+    throwIfTerminated();
+    final Spliterator<? extends DoubleStream> spliteratorOfStreams =
+        new MapToObjSpliterator<>(mapper, spliterator);
+
+    AbstractDoubleSpliterator flatMapSpliterator =
+        new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE, 0) {
+          DoubleStream nextStream;
+          Spliterator.OfDouble next;
+
+          @Override
+          public boolean tryAdvance(DoubleConsumer action) {
+            // look for a new spliterator
+            while (advanceToNextSpliterator()) {
+              // if we have one, try to read and use it
+              if (next.tryAdvance(action)) {
+                return true;
+              } else {
+                nextStream.close();
+                nextStream = null;
+                // failed, null it out so we can find another
+                next = null;
+              }
+            }
+            return false;
+          }
+
+          private boolean advanceToNextSpliterator() {
+            while (next == null) {
+              if (!spliteratorOfStreams.tryAdvance(
+                  n -> {
+                    if (n != null) {
+                      nextStream = n;
+                      next = n.spliterator();
+                    }
+                  })) {
+                return false;
+              }
+            }
+            return true;
+          }
+        };
+
+    return new DoubleStreamImpl(this, flatMapSpliterator);
+  }
+
+  @Override
+  public Stream<T> distinct() {
+    throwIfTerminated();
+    HashSet<T> seen = new HashSet<>();
+    return filter(seen::add);
+  }
+
+  @Override
+  public Stream<T> sorted() {
+    throwIfTerminated();
+    Comparator<T> c = (Comparator) Comparator.naturalOrder();
+    return sorted(c);
+  }
+
+  @Override
+  public Stream<T> sorted(final Comparator<? super T> comparator) {
+    throwIfTerminated();
+
+    AbstractSpliterator<T> sortedSpliterator =
+        new Spliterators.AbstractSpliterator<T>(
+            spliterator.estimateSize(), spliterator.characteristics() | Spliterator.SORTED) {
+          Spliterator<T> ordered = null;
+
+          @Override
+          public Comparator<? super T> getComparator() {
+            return comparator == Comparator.naturalOrder() ? null : comparator;
+          }
+
+          @Override
+          public boolean tryAdvance(Consumer<? super T> action) {
+            if (ordered == null) {
+              List<T> list = new ArrayList<>();
+              spliterator.forEachRemaining(list::add);
+              Collections.sort(list, comparator);
+              ordered = list.spliterator();
+            }
+            return ordered.tryAdvance(action);
+          }
+        };
+
+    return new StreamImpl<>(this, sortedSpliterator);
+  }
+
+  @Override
+  public Stream<T> peek(final Consumer<? super T> action) {
+    checkNotNull(action);
+    throwIfTerminated();
+
+    AbstractSpliterator<T> peekSpliterator =
+        new Spliterators.AbstractSpliterator<T>(
+            spliterator.estimateSize(), spliterator.characteristics()) {
+          @Override
+          public boolean tryAdvance(final Consumer<? super T> innerAction) {
+            return spliterator.tryAdvance(
+                item -> {
+                  action.accept(item);
+                  innerAction.accept(item);
+                });
+          }
+        };
+
+    return new StreamImpl<>(this, peekSpliterator);
+  }
+
+  @Override
+  public Stream<T> limit(long maxSize) {
+    throwIfTerminated();
+    checkState(maxSize >= 0, "maxSize may not be negative");
+    return new StreamImpl<>(this, new LimitSpliterator<>(maxSize, spliterator));
+  }
+
+  @Override
+  public Stream<T> skip(long n) {
+    throwIfTerminated();
+    checkState(n >= 0, "n may not be negative");
+    if (n == 0) {
+      return this;
+    }
+    return new StreamImpl<>(this, new SkipSpliterator<>(n, spliterator));
+  }
+
+  @Override
+  public boolean isParallel() {
+    throwIfTerminated();
+    return false;
+  }
+
+  @Override
+  public Stream<T> sequential() {
+    throwIfTerminated();
+    return this;
+  }
+
+  @Override
+  public Stream<T> parallel() {
+    throwIfTerminated();
+    // do nothing, no such thing as gwt+parallel
+    return this;
+  }
+
+  @Override
+  public Stream<T> unordered() {
+    throwIfTerminated();
+    return this;
+  }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/stream/StreamSupport.java b/user/super/com/google/gwt/emul/java/util/stream/StreamSupport.java
index 0c64d9e..3b37063 100644
--- a/user/super/com/google/gwt/emul/java/util/stream/StreamSupport.java
+++ b/user/super/com/google/gwt/emul/java/util/stream/StreamSupport.java
@@ -13,7 +13,6 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package java.util.stream;
 
 import java.util.Spliterator;
@@ -26,7 +25,7 @@
 public final class StreamSupport {
 
   public static DoubleStream doubleStream(Spliterator.OfDouble spliterator, boolean parallel) {
-    return new DoubleStream.DoubleStreamSource(null, spliterator);
+    return new DoubleStreamImpl(null, spliterator);
   }
 
   public static DoubleStream doubleStream(
@@ -41,7 +40,7 @@
   }
 
   public static IntStream intStream(Spliterator.OfInt spliterator, boolean parallel) {
-    return new IntStream.IntStreamSource(null, spliterator);
+    return new IntStreamImpl(null, spliterator);
   }
 
   public static IntStream intStream(
@@ -56,7 +55,7 @@
   }
 
   public static LongStream longStream(Spliterator.OfLong spliterator, boolean parallel) {
-    return new LongStream.LongStreamSource(null, spliterator);
+    return new LongStreamImpl(null, spliterator);
   }
 
   public static LongStream longStream(
@@ -73,7 +72,7 @@
   }
 
   public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel) {
-    return new Stream.StreamSource<T>(null, spliterator);
+    return new StreamImpl<T>(null, spliterator);
   }
 
   public static <T> Stream<T> stream(
