8044047: Missing null pointer checks for streams
authorpsandoz
Wed, 16 Jul 2014 14:35:48 +0200
changeset 25526 d3cbdae6e9f9
parent 25525 4ef885b4c7c6
child 25527 9df990320e71
8044047: Missing null pointer checks for streams Reviewed-by: dfuchs Contributed-by: paul.sandoz@oracle.com, ivan.gerasimov@oracle.com
jdk/src/share/classes/java/util/stream/AbstractPipeline.java
jdk/src/share/classes/java/util/stream/BaseStream.java
jdk/src/share/classes/java/util/stream/DoublePipeline.java
jdk/src/share/classes/java/util/stream/DoubleStream.java
jdk/src/share/classes/java/util/stream/IntPipeline.java
jdk/src/share/classes/java/util/stream/IntStream.java
jdk/src/share/classes/java/util/stream/LongPipeline.java
jdk/src/share/classes/java/util/stream/LongStream.java
jdk/src/share/classes/java/util/stream/PipelineHelper.java
jdk/src/share/classes/java/util/stream/SliceOps.java
jdk/src/share/classes/java/util/stream/Stream.java
jdk/src/share/classes/java/util/stream/StreamOpFlag.java
jdk/test/java/util/stream/bootlib/java/util/stream/ThowableHelper.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java
--- a/jdk/src/share/classes/java/util/stream/AbstractPipeline.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/AbstractPipeline.java	Wed Jul 16 14:35:48 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -322,6 +322,7 @@
     @Override
     @SuppressWarnings("unchecked")
     public S onClose(Runnable closeHandler) {
+        Objects.requireNonNull(closeHandler);
         Runnable existingHandler = sourceStage.sourceCloseAction;
         sourceStage.sourceCloseAction =
                 (existingHandler == null)
@@ -406,7 +407,7 @@
                         // Clear the short circuit flag for next pipeline stage
                         // This stage encapsulates short-circuiting, the next
                         // stage may not have any short-circuit operations, and
-                        // if so spliterator.forEachRemaining should be be used
+                        // if so spliterator.forEachRemaining should be used
                         // for traversal
                         thisOpFlags = thisOpFlags & ~StreamOpFlag.IS_SHORT_CIRCUIT;
                     }
--- a/jdk/src/share/classes/java/util/stream/BaseStream.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/BaseStream.java	Wed Jul 16 14:35:48 2014 +0200
@@ -53,7 +53,7 @@
  * parallelism, which governs the behavior of all stream types.
  *
  * @param <T> the type of the stream elements
- * @param <S> the type of of the stream implementing {@code BaseStream}
+ * @param <S> the type of the stream implementing {@code BaseStream}
  * @since 1.8
  * @see Stream
  * @see IntStream
--- a/jdk/src/share/classes/java/util/stream/DoublePipeline.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/DoublePipeline.java	Wed Jul 16 14:35:48 2014 +0200
@@ -254,6 +254,7 @@
 
     @Override
     public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
+        Objects.requireNonNull(mapper);
         return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
@@ -469,6 +470,7 @@
     public final <R> R collect(Supplier<R> supplier,
                                ObjDoubleConsumer<R> accumulator,
                                BiConsumer<R, R> combiner) {
+        Objects.requireNonNull(combiner);
         BinaryOperator<R> operator = (left, right) -> {
             combiner.accept(left, right);
             return left;
--- a/jdk/src/share/classes/java/util/stream/DoubleStream.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/DoubleStream.java	Wed Jul 16 14:35:48 2014 +0200
@@ -768,7 +768,7 @@
      *  to the element at position {@code n - 1}.
      *
      * @param seed the initial element
-     * @param f a function to be applied to to the previous element to produce
+     * @param f a function to be applied to the previous element to produce
      *          a new element
      * @return a new sequential {@code DoubleStream}
      */
--- a/jdk/src/share/classes/java/util/stream/IntPipeline.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/IntPipeline.java	Wed Jul 16 14:35:48 2014 +0200
@@ -290,6 +290,7 @@
 
     @Override
     public final IntStream flatMap(IntFunction<? extends IntStream> mapper) {
+        Objects.requireNonNull(mapper);
         return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
@@ -465,6 +466,7 @@
     public final <R> R collect(Supplier<R> supplier,
                                ObjIntConsumer<R> accumulator,
                                BiConsumer<R, R> combiner) {
+        Objects.requireNonNull(combiner);
         BinaryOperator<R> operator = (left, right) -> {
             combiner.accept(left, right);
             return left;
--- a/jdk/src/share/classes/java/util/stream/IntStream.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/IntStream.java	Wed Jul 16 14:35:48 2014 +0200
@@ -734,7 +734,7 @@
      * element at position {@code n - 1}.
      *
      * @param seed the initial element
-     * @param f a function to be applied to to the previous element to produce
+     * @param f a function to be applied to the previous element to produce
      *          a new element
      * @return A new sequential {@code IntStream}
      */
--- a/jdk/src/share/classes/java/util/stream/LongPipeline.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/LongPipeline.java	Wed Jul 16 14:35:48 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -271,6 +271,7 @@
 
     @Override
     public final LongStream flatMap(LongFunction<? extends LongStream> mapper) {
+        Objects.requireNonNull(mapper);
         return new StatelessOp<Long>(this, StreamShape.LONG_VALUE,
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
@@ -447,6 +448,7 @@
     public final <R> R collect(Supplier<R> supplier,
                                ObjLongConsumer<R> accumulator,
                                BiConsumer<R, R> combiner) {
+        Objects.requireNonNull(combiner);
         BinaryOperator<R> operator = (left, right) -> {
             combiner.accept(left, right);
             return left;
--- a/jdk/src/share/classes/java/util/stream/LongStream.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/LongStream.java	Wed Jul 16 14:35:48 2014 +0200
@@ -727,7 +727,7 @@
      * element at position {@code n - 1}.
      *
      * @param seed the initial element
-     * @param f a function to be applied to to the previous element to produce
+     * @param f a function to be applied to the previous element to produce
      *          a new element
      * @return a new sequential {@code LongStream}
      */
--- a/jdk/src/share/classes/java/util/stream/PipelineHelper.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/PipelineHelper.java	Wed Jul 16 14:35:48 2014 +0200
@@ -74,7 +74,7 @@
     /**
      * Returns the exact output size of the portion of the output resulting from
      * applying the pipeline stages described by this {@code PipelineHelper} to
-     * the the portion of the input described by the provided
+     * the portion of the input described by the provided
      * {@code Spliterator}, if known.  If not known or known infinite, will
      * return {@code -1}.
      *
--- a/jdk/src/share/classes/java/util/stream/SliceOps.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/SliceOps.java	Wed Jul 16 14:35:48 2014 +0200
@@ -693,7 +693,7 @@
          * size.
          *
          * @param target the target size
-         * @return return the number of completed elements
+         * @return the number of completed elements
          */
         private long completedSize(long target) {
             if (completed)
--- a/jdk/src/share/classes/java/util/stream/Stream.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/Stream.java	Wed Jul 16 14:35:48 2014 +0200
@@ -1013,7 +1013,7 @@
      *
      * @param <T> the type of stream elements
      * @param seed the initial element
-     * @param f a function to be applied to to the previous element to produce
+     * @param f a function to be applied to the previous element to produce
      *          a new element
      * @return a new sequential {@code Stream}
      */
--- a/jdk/src/share/classes/java/util/stream/StreamOpFlag.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/src/share/classes/java/util/stream/StreamOpFlag.java	Wed Jul 16 14:35:48 2014 +0200
@@ -115,7 +115,7 @@
  * characteristics that stream has; when describing a stream operation, one need
  * describe whether the operation preserves, injects, or clears that
  * characteristic.  Accordingly, two bits are used for each flag, so as to allow
- * representing not only the presence of of a characteristic, but how an
+ * representing not only the presence of a characteristic, but how an
  * operation modifies that characteristic.  There are two common forms in which
  * flag bits are combined into an {@code int} bit set.  <em>Stream flags</em>
  * are a unioned bit set constructed by ORing the enum characteristic values of
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/ThowableHelper.java	Wed Jul 16 14:35:48 2014 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+public final class ThowableHelper {
+
+    public static void checkException(Class<? extends Exception> ce, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        } catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught);
+        assertTrue(ce.isInstance(caught));
+    }
+
+    public static void checkNPE(Runnable r) {
+        checkException(NullPointerException.class, r);
+    }
+
+    public static void checkISE(Runnable r) {
+        checkException(IllegalStateException.class, r);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java	Wed Jul 16 14:35:48 2014 +0200
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary primtive stream collection with summary statistics
+ * @bug 8044047
+ */
+
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.DoubleSummaryStatistics;
+import java.util.IntSummaryStatistics;
+import java.util.List;
+import java.util.LongSummaryStatistics;
+import java.util.stream.Collectors;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.OpTestCase;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+import static java.util.stream.ThowableHelper.checkNPE;
+
+@Test
+public class CollectAndSummaryStatisticsTest extends OpTestCase {
+
+    public void testIntCollectNull() {
+        checkNPE(() -> IntStream.of(1).collect(null,
+                                               IntSummaryStatistics::accept,
+                                               IntSummaryStatistics::combine));
+        checkNPE(() -> IntStream.of(1).collect(IntSummaryStatistics::new,
+                                               null,
+                                               IntSummaryStatistics::combine));
+        checkNPE(() -> IntStream.of(1).collect(IntSummaryStatistics::new,
+                                               IntSummaryStatistics::accept,
+                                               null));
+    }
+
+    public void testLongCollectNull() {
+        checkNPE(() -> LongStream.of(1).collect(null,
+                                               LongSummaryStatistics::accept,
+                                               LongSummaryStatistics::combine));
+        checkNPE(() -> LongStream.of(1).collect(LongSummaryStatistics::new,
+                                                null,
+                                                LongSummaryStatistics::combine));
+        checkNPE(() -> LongStream.of(1).collect(LongSummaryStatistics::new,
+                                                LongSummaryStatistics::accept,
+                                                null));
+    }
+
+    public void testDoubleCollectNull() {
+        checkNPE(() -> DoubleStream.of(1).collect(null,
+                                                DoubleSummaryStatistics::accept,
+                                                DoubleSummaryStatistics::combine));
+        checkNPE(() -> DoubleStream.of(1).collect(DoubleSummaryStatistics::new,
+                                                null,
+                                                DoubleSummaryStatistics::combine));
+        checkNPE(() -> DoubleStream.of(1).collect(DoubleSummaryStatistics::new,
+                                                  DoubleSummaryStatistics::accept,
+                                                  null));
+    }
+
+    public void testIntStatistics() {
+        List<IntSummaryStatistics> instances = new ArrayList<>();
+        instances.add(countTo(1000).stream().collect(Collectors.summarizingInt(i -> i)));
+        instances.add(countTo(1000).stream().mapToInt(i -> i).summaryStatistics());
+        instances.add(countTo(1000).stream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
+                                                                      IntSummaryStatistics::accept,
+                                                                      IntSummaryStatistics::combine));
+        instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingInt(i -> i)));
+        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics());
+        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
+                                                                              IntSummaryStatistics::accept,
+                                                                              IntSummaryStatistics::combine));
+
+        for (IntSummaryStatistics stats : instances) {
+            assertEquals(stats.getCount(), 1000);
+            assertEquals(stats.getSum(), countTo(1000).stream().mapToInt(i -> i).sum());
+            assertEquals(stats.getAverage(), (double) stats.getSum() / stats.getCount());
+            assertEquals(stats.getMax(), 1000);
+            assertEquals(stats.getMin(), 1);
+        }
+    }
+
+
+    public void testLongStatistics() {
+        List<LongSummaryStatistics> instances = new ArrayList<>();
+        instances.add(countTo(1000).stream().collect(Collectors.summarizingLong(i -> i)));
+        instances.add(countTo(1000).stream().mapToLong(i -> i).summaryStatistics());
+        instances.add(countTo(1000).stream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
+                                                                       LongSummaryStatistics::accept,
+                                                                       LongSummaryStatistics::combine));
+        instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingLong(i -> i)));
+        instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics());
+        instances.add(countTo(1000).parallelStream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
+                                                                               LongSummaryStatistics::accept,
+                                                                               LongSummaryStatistics::combine));
+
+        for (LongSummaryStatistics stats : instances) {
+            assertEquals(stats.getCount(), 1000);
+            assertEquals(stats.getSum(), (long) countTo(1000).stream().mapToInt(i -> i).sum());
+            assertEquals(stats.getAverage(), (double) stats.getSum() / stats.getCount());
+            assertEquals(stats.getMax(), 1000L);
+            assertEquals(stats.getMin(), 1L);
+        }
+    }
+
+    public void testDoubleStatistics() {
+        List<DoubleSummaryStatistics> instances = new ArrayList<>();
+        instances.add(countTo(1000).stream().collect(Collectors.summarizingDouble(i -> i)));
+        instances.add(countTo(1000).stream().mapToDouble(i -> i).summaryStatistics());
+        instances.add(countTo(1000).stream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
+                                                                         DoubleSummaryStatistics::accept,
+                                                                         DoubleSummaryStatistics::combine));
+        instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingDouble(i -> i)));
+        instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics());
+        instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
+                                                                                 DoubleSummaryStatistics::accept,
+                                                                                 DoubleSummaryStatistics::combine));
+
+        for (DoubleSummaryStatistics stats : instances) {
+            assertEquals(stats.getCount(), 1000);
+            assertEquals(stats.getSum(), (double) countTo(1000).stream().mapToInt(i -> i).sum());
+            assertEquals(stats.getAverage(), stats.getSum() / stats.getCount());
+            assertEquals(stats.getMax(), 1000.0);
+            assertEquals(stats.getMin(), 1.0);
+        }
+    }
+}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java	Wed Jul 16 08:07:38 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.tests.java.util.stream;
-
-import org.testng.annotations.Test;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.function.Function;
-import java.util.stream.*;
-
-import static java.util.stream.LambdaTestHelpers.*;
-
-/**
- * ExplodeOpTest
- *
- * @author Brian Goetz
- */
-@Test
-public class ExplodeOpTest extends OpTestCase {
-
-    static final Function<Integer, Stream<Integer>> integerRangeMapper
-            = e -> IntStream.range(0, e).boxed();
-
-    public void testFlatMap() {
-        String[] stringsArray = {"hello", "there", "", "yada"};
-        Stream<String> strings = Arrays.asList(stringsArray).stream();
-        assertConcat(strings.flatMap(flattenChars).iterator(), "hellothereyada");
-
-        assertCountSum(countTo(10).stream().flatMap(mfId), 10, 55);
-        assertCountSum(countTo(10).stream().flatMap(mfNull), 0, 0);
-        assertCountSum(countTo(3).stream().flatMap(mfLt), 6, 4);
-
-        exerciseOps(TestData.Factory.ofArray("stringsArray", stringsArray), s -> s.flatMap(flattenChars));
-        exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testOps(String name, TestData.OfRef<Integer> data) {
-        Collection<Integer> result = exerciseOps(data, s -> s.flatMap(mfId));
-        assertEquals(data.size(), result.size());
-
-        result = exerciseOps(data, s -> s.flatMap(mfNull));
-        assertEquals(0, result.size());
-
-        result = exerciseOps(data, s-> s.flatMap(e -> Stream.empty()));
-        assertEquals(0, result.size());
-
-        exerciseOps(data, s -> s.flatMap(mfLt));
-        exerciseOps(data, s -> s.flatMap(integerRangeMapper));
-        exerciseOps(data, s -> s.flatMap((Integer e) -> IntStream.range(0, e).boxed().limit(10)));
-    }
-
-    //
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testIntOps(String name, TestData.OfInt data) {
-        Collection<Integer> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToInt(j -> j)));
-        assertEquals(data.size(), result.size());
-        assertContents(data, result);
-
-        result = exerciseOps(data, s -> s.flatMap(i -> IntStream.empty()));
-        assertEquals(0, result.size());
-
-        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e)));
-        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e).limit(10)));
-    }
-
-    //
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testLongOps(String name, TestData.OfLong data) {
-        Collection<Long> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToLong(j -> j)));
-        assertEquals(data.size(), result.size());
-        assertContents(data, result);
-
-        result = exerciseOps(data, s -> LongStream.empty());
-        assertEquals(0, result.size());
-
-        exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e)));
-        exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e).limit(10)));
-    }
-
-    //
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testDoubleOps(String name, TestData.OfDouble data) {
-        Collection<Double> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToDouble(j -> j)));
-        assertEquals(data.size(), result.size());
-        assertContents(data, result);
-
-        result = exerciseOps(data, s -> DoubleStream.empty());
-        assertEquals(0, result.size());
-
-        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).asDoubleStream()));
-        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).limit(10).asDoubleStream()));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java	Wed Jul 16 14:35:48 2014 +0200
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary flat-map operations
+ * @bug 8044047
+ */
+
+package org.openjdk.tests.java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.function.Function;
+import java.util.stream.*;
+
+import static java.util.stream.LambdaTestHelpers.*;
+import static java.util.stream.ThowableHelper.checkNPE;
+
+@Test
+public class FlatMapOpTest extends OpTestCase {
+
+    public void testNullMapper() {
+        checkNPE(() -> Stream.of(1).flatMap(null));
+        checkNPE(() -> IntStream.of(1).flatMap(null));
+        checkNPE(() -> LongStream.of(1).flatMap(null));
+        checkNPE(() -> DoubleStream.of(1).flatMap(null));
+    }
+
+    static final Function<Integer, Stream<Integer>> integerRangeMapper
+            = e -> IntStream.range(0, e).boxed();
+
+    public void testFlatMap() {
+        String[] stringsArray = {"hello", "there", "", "yada"};
+        Stream<String> strings = Arrays.asList(stringsArray).stream();
+        assertConcat(strings.flatMap(flattenChars).iterator(), "hellothereyada");
+
+        assertCountSum(countTo(10).stream().flatMap(mfId), 10, 55);
+        assertCountSum(countTo(10).stream().flatMap(mfNull), 0, 0);
+        assertCountSum(countTo(3).stream().flatMap(mfLt), 6, 4);
+
+        exerciseOps(TestData.Factory.ofArray("stringsArray", stringsArray), s -> s.flatMap(flattenChars));
+        exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testOps(String name, TestData.OfRef<Integer> data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.flatMap(mfId));
+        assertEquals(data.size(), result.size());
+
+        result = exerciseOps(data, s -> s.flatMap(mfNull));
+        assertEquals(0, result.size());
+
+        result = exerciseOps(data, s-> s.flatMap(e -> Stream.empty()));
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(mfLt));
+        exerciseOps(data, s -> s.flatMap(integerRangeMapper));
+        exerciseOps(data, s -> s.flatMap((Integer e) -> IntStream.range(0, e).boxed().limit(10)));
+    }
+
+    //
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testIntOps(String name, TestData.OfInt data) {
+        Collection<Integer> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToInt(j -> j)));
+        assertEquals(data.size(), result.size());
+        assertContents(data, result);
+
+        result = exerciseOps(data, s -> s.flatMap(i -> IntStream.empty()));
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e)));
+        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e).limit(10)));
+    }
+
+    //
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testLongOps(String name, TestData.OfLong data) {
+        Collection<Long> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToLong(j -> j)));
+        assertEquals(data.size(), result.size());
+        assertContents(data, result);
+
+        result = exerciseOps(data, s -> LongStream.empty());
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e)));
+        exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e).limit(10)));
+    }
+
+    //
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testDoubleOps(String name, TestData.OfDouble data) {
+        Collection<Double> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToDouble(j -> j)));
+        assertEquals(data.size(), result.size());
+        assertContents(data, result);
+
+        result = exerciseOps(data, s -> DoubleStream.empty());
+        assertEquals(0, result.size());
+
+        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).asDoubleStream()));
+        exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).limit(10).asDoubleStream()));
+    }
+}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java	Wed Jul 16 14:35:48 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
 import java.util.stream.TestData;
 
 import static java.util.stream.Collectors.toList;
+import static java.util.stream.ThowableHelper.checkISE;
 
 @Test
 public class StreamBuilderTest extends OpTestCase {
@@ -52,23 +53,6 @@
         return sizes.stream().map(i -> new Object[] { i }).toArray(Object[][]::new);
     }
 
-    private void checkException(Class<? extends Exception> ce, Runnable r) {
-        Exception caught = null;
-        try {
-            r.run();
-        } catch (Exception e) {
-            caught = e;
-        }
-
-        assertNotNull(caught);
-        assertTrue(ce.isInstance(caught));
-    }
-
-    private void checkISE(Runnable r) {
-        checkException(IllegalStateException.class, r);
-    }
-
-        //
 
     @Test
     public void testSingleton() {
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java	Wed Jul 16 08:07:38 2014 -0400
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java	Wed Jul 16 14:35:48 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,6 +20,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
+/*
+ * @test
+ * @summary close handlers and closing streams
+ * @bug 8044047
+ */
+
 package org.openjdk.tests.java.util.stream;
 
 import java.util.Arrays;
@@ -29,14 +36,14 @@
 import org.testng.annotations.Test;
 
 import static java.util.stream.LambdaTestHelpers.countTo;
+import static java.util.stream.ThowableHelper.checkNPE;
 
-/**
- * StreamCloseTest
- *
- * @author Brian Goetz
- */
 @Test(groups = { "serialization-hostile" })
 public class StreamCloseTest extends OpTestCase {
+    public void testNullCloseHandler() {
+        checkNPE(() -> Stream.of(1).onClose(null));
+    }
+
     public void testEmptyCloseHandler() {
         try (Stream<Integer> ints = countTo(100).stream()) {
             ints.forEach(i -> {});
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java	Wed Jul 16 08:07:38 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.tests.java.util.stream;
-
-import java.util.ArrayList;
-import java.util.DoubleSummaryStatistics;
-import java.util.IntSummaryStatistics;
-import java.util.List;
-import java.util.LongSummaryStatistics;
-import java.util.stream.Collectors;
-import java.util.stream.OpTestCase;
-
-import org.testng.annotations.Test;
-
-import static java.util.stream.LambdaTestHelpers.countTo;
-
-/**
- * TestSummaryStatistics
- *
- * @author Brian Goetz
- */
-@Test
-public class SummaryStatisticsTest extends OpTestCase {
-    public void testIntStatistics() {
-        List<IntSummaryStatistics> instances = new ArrayList<>();
-        instances.add(countTo(1000).stream().collect(Collectors.summarizingInt(i -> i)));
-        instances.add(countTo(1000).stream().mapToInt(i -> i).summaryStatistics());
-        instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingInt(i -> i)));
-        instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics());
-
-        for (IntSummaryStatistics stats : instances) {
-            assertEquals(stats.getCount(), 1000);
-            assertEquals(stats.getSum(), countTo(1000).stream().mapToInt(i -> i).sum());
-            assertEquals(stats.getMax(), 1000);
-            assertEquals(stats.getMin(), 1);
-        }
-    }
-
-    public void testLongStatistics() {
-        List<LongSummaryStatistics> instances = new ArrayList<>();
-        instances.add(countTo(1000).stream().collect(Collectors.summarizingLong(i -> i)));
-        instances.add(countTo(1000).stream().mapToLong(i -> i).summaryStatistics());
-        instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingLong(i -> i)));
-        instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics());
-
-        for (LongSummaryStatistics stats : instances) {
-            assertEquals(stats.getCount(), 1000);
-            assertEquals(stats.getSum(), (long) countTo(1000).stream().mapToInt(i -> i).sum());
-            assertEquals(stats.getMax(), 1000L);
-            assertEquals(stats.getMin(), 1L);
-        }
-    }
-
-    public void testDoubleStatistics() {
-        List<DoubleSummaryStatistics> instances = new ArrayList<>();
-        instances.add(countTo(1000).stream().collect(Collectors.summarizingDouble(i -> i)));
-        instances.add(countTo(1000).stream().mapToDouble(i -> i).summaryStatistics());
-        instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingDouble(i -> i)));
-        instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics());
-
-        for (DoubleSummaryStatistics stats : instances) {
-            assertEquals(stats.getCount(), 1000);
-            assertEquals(stats.getSum(), (double) countTo(1000).stream().mapToInt(i -> i).sum());
-            assertEquals(stats.getMax(), 1000.0);
-            assertEquals(stats.getMin(), 1.0);
-        }
-    }
-}