changeset 11553:11dfc712c44f

Merge
author kvn
date Mon, 02 Mar 2015 10:09:03 -0800
parents 8a07f1204f5b 7c6d6f1b7a56
children c5ea253b6dc0
files test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java
diffstat 41 files changed, 1807 insertions(+), 934 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Feb 26 10:56:26 2015 -0800
+++ b/.hgtags	Mon Mar 02 10:09:03 2015 -0800
@@ -294,3 +294,4 @@
 541a8cef4e0d54c3e4b52a98c6af3c31e2096669 jdk9-b49
 f6b8edd397ee463be208fee27517c99101293267 jdk9-b50
 a0dad230aeb3b0d5cfd5b0715029e48d50573f8c jdk9-b51
+607ea68032cd4a4cf2c7a7a41fcb39602d6a75e2 jdk9-b52
--- a/make/Tools.gmk	Thu Feb 26 10:56:26 2015 -0800
+++ b/make/Tools.gmk	Mon Mar 02 10:09:03 2015 -0800
@@ -180,6 +180,8 @@
       OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
       OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
       PROGRAM := fix_empty_sec_hdr_flags))
+
+  BUILD_TOOLS_JDK += $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS)
 endif
 
 $(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE) $(COPY_JIMAGE_SERVICE_PROVIDER)
@@ -189,4 +191,3 @@
 all: java-tools
 
 endif # _TOOLS_GMK
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/test/JtregNative.gmk	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,82 @@
+#
+# Copyright (c) 2015, 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# 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.
+#
+
+################################################################################
+# This file builds the native component of the JTReg tests for JDK.
+# It also covers the test-image part, where the built files are copied to the
+# test image.
+################################################################################
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include TestFilesCompilation.gmk
+
+################################################################################
+# Targets for building the native tests themselves.
+################################################################################
+
+# Add more directories here when needed.
+BUILD_JDK_JTREG_NATIVE_SRC := \
+    $(JDK_TOPDIR)/test/native_sanity \
+    #
+
+BUILD_JDK_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/jdk/jtreg/native
+
+BUILD_JDK_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/jdk/jtreg
+
+$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \
+    TYPE := LIBRARY, \
+    SOURCE_DIRS := $(BUILD_JDK_JTREG_NATIVE_SRC), \
+    OUTPUT_DIR := $(BUILD_JDK_JTREG_OUTPUT_DIR), \
+))
+
+$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_EXECUTABLES, \
+    TYPE := PROGRAM, \
+    SOURCE_DIRS := $(BUILD_JDK_JTREG_NATIVE_SRC), \
+    OUTPUT_DIR := $(BUILD_JDK_JTREG_OUTPUT_DIR), \
+))
+
+build-test-jdk-jtreg-native: $(BUILD_JDK_JTREG_LIBRARIES) $(BUILD_JDK_JTREG_EXECUTABLES)
+
+
+################################################################################
+# Targets for building test-image.
+################################################################################
+
+# Copy to jdk jtreg test image
+$(eval $(call SetupCopyFiles,COPY_JDK_JTREG_NATIVE, \
+    SRC := $(BUILD_JDK_JTREG_OUTPUT_DIR), \
+    DEST := $(TEST_IMAGE_DIR)/jdk/jtreg/native, \
+    FILES := $(BUILD_JDK_JTREG_LIBRARIES) $(BUILD_JDK_JTREG_EXECUTABLES), \
+    FLATTEN := true))
+
+test-image-jdk-jtreg-native: $(COPY_JDK_JTREG_NATIVE)
+
+all: build-test-jdk-jtreg-native
+test-image: test-image-jdk-jtreg-native
+
+.PHONY: default all build-test-jdk-jtreg-native test-image-jdk-jtreg-native test-image
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java	Mon Mar 02 10:09:03 2015 -0800
@@ -40,6 +40,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import static java.io.ObjectStreamClass.processQueue;
+import sun.misc.Unsafe;
 import sun.reflect.misc.ReflectUtil;
 
 /**
@@ -375,6 +376,7 @@
             }
             if (depth == 0) {
                 vlist.doCallbacks();
+                freeze();
             }
             return obj;
         } finally {
@@ -465,6 +467,7 @@
             }
             if (depth == 0) {
                 vlist.doCallbacks();
+                freeze();
             }
             return obj;
         } finally {
@@ -2357,6 +2360,26 @@
         }
     }
 
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+    /**
+     * Performs a "freeze" action, required to adhere to final field semantics.
+     *
+     * <p> This method can be called unconditionally before returning the graph,
+     * from the topmost readObject call, since it is expected that the
+     * additional cost of the freeze action is negligible compared to
+     * reconstituting even the most simple graph.
+     *
+     * <p> Nested calls to readObject do not issue freeze actions because the
+     * sub-graph returned from a nested call is not guaranteed to be fully
+     * initialized yet (possible cycles).
+     */
+    private void freeze() {
+        // Issue a StoreStore|StoreLoad fence, which is at least sufficient
+        // to provide final-freeze semantics.
+        UNSAFE.storeFence();
+    }
+
     /**
      * Input stream with two modes: in default mode, inputs data written in the
      * same format as DataOutputStream; in "block data" mode, inputs data
--- a/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Mon Mar 02 10:09:03 2015 -0800
@@ -436,7 +436,7 @@
     }
 
     private MethodType bindArgumentType(BoundMethodHandle mh, int pos, BasicType bt) {
-        assert(mh.form == lambdaForm);
+        assert(mh.form.uncustomize() == lambdaForm);
         assert(mh.form.names[1+pos].type == bt);
         assert(BasicType.basicType(mh.type().parameterType(pos)) == bt);
         return mh.type().dropParameterTypes(pos, pos+1);
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java	Mon Mar 02 10:09:03 2015 -0800
@@ -296,7 +296,8 @@
      * constructor has default (package) access.
      *
      * @return a string describing this {@code Constructor}
-     * @jls 8.8.3. Constructor Modifiers
+     * @jls 8.8.3 Constructor Modifiers
+     * @jls 8.9.2 Enum Body Declarations
      */
     public String toString() {
         return sharedToString(Modifier.constructorModifiers(),
@@ -342,7 +343,8 @@
      * include type parameters
      *
      * @since 1.5
-     * @jls 8.8.3. Constructor Modifiers
+     * @jls 8.8.3 Constructor Modifiers
+     * @jls 8.9.2 Enum Body Declarations
      */
     @Override
     public String toGenericString() {
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Mon Mar 02 10:09:03 2015 -0800
@@ -356,6 +356,8 @@
      * @return a string describing this {@code Method}
      *
      * @jls 8.4.3 Method Modifiers
+     * @jls 9.4   Method Declarations
+     * @jls 9.6.1 Annotation Type Elements
      */
     public String toString() {
         return sharedToString(Modifier.methodModifiers(),
@@ -409,6 +411,8 @@
      * @since 1.5
      *
      * @jls 8.4.3 Method Modifiers
+     * @jls 9.4   Method Declarations
+     * @jls 9.6.1 Annotation Type Elements
      */
     @Override
     public String toGenericString() {
--- a/src/java.base/share/classes/java/math/BigDecimal.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/math/BigDecimal.java	Mon Mar 02 10:09:03 2015 -0800
@@ -3740,8 +3740,8 @@
                 throw new ExceptionInInitializerError(ex);
             }
         }
-        static void setIntCompactVolatile(BigDecimal bd, long val) {
-            unsafe.putLongVolatile(bd, intCompactOffset, val);
+        static void setIntCompact(BigDecimal bd, long val) {
+            unsafe.putLong(bd, intCompactOffset, val);
         }
 
         static void setIntValVolatile(BigDecimal bd, BigInteger val) {
@@ -3765,7 +3765,7 @@
             throw new java.io.StreamCorruptedException(message);
         // [all values of scale are now allowed]
         }
-        UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal));
+        UnsafeHolder.setIntCompact(this, compactValFor(intVal));
     }
 
    /**
--- a/src/java.base/share/classes/java/math/BigInteger.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/math/BigInteger.java	Mon Mar 02 10:09:03 2015 -0800
@@ -4368,11 +4368,11 @@
         }
 
         static void putSign(BigInteger bi, int sign) {
-            unsafe.putIntVolatile(bi, signumOffset, sign);
+            unsafe.putInt(bi, signumOffset, sign);
         }
 
         static void putMag(BigInteger bi, int[] magnitude) {
-            unsafe.putObjectVolatile(bi, magOffset, magnitude);
+            unsafe.putObject(bi, magOffset, magnitude);
         }
     }
 
--- a/src/java.base/share/classes/java/time/Instant.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/time/Instant.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -1229,8 +1229,14 @@
      * @throws ArithmeticException if numeric overflow occurs
      */
     public long toEpochMilli() {
-        long millis = Math.multiplyExact(seconds, 1000);
-        return millis + nanos / 1000_000;
+        if (seconds < 0 && nanos > 0) {
+            long millis = Math.multiplyExact(seconds+1, 1000);
+            long adjustment = nanos / 1000_000 - 1000;
+            return millis + adjustment;
+        } else {
+            long millis = Math.multiplyExact(seconds, 1000);
+            return millis + nanos / 1000_000;
+        }
     }
 
     //-----------------------------------------------------------------------
--- a/src/java.base/share/classes/java/util/Arrays.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/Arrays.java	Mon Mar 02 10:09:03 2015 -0800
@@ -4685,6 +4685,14 @@
      * <p>If the generator function throws an exception, it is relayed to
      * the caller and the array is left in an indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, using a generator function to compute
+     * each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.apply(i));
+     * }</pre>
+     *
      * @param <T> type of elements of the array
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
@@ -4706,6 +4714,15 @@
      * is thrown from {@code parallelSetAll} and the array is left in an
      * indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, in parallel, using a generator function
+     * to compute each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.apply(i));
+     * }</pre>
+     *
      * @param <T> type of elements of the array
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
@@ -4725,6 +4742,14 @@
      * <p>If the generator function throws an exception, it is relayed to
      * the caller and the array is left in an indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, using a generator function to compute
+     * each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.applyAsInt(i));
+     * }</pre>
+     *
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
      *        value for that position
@@ -4745,6 +4770,15 @@
      * is thrown from {@code parallelSetAll} and the array is left in an
      * indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, in parallel, using a generator function
+     * to compute each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.applyAsInt(i));
+     * }</pre>
+     *
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
      * value for that position
@@ -4763,6 +4797,14 @@
      * <p>If the generator function throws an exception, it is relayed to
      * the caller and the array is left in an indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, using a generator function to compute
+     * each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.applyAsLong(i));
+     * }</pre>
+     *
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
      *        value for that position
@@ -4783,6 +4825,15 @@
      * is thrown from {@code parallelSetAll} and the array is left in an
      * indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, in parallel, using a generator function
+     * to compute each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.applyAsLong(i));
+     * }</pre>
+     *
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
      *        value for that position
@@ -4801,6 +4852,14 @@
      * <p>If the generator function throws an exception, it is relayed to
      * the caller and the array is left in an indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, using a generator function to compute
+     * each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.applyAsDouble(i));
+     * }</pre>
+     *
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
      *        value for that position
@@ -4821,6 +4880,15 @@
      * is thrown from {@code parallelSetAll} and the array is left in an
      * indeterminate state.
      *
+     * @apiNote
+     * Setting a subrange of an array, in parallel, using a generator function
+     * to compute each element, can be written as follows:
+     * <pre>{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.applyAsDouble(i));
+     * }</pre>
+     *
      * @param array array to be initialized
      * @param generator a function accepting an index and producing the desired
      *        value for that position
--- a/src/java.base/share/classes/java/util/stream/Collectors.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/stream/Collectors.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -404,6 +404,54 @@
     }
 
     /**
+     * Adapts a {@code Collector} accepting elements of type {@code U} to one
+     * accepting elements of type {@code T} by applying a flat mapping function
+     * to each input element before accumulation.  The flat mapping function
+     * maps an input element to a {@link Stream stream} covering zero or more
+     * output elements that are then accumulated downstream.  Each mapped stream
+     * is {@link java.util.stream.BaseStream#close() closed} after its contents
+     * have been placed downstream.  (If a mapped stream is {@code null}
+     * an empty stream is used, instead.)
+     *
+     * @apiNote
+     * The {@code flatMapping()} collectors are most useful when used in a
+     * multi-level reduction, such as downstream of a {@code groupingBy} or
+     * {@code partitioningBy}.  For example, given a stream of
+     * {@code Order}, to accumulate the set of line items for each customer:
+     * <pre>{@code
+     *     Map<String, Set<LineItem>> itemsByCustomerName
+     *         = orders.stream().collect(groupingBy(Order::getCustomerName,
+     *                                              flatMapping(order -> order.getLineItems().stream(), toSet())));
+     * }</pre>
+     *
+     * @param <T> the type of the input elements
+     * @param <U> type of elements accepted by downstream collector
+     * @param <A> intermediate accumulation type of the downstream collector
+     * @param <R> result type of collector
+     * @param mapper a function to be applied to the input elements, which
+     * returns a stream of results
+     * @param downstream a collector which will receive the elements of the
+     * stream returned by mapper
+     * @return a collector which applies the mapping function to the input
+     * elements and provides the flat mapped results to the downstream collector
+     * @since 1.9
+     */
+    public static <T, U, A, R>
+    Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
+                                   Collector<? super U, A, R> downstream) {
+        BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
+        return new CollectorImpl<>(downstream.supplier(),
+                            (r, t) -> {
+                                try (Stream<? extends U> result = mapper.apply(t)) {
+                                    if (result != null)
+                                        result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
+                                }
+                            },
+                            downstream.combiner(), downstream.finisher(),
+                            downstream.characteristics());
+    }
+
+    /**
      * Adapts a {@code Collector} to perform an additional finishing
      * transformation.  For example, one could adapt the {@link #toList()}
      * collector to always produce an immutable list with:
--- a/src/java.base/share/classes/java/util/zip/ZipEntry.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/zip/ZipEntry.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, 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
@@ -41,7 +41,9 @@
 class ZipEntry implements ZipConstants, Cloneable {
 
     String name;        // entry name
-    long time = -1;     // last modification time
+    long xdostime = -1; // last modification time (in extended DOS time,
+                        // where milliseconds lost in conversion might
+                        // be encoded into the upper half)
     FileTime mtime;     // last modification time, from extra field data
     FileTime atime;     // last access time, from extra field data
     FileTime ctime;     // creation time, from extra field data
@@ -64,6 +66,28 @@
     public static final int DEFLATED = 8;
 
     /**
+     * DOS time constant for representing timestamps before 1980.
+     */
+    static final long DOSTIME_BEFORE_1980 = (1 << 21) | (1 << 16);
+
+    /**
+     * Approximately 128 years, in milliseconds (ignoring leap years etc).
+     *
+     * This establish an approximate high-bound value for DOS times in
+     * milliseconds since epoch, used to enable an efficient but
+     * sufficient bounds check to avoid generating extended last modified
+     * time entries.
+     *
+     * Calculating the exact number is locale dependent, would require loading
+     * TimeZone data eagerly, and would make little practical sense. Since DOS
+     * times theoretically go to 2107 - with compatibility not guaranteed
+     * after 2099 - setting this to a time that is before but near 2099
+     * should be sufficient.
+     */
+    private static final long UPPER_DOSTIME_BOUND =
+            128L * 365 * 24 * 60 * 60 * 1000;
+
+    /**
      * Creates a new zip entry with the specified name.
      *
      * @param  name
@@ -93,7 +117,7 @@
     public ZipEntry(ZipEntry e) {
         Objects.requireNonNull(e, "entry");
         name = e.name;
-        time = e.time;
+        xdostime = e.xdostime;
         mtime = e.mtime;
         atime = e.atime;
         ctime = e.ctime;
@@ -137,8 +161,14 @@
      * @see #getLastModifiedTime()
      */
     public void setTime(long time) {
-        this.time = time;
-        this.mtime = null;
+        this.xdostime = javaToExtendedDosTime(time);
+        // Avoid setting the mtime field if time is in the valid
+        // range for a DOS time
+        if (xdostime != DOSTIME_BEFORE_1980 && time <= UPPER_DOSTIME_BOUND) {
+            this.mtime = null;
+        } else {
+            this.mtime = FileTime.from(time, TimeUnit.MILLISECONDS);
+        }
     }
 
     /**
@@ -158,7 +188,10 @@
      * @see #setLastModifiedTime(FileTime)
      */
     public long getTime() {
-        return time;
+        if (mtime != null) {
+            return mtime.toMillis();
+        }
+        return (xdostime != -1) ? extendedDosToJavaTime(xdostime) : -1;
     }
 
     /**
@@ -181,7 +214,7 @@
      */
     public ZipEntry setLastModifiedTime(FileTime time) {
         this.mtime = Objects.requireNonNull(time, "lastModifiedTime");
-        this.time = time.to(TimeUnit.MILLISECONDS);
+        this.xdostime = javaToExtendedDosTime(time.to(TimeUnit.MILLISECONDS));
         return this;
     }
 
@@ -204,9 +237,9 @@
     public FileTime getLastModifiedTime() {
         if (mtime != null)
             return mtime;
-        if (time == -1)
+        if (xdostime == -1)
             return null;
-        return FileTime.from(time, TimeUnit.MILLISECONDS);
+        return FileTime.from(getTime(), TimeUnit.MILLISECONDS);
     }
 
     /**
--- a/src/java.base/share/classes/java/util/zip/ZipFile.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/zip/ZipFile.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, 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
@@ -46,7 +46,6 @@
 import java.util.stream.StreamSupport;
 
 import static java.util.zip.ZipConstants64.*;
-import static java.util.zip.ZipUtils.*;
 
 /**
  * This class is used to read entries from a zip file.
@@ -567,7 +566,7 @@
                 e.name = zc.toString(bname, bname.length);
             }
         }
-        e.time = dosToJavaTime(getEntryTime(jzentry));
+        e.xdostime = getEntryTime(jzentry);
         e.crc = getEntryCrc(jzentry);
         e.size = getEntrySize(jzentry);
         e.csize = getEntryCSize(jzentry);
--- a/src/java.base/share/classes/java/util/zip/ZipInputStream.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/zip/ZipInputStream.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -303,7 +303,7 @@
             throw new ZipException("encrypted ZIP entry not supported");
         }
         e.method = get16(tmpbuf, LOCHOW);
-        e.time = dosToJavaTime(get32(tmpbuf, LOCTIM));
+        e.xdostime = get32(tmpbuf, LOCTIM);
         if ((flag & 8) == 8) {
             /* "Data Descriptor" present */
             if (e.method != DEFLATED) {
--- a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -61,7 +61,6 @@
     private static class XEntry {
         final ZipEntry entry;
         final long offset;
-        long dostime;    // last modification time in msdos format
         public XEntry(ZipEntry entry, long offset) {
             this.entry = entry;
             this.offset = offset;
@@ -192,7 +191,7 @@
         if (current != null) {
             closeEntry();       // close previous entry
         }
-        if (e.time == -1) {
+        if (e.xdostime == -1) {
             // by default, do NOT use extended timestamps in extra
             // data, for now.
             e.setTime(System.currentTimeMillis());
@@ -389,18 +388,12 @@
         boolean hasZip64 = false;
         int elen = getExtraLen(e.extra);
 
-        // keep a copy of dostime for writeCEN(), otherwise the tz
-        // sensitive local time entries in loc and cen might be
-        // different if the default tz get changed during writeLOC()
-        // and writeCEN()
-        xentry.dostime = javaToDosTime(e.time);
-
         writeInt(LOCSIG);               // LOC header signature
         if ((flag & 8) == 8) {
             writeShort(version(e));     // version needed to extract
             writeShort(flag);           // general purpose bit flag
             writeShort(e.method);       // compression method
-            writeInt(xentry.dostime);   // last modification time
+            writeInt(e.xdostime);       // last modification time
             // store size, uncompressed size, and crc-32 in data descriptor
             // immediately following compressed entry data
             writeInt(0);
@@ -415,7 +408,7 @@
             }
             writeShort(flag);           // general purpose bit flag
             writeShort(e.method);       // compression method
-            writeInt(xentry.dostime);   // last modification time
+            writeInt(e.xdostime);       // last modification time
             writeInt(e.crc);            // crc-32
             if (hasZip64) {
                 writeInt(ZIP64_MAGICVAL);
@@ -522,9 +515,7 @@
         }
         writeShort(flag);           // general purpose bit flag
         writeShort(e.method);       // compression method
-        // use the copy in xentry, which has been converted
-        // from e.time in writeLOC()
-        writeInt(xentry.dostime);   // last modification time
+        writeInt(e.xdostime);       // last modification time
         writeInt(e.crc);            // crc-32
         writeInt(csize);            // compressed size
         writeInt(size);             // uncompressed size
--- a/src/java.base/share/classes/java/util/zip/ZipUtils.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -29,9 +29,6 @@
 import java.util.Date;
 import java.util.concurrent.TimeUnit;
 
-import static java.util.zip.ZipConstants.*;
-import static java.util.zip.ZipConstants64.*;
-
 class ZipUtils {
 
     // used to adjust values between Windows and java epoch
@@ -69,7 +66,7 @@
     /**
      * Converts DOS time to Java time (number of milliseconds since epoch).
      */
-    public static long dosToJavaTime(long dtime) {
+    private static long dosToJavaTime(long dtime) {
         @SuppressWarnings("deprecation") // Use of date constructor.
         Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
                           (int)(((dtime >> 21) & 0x0f) - 1),
@@ -81,14 +78,26 @@
     }
 
     /**
+     * Converts extended DOS time to Java time, where up to 1999 milliseconds
+     * might be encoded into the upper half of the returned long.
+     *
+     * @param xdostime the extended DOS time value
+     * @return milliseconds since epoch
+     */
+    public static long extendedDosToJavaTime(long xdostime) {
+        long time = dosToJavaTime(xdostime);
+        return time + (xdostime >> 32);
+    }
+
+    /**
      * Converts Java time to DOS time.
      */
     @SuppressWarnings("deprecation") // Use of date methods
-    public static long javaToDosTime(long time) {
+    private static long javaToDosTime(long time) {
         Date d = new Date(time);
         int year = d.getYear() + 1900;
         if (year < 1980) {
-            return (1 << 21) | (1 << 16);
+            return ZipEntry.DOSTIME_BEFORE_1980;
         }
         return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
                d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
@@ -96,6 +105,23 @@
     }
 
     /**
+     * Converts Java time to DOS time, encoding any milliseconds lost
+     * in the conversion into the upper half of the returned long.
+     *
+     * @param time milliseconds since epoch
+     * @return DOS time with 2s remainder encoded into upper half
+     */
+    public static long javaToExtendedDosTime(long time) {
+        if (time < 0) {
+            return ZipEntry.DOSTIME_BEFORE_1980;
+        }
+        long dostime = javaToDosTime(time);
+        return (dostime != ZipEntry.DOSTIME_BEFORE_1980)
+                ? dostime + ((time % 2000) << 32)
+                : ZipEntry.DOSTIME_BEFORE_1980;
+    }
+
+    /**
      * Fetches unsigned 16-bit value from byte array at specified offset.
      * The bytes are assumed to be in Intel (little-endian) byte order.
      */
--- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -321,12 +321,9 @@
     }
 
     public void sendUrgentData(int data) throws IOException {
-        synchronized (sc.blockingLock()) {
-            if (!sc.isBlocking())
-                throw new IllegalBlockingModeException();
-            int n = sc.sendOutOfBandData((byte)data);
-            assert n == 1;
-        }
+        int n = sc.sendOutOfBandData((byte) data);
+        if (n == 0)
+            throw new IOException("Socket buffer full");
     }
 
     public void setOOBInline(boolean on) throws SocketException {
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Mon Mar 02 10:09:03 2015 -0800
@@ -3790,6 +3790,17 @@
             PublicKey pkey,
             PublicKey akey) throws Exception {
 
+        // By design, inside a CertificateExtensions object, all known
+        // extensions uses name (say, "BasicConstraints") as key and
+        // a child Extension type (say, "BasicConstraintsExtension")
+        // as value, unknown extensions uses OID as key and bare
+        // Extension object as value. This works fine inside JDK.
+        //
+        // However, in keytool, there is no way to prevent people
+        // using OID in -ext, either as a new extension, or in a
+        // honored value. Thus here we (ab)use CertificateExtensions
+        // by always using OID as key and value can be of any type.
+
         if (existingEx != null && requestedEx != null) {
             // This should not happen
             throw new Exception("One of request and original should be null.");
@@ -3805,13 +3816,19 @@
             // name{:critical}{=value}
             // Honoring requested extensions
             if (requestedEx != null) {
+                // The existing requestedEx might use names as keys,
+                // translate to all-OID first.
+                CertificateExtensions request2 = new CertificateExtensions();
+                for (sun.security.x509.Extension ex: requestedEx.getAllExtensions()) {
+                    request2.set(ex.getId(), ex);
+                }
                 for(String extstr: extstrs) {
                     if (extstr.toLowerCase(Locale.ENGLISH).startsWith("honored=")) {
                         List<String> list = Arrays.asList(
                                 extstr.toLowerCase(Locale.ENGLISH).substring(8).split(","));
                         // First check existence of "all"
                         if (list.contains("all")) {
-                            for (Extension ex: requestedEx.getAllExtensions()) {
+                            for (Extension ex: request2.getAllExtensions()) {
                                 setExt(result, ex);
                             }
                         }
@@ -3844,7 +3861,7 @@
                             }
                             String n = findOidForExtName(type).toString();
                             if (add) {
-                                Extension e = requestedEx.get(n);
+                                Extension e = request2.get(n);
                                 if (!e.isCritical() && action == 0
                                         || e.isCritical() && action == 1) {
                                     e = Extension.newExtension(
--- a/src/java.base/windows/native/libjava/TimeZone_md.c	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/windows/native/libjava/TimeZone_md.c	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -195,7 +195,7 @@
          * Vista uses the different key name.
          */
         if (ret != ERROR_SUCCESS) {
-          bufSize = sizeof(val);
+            bufSize = sizeof(val);
             ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled",
                                    NULL, &valueType, (LPBYTE) &val, &bufSize);
         }
@@ -510,18 +510,49 @@
         } else {
             std_timezone = matchJavaTZ(java_home_dir, result,
                                        winZoneName, winMapID);
+            if (std_timezone == NULL) {
+                std_timezone = getGMTOffsetID();
+            }
         }
     }
-
     return std_timezone;
 }
 
 /**
- * Returns a GMT-offset-based time zone ID. On Win32, it always return
- * NULL since the fall back is performed in getWinTimeZone().
+ * Returns a GMT-offset-based time zone ID.
  */
 char *
 getGMTOffsetID()
 {
-    return NULL;
+    LONG bias = 0;
+    LONG ret;
+    HANDLE hKey = NULL;
+    char zonename[32];
+
+    // Obtain the current GMT offset value of ActiveTimeBias.
+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
+                       KEY_READ, (PHKEY)&hKey);
+    if (ret == ERROR_SUCCESS) {
+        DWORD val;
+        DWORD bufSize = sizeof(val);
+        ULONG valueType = 0;
+        ret = RegQueryValueExA(hKey, "ActiveTimeBias",
+                               NULL, &valueType, (LPBYTE) &val, &bufSize);
+        if (ret == ERROR_SUCCESS) {
+            bias = (LONG) val;
+        }
+        (void) RegCloseKey(hKey);
+    }
+
+    // If we can't get the ActiveTimeBias value, use Bias of TimeZoneInformation.
+    // Note: Bias doesn't reflect current daylight saving.
+    if (ret != ERROR_SUCCESS) {
+        TIME_ZONE_INFORMATION tzi;
+        if (GetTimeZoneInformation(&tzi) != TIME_ZONE_ID_INVALID) {
+            bias = tzi.Bias;
+        }
+    }
+
+    customZoneName(bias, zonename);
+    return _strdup(zonename);
 }
--- a/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c	Thu Feb 26 10:56:26 2015 -0800
+++ b/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c	Mon Mar 02 10:09:03 2015 -0800
@@ -325,17 +325,14 @@
 {
     BOOL result = 0;
     HANDLE h = (HANDLE)(handleval(env, fdo));
-    LARGE_INTEGER offset;
+    FILE_END_OF_FILE_INFO eofInfo;
 
-    offset.QuadPart = size;
-    result = SetFilePointerEx(h, offset, NULL, FILE_BEGIN);
-    if (result == 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
-        return IOS_THROWN;
-    }
-
-    result = SetEndOfFile(h);
-    if (result == 0) {
+    eofInfo.EndOfFile.QuadPart = size;
+    result = SetFileInformationByHandle(h,
+                                        FileEndOfFileInfo,
+                                        &eofInfo,
+                                        sizeof(eofInfo));
+    if (result == FALSE) {
         JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
         return IOS_THROWN;
     }
--- a/test/Makefile	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/Makefile	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2015, 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
@@ -112,6 +112,19 @@
   JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS)
 endif
 
+# jtreg -nativepath <dir>
+#
+# Local make tests will be TEST_IMAGE_DIR and JPRT with jprt.use.reg.test.bundle=true
+# should be JPRT_TESTNATIVE_PATH
+ifdef TEST_IMAGE_DIR
+  TESTNATIVE_DIR = $(TEST_IMAGE_DIR)
+else ifdef JPRT_TESTNATIVE_PATH
+  TESTNATIVE_DIR = $(JPRT_TESTNATIVE_PATH)
+endif
+ifdef TESTNATIVE_DIR
+  JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/jdk/jtreg/native")
+endif
+
 # Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
 ifdef JPRT_ARCHIVE_BUNDLE
   ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
@@ -313,6 +326,7 @@
               -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport")  \
               -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork")    \
               -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                \
+              $(JTREG_NATIVE_PATH)                                           \
               $(JTREG_EXCLUSIONS)                                            \
               $(JTREG_TEST_OPTIONS)                                          \
               $(TEST_SELECTION)                                                    \
--- a/test/TEST.groups	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/TEST.groups	Mon Mar 02 10:09:03 2015 -0800
@@ -168,6 +168,9 @@
 jdk_jdi = \
     com/sun/jdi
 
+jdk_native_sanity = \
+    native_sanity
+
 # java launcher specific tests, Note: do not include this group into any groups
 # that potentially could be included into a jprt test rule, as the complementary
 # closed  group includes awt SplashScreen and these tests may not run 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/CustomizedLambdaFormTest.java	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, 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.lang.invoke;
+
+/* @test
+ * @summary Assertion in LambdaFormEditor.bindArgumentType is too strong
+ *
+ * @run main/bootclasspath -esa java.lang.invoke.CustomizedLambdaFormTest
+ */
+public class CustomizedLambdaFormTest {
+
+    static void testExtendCustomizedBMH() throws Exception {
+        // Construct BMH
+        MethodHandle mh = MethodHandles.Lookup.IMPL_LOOKUP.findVirtual(String.class, "concat",
+                MethodType.methodType(String.class, String.class))
+                .bindTo("a");
+        mh.customize();
+        mh.bindTo("b"); // Try to extend customized BMH
+    }
+
+    public static void main(String[] args) throws Throwable {
+        testExtendCustomizedBMH();
+    }
+}
--- a/test/java/nio/channels/SocketChannel/OutOfBand.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/java/nio/channels/SocketChannel/OutOfBand.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -58,8 +58,6 @@
             test1(sc1, sc2);
             test2(sc1, sc2);
             test3(sc1, sc2);
-            test4(sc1);
-
         } finally {
             if (sc1 != null) sc1.close();
             if (sc2 != null) sc2.close();
@@ -175,17 +173,4 @@
 
         thr.join();
     }
-
-    static void test4(SocketChannel sc) throws IOException {
-        boolean blocking = sc.isBlocking();
-        sc.configureBlocking(false);
-        try {
-            sc.socket().sendUrgentData(0);
-            throw new RuntimeException("IllegalBlockingModeException expected");
-        } catch (IllegalBlockingModeException x) {
-            // expected
-        } finally {
-            sc.configureBlocking(blocking);
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/nio/channels/SocketChannel/SendUrgentData.java	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2015, 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
+ * @bug 8071599
+ * @run main/othervm SendUrgentData
+ * @run main/othervm SendUrgentData -inline
+ * @summary Test sending of urgent data.
+ */
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+public class SendUrgentData {
+
+    /**
+     * The arguments may be one of the following:
+     * <ol>
+     * <li>-server</li>
+     * <li>-client host port [-inline]</li>
+     * <li>[-inline]</li>
+     * </ol>
+     * The first option creates a standalone server, the second a standalone
+     * client, and the third a self-contained server-client pair on the
+     * local host.
+     *
+     * @param args
+     * @throws Exception
+     */
+    public static void main(String[] args) throws Exception {
+
+        ServerSocketChannelThread serverThread
+                = new ServerSocketChannelThread("SendUrgentDataServer");
+        serverThread.start();
+        boolean b = serverThread.isAlive();
+
+        String host = null;
+        int port = 0;
+        boolean inline = false;
+        if (args.length > 0 && args[0].equals("-server")) {
+            System.out.println(serverThread.getAddress());
+            Thread.currentThread().suspend();
+        } else {
+            if (args.length > 0 && args[0].equals("-client")) {
+                host = args[1];
+                port = Integer.parseInt(args[2]);
+                if (args.length > 3) {
+                    inline = args[2].equals("-inline");
+                }
+            } else {
+                host = "localhost";
+                port = serverThread.getAddress().getPort();
+                if (args.length > 0) {
+                    inline = args[0].equals("-inline");
+                }
+            }
+        }
+
+        System.out.println("OOB Inline : "+inline);
+
+        SocketAddress sa = new InetSocketAddress(host, port);
+
+        try (SocketChannel sc = SocketChannel.open(sa)) {
+            sc.configureBlocking(false);
+            sc.socket().setOOBInline(inline);
+
+            sc.socket().sendUrgentData(0);
+            System.out.println("wrote 1 OOB byte");
+
+            ByteBuffer bb = ByteBuffer.wrap(new byte[100 * 1000]);
+
+            int blocked = 0;
+            long total = 0;
+
+            int n;
+            do {
+                n = sc.write(bb);
+                if (n == 0) {
+                    System.out.println("blocked, wrote " + total + " so far");
+                    if (++blocked == 10) {
+                        break;
+                    }
+                    Thread.sleep(100);
+                } else {
+                    total += n;
+                    bb.rewind();
+                }
+            } while (n > 0);
+
+            long attempted = 0;
+            while (attempted < total) {
+                bb.rewind();
+                n = sc.write(bb);
+                System.out.println("wrote " + n + " normal bytes");
+                attempted += bb.capacity();
+
+                String osName = System.getProperty("os.name").toLowerCase();
+
+                try {
+                    sc.socket().sendUrgentData(0);
+                } catch (IOException ex) {
+                    if (osName.contains("linux")) {
+                        if (!ex.getMessage().contains("Socket buffer full")) {
+                            throw new RuntimeException("Unexpected message", ex);
+                        }
+                    } else if (osName.contains("os x") || osName.contains("mac")) {
+                        if (!ex.getMessage().equals("No buffer space available")) {
+                            throw new RuntimeException("Unexpected message", ex);
+                        }
+                    } else if (osName.contains("windows")) {
+                        if (!(ex instanceof SocketException)) {
+                            throw new RuntimeException("Unexpected exception", ex);
+                        } else if (!ex.getMessage().contains("Resource temporarily unavailable")) {
+                            throw new RuntimeException("Unexpected message", ex);
+                        }
+                    } else {
+                        throw new RuntimeException("Unexpected IOException", ex);
+                    }
+                }
+
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException ex) {
+                    // don't want to fail on this so just print trace and break
+                    ex.printStackTrace();
+                    break;
+                }
+            }
+        } finally {
+            serverThread.close();
+        }
+    }
+
+    static class ServerSocketChannelThread extends Thread {
+
+        private ServerSocketChannel ssc;
+
+        private ServerSocketChannelThread(String name) {
+            super(name);
+            try {
+                ssc = ServerSocketChannel.open();
+                ssc.bind(new InetSocketAddress((0)));
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        public void run() {
+            while (ssc.isOpen()) {
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+            try {
+                ssc.close();
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+            System.out.println("ServerSocketChannelThread exiting ...");
+        }
+
+        public InetSocketAddress getAddress() throws IOException {
+            if (ssc == null) {
+                throw new IllegalStateException("ServerSocketChannel not created");
+            }
+
+            return (InetSocketAddress) ssc.getLocalAddress();
+        }
+
+        public void close() {
+            try {
+                ssc.close();
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+}
--- a/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -23,41 +23,63 @@
 
 /*
  * @test
- * @bug 4777124 6920545 6911753
+ * @bug 4777124 6920545 6911753 8073924
  * @summary Verify that all Charset subclasses are available through the API
  */
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
+import java.net.URI;
 import java.nio.charset.Charset;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Collection;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Set;
-import java.util.Vector;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 public class NIOCharsetAvailabilityTest {
 
     public static void main(String[] args) throws Exception {
+
         // build the set of all Charset subclasses in the
         // two known charset implementation packages
-        Set charsets = new HashSet();
-        addCharsets(charsets, "sun.nio.cs");
-        addCharsets(charsets, "sun.nio.cs.ext");
-
+        FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
+        Set<Class> charsets =
+            Stream.concat(Files.walk(fs.getPath("/java.base/sun/nio/cs/")),
+                          Files.walk(fs.getPath("/jdk.charsets/sun/nio/cs/ext/")))
+                 .map( p -> p.subpath(1, p.getNameCount()).toString())
+                 .filter( s ->  s.indexOf("$") == -1 && s.endsWith(".class"))
+                 .map( s -> {
+                     try {
+                         return Class.forName(s.substring(0, s.length() - 6)
+                                               .replace('/', '.'));
+                     } catch (Exception x) {
+                         throw new RuntimeException(x);
+                     }
+                  })
+                 .filter( clz -> {
+                     Class superclazz = clz.getSuperclass();
+                     while (superclazz != null && !superclazz.equals(Object.class)) {
+                         if (superclazz.equals(Charset.class)) {
+                             return true;
+                         } else {
+                             superclazz = superclazz.getSuperclass();
+                         }
+                     }
+                     return false;
+                  })
+                 .collect(Collectors.toCollection(HashSet::new));
         // remove the charsets that the API says are available
-        Collection availableCharsets = Charset.availableCharsets().values();
-        Iterator iter = availableCharsets.iterator();
-        while (iter.hasNext()) {
-            charsets.remove(((Charset) iter.next()).getClass());
-        }
+        Charset.availableCharsets()
+               .values()
+               .stream()
+               .forEach(cs -> {
+                   if (!charsets.contains(cs.getClass())) {
+                       System.out.println(" missing -> " + cs.getClass());
+                   }
+                   charsets.remove(cs.getClass());
+                });
 
         // remove the known pseudo-charsets that serve only to implement
         // other charsets, but shouldn't be known to the public
@@ -76,146 +98,12 @@
             charsets.remove(Class.forName("sun.nio.cs.JIS_X_0208_Solaris"));
             charsets.remove(Class.forName("sun.nio.cs.JIS_X_0212_Solaris"));
         }
-
         // report the charsets that are implemented but not available
-        iter = charsets.iterator();
-        while (iter.hasNext()) {
-            System.out.println("Unused Charset subclass: " + ((Class) iter.next()).getName());
-        }
         if (charsets.size() > 0) {
+            charsets.stream()
+                    .forEach( clz ->
+                        System.out.println("Unused Charset subclass: " + clz));
             throw new RuntimeException();
         }
     }
-
-    private static Vector classPathSegments = new Vector();
-
-    private static void addCharsets(Set charsets, final String packageName)
-            throws Exception {
-
-        String classPath = AccessController.doPrivileged(
-             (PrivilegedAction<String>)() -> System.getProperty("sun.boot.class.path"));
-        String s = AccessController.doPrivileged(
-             (PrivilegedAction<String>)() -> System.getProperty("java.class.path"));
-
-        // Search combined system and application class path
-        if (s != null && s.length() != 0) {
-            classPath += File.pathSeparator + s;
-        }
-        while (classPath != null && classPath.length() != 0) {
-            int i = classPath.lastIndexOf(java.io.File.pathSeparatorChar);
-            String dir = classPath.substring(i + 1);
-            if (i == -1) {
-                classPath = null;
-            } else {
-                classPath = classPath.substring(0, i);
-            }
-            classPathSegments.insertElementAt(dir, 0);
-        }
-
-        String[] classList = (String[])
-            java.security.AccessController.doPrivileged(
-                                    new java.security.PrivilegedAction() {
-                public Object run() {
-                    return getClassList(packageName, "");
-                }
-            });
-
-        for (int i = 0; i < classList.length; i++) {
-            try {
-                Class clazz = Class.forName(packageName + "." + classList[i]);
-                Class superclazz = clazz.getSuperclass();
-                while (superclazz != null && !superclazz.equals(Object.class)) {
-                    if (superclazz.equals(Charset.class)) {
-                        charsets.add(clazz);
-                        break;
-                    } else {
-                        superclazz = superclazz.getSuperclass();
-                    }
-                }
-            } catch (ClassNotFoundException e) {
-            }
-        }
-    }
-
-    private static final char ZIPSEPARATOR = '/';
-
-    /**
-     * Walk through CLASSPATH and find class list from a package.
-     * The class names start with prefix string
-     * @param package name, class name prefix
-     * @return class list in an array of String
-     */
-    private static String[] getClassList(String pkgName, String prefix) {
-        Vector listBuffer = new Vector();
-        String packagePath = pkgName.replace('.', File.separatorChar)
-            + File.separatorChar;
-        String zipPackagePath = pkgName.replace('.', ZIPSEPARATOR)
-            + ZIPSEPARATOR;
-        for (int i = 0; i < classPathSegments.size(); i++){
-            String onePath = (String) classPathSegments.elementAt(i);
-            File f = new File(onePath);
-            if (!f.exists())
-                continue;
-            if (f.isFile())
-                scanFile(f, zipPackagePath, listBuffer, prefix);
-            else if (f.isDirectory()) {
-                String fullPath;
-                if (onePath.endsWith(File.separator))
-                    fullPath = onePath + packagePath;
-                else
-                    fullPath = onePath + File.separatorChar + packagePath;
-                File dir = new File(fullPath);
-                if (dir.exists() && dir.isDirectory())
-                    scanDir(dir, listBuffer, prefix);
-            }
-        }
-        String[] classNames = new String[listBuffer.size()];
-        listBuffer.copyInto(classNames);
-        return classNames;
-    }
-
-    private static void addClass (String className, Vector listBuffer, String prefix) {
-        if (className != null && className.startsWith(prefix)
-                    && !listBuffer.contains(className))
-            listBuffer.addElement(className);
-    }
-
-    private static String midString(String str, String pre, String suf) {
-        String midStr;
-        if (str.startsWith(pre) && str.endsWith(suf))
-            midStr = str.substring(pre.length(), str.length() - suf.length());
-        else
-            midStr = null;
-        return midStr;
-    }
-
-    private static void scanDir(File dir, Vector listBuffer, String prefix) {
-        String[] fileList = dir.list();
-        for (int i = 0; i < fileList.length; i++) {
-            addClass(midString(fileList[i], "", ".class"), listBuffer, prefix);
-        }
-    }
-
-    private static void scanFile(File f, String packagePath, Vector listBuffer,
-                String prefix) {
-        try {
-            ZipInputStream zipFile = new ZipInputStream(new FileInputStream(f));
-            ZipEntry entry;
-            while ((entry = zipFile.getNextEntry()) != null) {
-                String eName = entry.getName();
-                if (eName.startsWith(packagePath)) {
-                    if (eName.endsWith(".class")) {
-                        addClass(midString(eName, packagePath, ".class"),
-                                listBuffer, prefix);
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-            System.out.println("file not found:" + e);
-        } catch (IOException e) {
-            System.out.println("file IO Exception:" + e);
-        } catch (Exception e) {
-            System.out.println("Exception:" + e);
-        }
-    }
 }
--- a/test/java/time/test/java/time/TestInstant.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/java/time/test/java/time/TestInstant.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -62,6 +62,8 @@
 import java.time.Instant;
 
 import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertEquals;
 
 /**
  * Test Instant.
@@ -74,4 +76,24 @@
         assertImmutable(Instant.class);
     }
 
+    @DataProvider(name="sampleEpochMillis")
+    private Object[][] provider_sampleEpochMillis() {
+        return new Object[][] {
+            {"Long.MAX_VALUE", Long.MAX_VALUE},
+            {"Long.MAX_VALUE-1", Long.MAX_VALUE - 1},
+            {"1", 1L},
+            {"0", 0L},
+            {"-1", -1L},
+            {"Long.MIN_VALUE+1", Long.MIN_VALUE + 1},
+            {"Long.MIN_VALUE", Long.MIN_VALUE}
+        };
+    }
+
+    @Test(dataProvider="sampleEpochMillis")
+    public void test_epochMillis(String name, long millis) {
+        Instant t1 = Instant.ofEpochMilli(millis);
+        long m = t1.toEpochMilli();
+        assertEquals(millis, m, name);
+    }
+
 }
--- a/test/java/util/Arrays/TimSortStackSize2.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/java/util/Arrays/TimSortStackSize2.java	Mon Mar 02 10:09:03 2015 -0800
@@ -24,63 +24,59 @@
 /*
  * @test
  * @bug 8072909
- * @run main/othervm -Xmx385m TimSortStackSize2 67108864
- * not for regular execution on all platforms:
+ * @run main/othervm -Xms385m TimSortStackSize2 67108864
+ * @summary Test TimSort stack size on big arrays
+ * big tests not for regular execution on all platforms:
  * run main/othervm -Xmx8g TimSortStackSize2 1073741824
  * run main/othervm -Xmx16g TimSortStackSize2 2147483644
- * @summary Test TimSort stack size on big arrays
  */
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
+import java.util.function.Consumer;
 
 public class TimSortStackSize2 {
 
     public static void main(String[] args) {
         int lengthOfTest = Integer.parseInt(args[0]);
-        boolean passed = true;
-        try {
-            Integer [] a = new TimSortStackSize2(lengthOfTest).createArray();
-            long begin = System.nanoTime();
-            Arrays.sort(a, new Comparator<Object>() {
-                    @SuppressWarnings("unchecked")
-                    public int compare(Object first, Object second) {
-                        return ((Comparable<Object>)first).compareTo(second);
-                    }
-                });
-            long end = System.nanoTime();
-            System.out.println("TimSort: " + (end - begin));
-            a = null;
-        } catch (ArrayIndexOutOfBoundsException e){
-            System.out.println("TimSort broken:");
-            e.printStackTrace();
-            passed = false;
-        }
-
-        try {
-            Integer [] a = new TimSortStackSize2(lengthOfTest).createArray();
-            long begin = System.nanoTime();
-            Arrays.sort(a);
-            long end = System.nanoTime();
-            System.out.println("ComparableTimSort: " + (end - begin));
-            a = null;
-        } catch (ArrayIndexOutOfBoundsException e){
-            System.out.println("ComparableTimSort broken:");
-            e.printStackTrace();
-            passed = false;
-        }
+        boolean passed = doTest("TimSort", lengthOfTest,
+            (Integer [] a) -> Arrays.sort(a));
+        passed = doTest("ComparableTimSort", lengthOfTest, (Integer [] a) ->
+            Arrays.sort(a, (Object first, Object second) -> {
+                return ((Comparable<Object>)first).compareTo(second);
+            }))
+            && passed;
         if ( !passed ){
             throw new RuntimeException();
         }
     }
 
+    private static boolean doTest(final String msg, final int lengthOfTest,
+                                  final  Consumer<Integer[]> c){
+        Integer [] a = null;
+        try {
+            a = new TimSortStackSize2(lengthOfTest).createArray();
+            long begin = System.nanoTime();
+            c.accept(a);
+            long end = System.nanoTime();
+            System.out.println(msg + " OK. Time: " + (end - begin) + "ns");
+        } catch (ArrayIndexOutOfBoundsException e){
+            System.out.println(msg + " broken:");
+            e.printStackTrace();
+            return false;
+        } finally {
+            a = null;
+        }
+        return true;
+    }
+
     private static final int MIN_MERGE = 32;
     private final int minRun;
     private final int length;
     private final List<Long> runs = new ArrayList<Long>();
 
-    public TimSortStackSize2(int len) {
+    public TimSortStackSize2(final int len) {
         this.length = len;
         minRun = minRunLength(len);
         fillRunsJDKWorstCase();
@@ -106,24 +102,24 @@
      * @param X  The sum of the sequence that should be added to runs.
      */
     private void generateJDKWrongElem(long X) {
-        for(long newTotal; X >= 2*minRun+1; X = newTotal) {
+        for(long newTotal; X >= 2 * minRun + 1; X = newTotal) {
             //Default strategy
-            newTotal = X/2 + 1;
+            newTotal = X / 2 + 1;
             //Specialized strategies
-            if(3*minRun+3 <= X && X <= 4*minRun+1) {
+            if(3 * minRun + 3 <= X && X <= 4*minRun+1) {
                 // add x_1=MIN+1, x_2=MIN, x_3=X-newTotal  to runs
-                newTotal = 2*minRun+1;
-            } else if(5*minRun+5 <= X && X <= 6*minRun+5) {
+                newTotal = 2 * minRun + 1;
+            } else if (5 * minRun + 5 <= X && X <= 6 * minRun + 5) {
                 // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=X-newTotal  to runs
-                newTotal = 3*minRun+3;
-            } else if(8*minRun+9 <= X && X <= 10*minRun+9) {
+                newTotal = 3 * minRun + 3;
+            } else if (8 * minRun + 9 <= X && X <= 10 * minRun + 9) {
                 // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=X-newTotal  to runs
-                newTotal = 5*minRun+5;
-            } else if(13*minRun+15 <= X && X <= 16*minRun+17) {
+                newTotal = 5 * minRun + 5;
+            } else if (13 * minRun + 15 <= X && X <= 16 * minRun + 17) {
                 // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=3MIN+4, x_6=X-newTotal  to runs
-                newTotal = 8*minRun+9;
+                newTotal = 8 * minRun + 9;
             }
-            runs.add(0, X-newTotal);
+            runs.add(0, X - newTotal);
         }
         runs.add(0, X);
     }
@@ -144,10 +140,10 @@
         long Y = minRun + 4;
         long X = minRun;
 
-        while(runningTotal+Y+X <= length) {
+        while (runningTotal + Y + X <= length) {
             runningTotal += X + Y;
             generateJDKWrongElem(X);
-            runs.add(0,Y);
+            runs.add(0, Y);
 
             // X_{i+1} = Y_i + x_{i,1} + 1, since runs.get(1) = x_{i,1}
             X = Y + runs.get(1) + 1;
@@ -156,21 +152,22 @@
             Y += X + 1;
         }
 
-        if(runningTotal + X <= length) {
+        if (runningTotal + X <= length) {
             runningTotal += X;
             generateJDKWrongElem(X);
         }
 
-        runs.add(length-runningTotal);
+        runs.add(length - runningTotal);
     }
 
-    private Integer[] createArray() {
-        Integer[] a = new Integer[length];
+    private Integer [] createArray() {
+        Integer [] a = new Integer[length];
         Arrays.fill(a, 0);
         int endRun = -1;
-        for(long len : runs)
-            a[endRun+=len] = 1;
-        a[length-1]=0;
+        for (long len : runs) {
+            a[endRun += len] = 1;
+        }
+        a[length - 1] = 0;
         return a;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,701 @@
+/*
+ * Copyright (c) 2012, 2015, 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.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamOpFlagTestHelper;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
+
+import org.testng.annotations.Test;
+
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.flatMapping;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.groupingByConcurrent;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.partitioningBy;
+import static java.util.stream.Collectors.reducing;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toConcurrentMap;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+import static java.util.stream.LambdaTestHelpers.assertContents;
+import static java.util.stream.LambdaTestHelpers.assertContentsUnordered;
+import static java.util.stream.LambdaTestHelpers.mDoubler;
+
+/*
+ * @test
+ * @bug 8071600
+ * @summary Test for collectors.
+ */
+public class CollectorsTest extends OpTestCase {
+
+    private static abstract class CollectorAssertion<T, U> {
+        abstract void assertValue(U value,
+                                  Supplier<Stream<T>> source,
+                                  boolean ordered) throws ReflectiveOperationException;
+    }
+
+    static class MappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
+        private final Function<T, V> mapper;
+        private final CollectorAssertion<V, R> downstream;
+
+        MappingAssertion(Function<T, V> mapper, CollectorAssertion<V, R> downstream) {
+            this.mapper = mapper;
+            this.downstream = downstream;
+        }
+
+        @Override
+        void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
+            downstream.assertValue(value,
+                                   () -> source.get().map(mapper::apply),
+                                   ordered);
+        }
+    }
+
+    static class FlatMappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
+        private final Function<T, Stream<V>> mapper;
+        private final CollectorAssertion<V, R> downstream;
+
+        FlatMappingAssertion(Function<T, Stream<V>> mapper,
+                             CollectorAssertion<V, R> downstream) {
+            this.mapper = mapper;
+            this.downstream = downstream;
+        }
+
+        @Override
+        void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
+            downstream.assertValue(value,
+                                   () -> source.get().flatMap(mapper::apply),
+                                   ordered);
+        }
+    }
+
+    static class GroupingByAssertion<T, K, V, M extends Map<K, ? extends V>> extends CollectorAssertion<T, M> {
+        private final Class<? extends Map> clazz;
+        private final Function<T, K> classifier;
+        private final CollectorAssertion<T,V> downstream;
+
+        GroupingByAssertion(Function<T, K> classifier, Class<? extends Map> clazz,
+                            CollectorAssertion<T, V> downstream) {
+            this.clazz = clazz;
+            this.classifier = classifier;
+            this.downstream = downstream;
+        }
+
+        @Override
+        void assertValue(M map,
+                         Supplier<Stream<T>> source,
+                         boolean ordered) throws ReflectiveOperationException {
+            if (!clazz.isAssignableFrom(map.getClass()))
+                fail(String.format("Class mismatch in GroupingByAssertion: %s, %s", clazz, map.getClass()));
+            assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(toSet()));
+            for (Map.Entry<K, ? extends V> entry : map.entrySet()) {
+                K key = entry.getKey();
+                downstream.assertValue(entry.getValue(),
+                                       () -> source.get().filter(e -> classifier.apply(e).equals(key)),
+                                       ordered);
+            }
+        }
+    }
+
+    static class ToMapAssertion<T, K, V, M extends Map<K,V>> extends CollectorAssertion<T, M> {
+        private final Class<? extends Map> clazz;
+        private final Function<T, K> keyFn;
+        private final Function<T, V> valueFn;
+        private final BinaryOperator<V> mergeFn;
+
+        ToMapAssertion(Function<T, K> keyFn,
+                       Function<T, V> valueFn,
+                       BinaryOperator<V> mergeFn,
+                       Class<? extends Map> clazz) {
+            this.clazz = clazz;
+            this.keyFn = keyFn;
+            this.valueFn = valueFn;
+            this.mergeFn = mergeFn;
+        }
+
+        @Override
+        void assertValue(M map, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
+            if (!clazz.isAssignableFrom(map.getClass()))
+                fail(String.format("Class mismatch in ToMapAssertion: %s, %s", clazz, map.getClass()));
+            Set<K> uniqueKeys = source.get().map(keyFn).collect(toSet());
+            assertEquals(uniqueKeys, map.keySet());
+            source.get().forEach(t -> {
+                K key = keyFn.apply(t);
+                V v = source.get()
+                            .filter(e -> key.equals(keyFn.apply(e)))
+                            .map(valueFn)
+                            .reduce(mergeFn)
+                            .get();
+                assertEquals(map.get(key), v);
+            });
+        }
+    }
+
+    static class PartitioningByAssertion<T, D> extends CollectorAssertion<T, Map<Boolean,D>> {
+        private final Predicate<T> predicate;
+        private final CollectorAssertion<T,D> downstream;
+
+        PartitioningByAssertion(Predicate<T> predicate, CollectorAssertion<T, D> downstream) {
+            this.predicate = predicate;
+            this.downstream = downstream;
+        }
+
+        @Override
+        void assertValue(Map<Boolean, D> map,
+                         Supplier<Stream<T>> source,
+                         boolean ordered) throws ReflectiveOperationException {
+            if (!Map.class.isAssignableFrom(map.getClass()))
+                fail(String.format("Class mismatch in PartitioningByAssertion: %s", map.getClass()));
+            assertEquals(2, map.size());
+            downstream.assertValue(map.get(true), () -> source.get().filter(predicate), ordered);
+            downstream.assertValue(map.get(false), () -> source.get().filter(predicate.negate()), ordered);
+        }
+    }
+
+    static class ToListAssertion<T> extends CollectorAssertion<T, List<T>> {
+        @Override
+        void assertValue(List<T> value, Supplier<Stream<T>> source, boolean ordered)
+                throws ReflectiveOperationException {
+            if (!List.class.isAssignableFrom(value.getClass()))
+                fail(String.format("Class mismatch in ToListAssertion: %s", value.getClass()));
+            Stream<T> stream = source.get();
+            List<T> result = new ArrayList<>();
+            for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
+                result.add(it.next());
+            if (StreamOpFlagTestHelper.isStreamOrdered(stream) && ordered)
+                assertContents(value, result);
+            else
+                assertContentsUnordered(value, result);
+        }
+    }
+
+    static class ToCollectionAssertion<T> extends CollectorAssertion<T, Collection<T>> {
+        private final Class<? extends Collection> clazz;
+        private final boolean targetOrdered;
+
+        ToCollectionAssertion(Class<? extends Collection> clazz, boolean targetOrdered) {
+            this.clazz = clazz;
+            this.targetOrdered = targetOrdered;
+        }
+
+        @Override
+        void assertValue(Collection<T> value, Supplier<Stream<T>> source, boolean ordered)
+                throws ReflectiveOperationException {
+            if (!clazz.isAssignableFrom(value.getClass()))
+                fail(String.format("Class mismatch in ToCollectionAssertion: %s, %s", clazz, value.getClass()));
+            Stream<T> stream = source.get();
+            Collection<T> result = clazz.newInstance();
+            for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
+                result.add(it.next());
+            if (StreamOpFlagTestHelper.isStreamOrdered(stream) && targetOrdered && ordered)
+                assertContents(value, result);
+            else
+                assertContentsUnordered(value, result);
+        }
+    }
+
+    static class ReducingAssertion<T, U> extends CollectorAssertion<T, U> {
+        private final U identity;
+        private final Function<T, U> mapper;
+        private final BinaryOperator<U> reducer;
+
+        ReducingAssertion(U identity, Function<T, U> mapper, BinaryOperator<U> reducer) {
+            this.identity = identity;
+            this.mapper = mapper;
+            this.reducer = reducer;
+        }
+
+        @Override
+        void assertValue(U value, Supplier<Stream<T>> source, boolean ordered)
+                throws ReflectiveOperationException {
+            Optional<U> reduced = source.get().map(mapper).reduce(reducer);
+            if (value == null)
+                assertTrue(!reduced.isPresent());
+            else if (!reduced.isPresent()) {
+                assertEquals(value, identity);
+            }
+            else {
+                assertEquals(value, reduced.get());
+            }
+        }
+    }
+
+    private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) {
+        return (act, exp, ord, par) -> {
+            if (par && (!ordered || !ord)) {
+                CollectorsTest.nestedMapEqualityAssertion(act, exp);
+            }
+            else {
+                LambdaTestHelpers.assertContentsEqual(act, exp);
+            }
+        };
+    }
+
+    private<T, M extends Map>
+    void exerciseMapCollection(TestData<T, Stream<T>> data,
+                               Collector<T, ?, ? extends M> collector,
+                               CollectorAssertion<T, M> assertion)
+            throws ReflectiveOperationException {
+        boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
+
+        M m = withData(data)
+                .terminal(s -> s.collect(collector))
+                .resultAsserter(mapTabulationAsserter(ordered))
+                .exercise();
+        assertion.assertValue(m, () -> data.stream(), ordered);
+
+        m = withData(data)
+                .terminal(s -> s.unordered().collect(collector))
+                .resultAsserter(mapTabulationAsserter(ordered))
+                .exercise();
+        assertion.assertValue(m, () -> data.stream(), false);
+    }
+
+    private static void nestedMapEqualityAssertion(Object o1, Object o2) {
+        if (o1 instanceof Map) {
+            Map m1 = (Map) o1;
+            Map m2 = (Map) o2;
+            assertContentsUnordered(m1.keySet(), m2.keySet());
+            for (Object k : m1.keySet())
+                nestedMapEqualityAssertion(m1.get(k), m2.get(k));
+        }
+        else if (o1 instanceof Collection) {
+            assertContentsUnordered(((Collection) o1), ((Collection) o2));
+        }
+        else
+            assertEquals(o1, o2);
+    }
+
+    private<T, R> void assertCollect(TestData.OfRef<T> data,
+                                     Collector<T, ?, R> collector,
+                                     Function<Stream<T>, R> streamReduction) {
+        R check = streamReduction.apply(data.stream());
+        withData(data).terminal(s -> s.collect(collector)).expectedResult(check).exercise();
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testReducing(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        assertCollect(data, Collectors.reducing(0, Integer::sum),
+                      s -> s.reduce(0, Integer::sum));
+        assertCollect(data, Collectors.reducing(Integer.MAX_VALUE, Integer::min),
+                      s -> s.min(Integer::compare).orElse(Integer.MAX_VALUE));
+        assertCollect(data, Collectors.reducing(Integer.MIN_VALUE, Integer::max),
+                      s -> s.max(Integer::compare).orElse(Integer.MIN_VALUE));
+
+        assertCollect(data, Collectors.reducing(Integer::sum),
+                      s -> s.reduce(Integer::sum));
+        assertCollect(data, Collectors.minBy(Comparator.naturalOrder()),
+                      s -> s.min(Integer::compare));
+        assertCollect(data, Collectors.maxBy(Comparator.naturalOrder()),
+                      s -> s.max(Integer::compare));
+
+        assertCollect(data, Collectors.reducing(0, x -> x*2, Integer::sum),
+                      s -> s.map(x -> x*2).reduce(0, Integer::sum));
+
+        assertCollect(data, Collectors.summingLong(x -> x * 2L),
+                      s -> s.map(x -> x*2L).reduce(0L, Long::sum));
+        assertCollect(data, Collectors.summingInt(x -> x * 2),
+                      s -> s.map(x -> x*2).reduce(0, Integer::sum));
+        assertCollect(data, Collectors.summingDouble(x -> x * 2.0d),
+                      s -> s.map(x -> x * 2.0d).reduce(0.0d, Double::sum));
+
+        assertCollect(data, Collectors.averagingInt(x -> x * 2),
+                      s -> s.mapToInt(x -> x * 2).average().orElse(0));
+        assertCollect(data, Collectors.averagingLong(x -> x * 2),
+                      s -> s.mapToLong(x -> x * 2).average().orElse(0));
+        assertCollect(data, Collectors.averagingDouble(x -> x * 2),
+                      s -> s.mapToDouble(x -> x * 2).average().orElse(0));
+
+        // Test explicit Collector.of
+        Collector<Integer, long[], Double> avg2xint = Collector.of(() -> new long[2],
+                                                                   (a, b) -> {
+                                                                       a[0] += b * 2;
+                                                                       a[1]++;
+                                                                   },
+                                                                   (a, b) -> {
+                                                                       a[0] += b[0];
+                                                                       a[1] += b[1];
+                                                                       return a;
+                                                                   },
+                                                                   a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]);
+        assertCollect(data, avg2xint,
+                      s -> s.mapToInt(x -> x * 2).average().orElse(0));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testJoining(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        withData(data)
+                .terminal(s -> s.map(Object::toString).collect(Collectors.joining()))
+                .expectedResult(join(data, ""))
+                .exercise();
+
+        Collector<String, StringBuilder, String> likeJoining = Collector.of(StringBuilder::new, StringBuilder::append, (sb1, sb2) -> sb1.append(sb2.toString()), StringBuilder::toString);
+        withData(data)
+                .terminal(s -> s.map(Object::toString).collect(likeJoining))
+                .expectedResult(join(data, ""))
+                .exercise();
+
+        withData(data)
+                .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",")))
+                .expectedResult(join(data, ","))
+                .exercise();
+
+        withData(data)
+                .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",", "[", "]")))
+                .expectedResult("[" + join(data, ",") + "]")
+                .exercise();
+
+        withData(data)
+                .terminal(s -> s.map(Object::toString)
+                                .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
+                                .toString())
+                .expectedResult(join(data, ""))
+                .exercise();
+
+        withData(data)
+                .terminal(s -> s.map(Object::toString)
+                                .collect(() -> new StringJoiner(","),
+                                         (sj, cs) -> sj.add(cs),
+                                         (j1, j2) -> j1.merge(j2))
+                                .toString())
+                .expectedResult(join(data, ","))
+                .exercise();
+
+        withData(data)
+                .terminal(s -> s.map(Object::toString)
+                                .collect(() -> new StringJoiner(",", "[", "]"),
+                                         (sj, cs) -> sj.add(cs),
+                                         (j1, j2) -> j1.merge(j2))
+                                .toString())
+                .expectedResult("[" + join(data, ",") + "]")
+                .exercise();
+    }
+
+    private<T> String join(TestData.OfRef<T> data, String delim) {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (T i : data) {
+            if (!first)
+                sb.append(delim);
+            sb.append(i.toString());
+            first = false;
+        }
+        return sb.toString();
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSimpleToMap(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> keyFn = i -> i * 2;
+        Function<Integer, Integer> valueFn = i -> i * 4;
+
+        List<Integer> dataAsList = Arrays.asList(data.stream().toArray(Integer[]::new));
+        Set<Integer> dataAsSet = new HashSet<>(dataAsList);
+
+        BinaryOperator<Integer> sum = Integer::sum;
+        for (BinaryOperator<Integer> op : Arrays.asList((u, v) -> u,
+                                                        (u, v) -> v,
+                                                        sum)) {
+            try {
+                exerciseMapCollection(data, toMap(keyFn, valueFn),
+                                      new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class));
+                if (dataAsList.size() != dataAsSet.size())
+                    fail("Expected ISE on input with duplicates");
+            }
+            catch (IllegalStateException e) {
+                if (dataAsList.size() == dataAsSet.size())
+                    fail("Expected no ISE on input without duplicates");
+            }
+
+            exerciseMapCollection(data, toMap(keyFn, valueFn, op),
+                                  new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class));
+
+            exerciseMapCollection(data, toMap(keyFn, valueFn, op, TreeMap::new),
+                                  new ToMapAssertion<>(keyFn, valueFn, op, TreeMap.class));
+        }
+
+        // For concurrent maps, only use commutative merge functions
+        try {
+            exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn),
+                                  new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class));
+            if (dataAsList.size() != dataAsSet.size())
+                fail("Expected ISE on input with duplicates");
+        }
+        catch (IllegalStateException e) {
+            if (dataAsList.size() == dataAsSet.size())
+                fail("Expected no ISE on input without duplicates");
+        }
+
+        exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn, sum),
+                              new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class));
+
+        exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn, sum, ConcurrentSkipListMap::new),
+                              new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentSkipListMap.class));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSimpleGroupingBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+
+        // Single-level groupBy
+        exerciseMapCollection(data, groupingBy(classifier),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new ToListAssertion<>()));
+        exerciseMapCollection(data, groupingByConcurrent(classifier),
+                              new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ToListAssertion<>()));
+
+        // With explicit constructors
+        exerciseMapCollection(data,
+                              groupingBy(classifier, TreeMap::new, toCollection(HashSet::new)),
+                              new GroupingByAssertion<>(classifier, TreeMap.class,
+                                                        new ToCollectionAssertion<Integer>(HashSet.class, false)));
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new,
+                                                   toCollection(HashSet::new)),
+                              new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new ToCollectionAssertion<Integer>(HashSet.class, false)));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testGroupingByWithMapping(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+        Function<Integer, Integer> mapper = i -> i * 2;
+
+        exerciseMapCollection(data,
+                              groupingBy(classifier, mapping(mapper, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new MappingAssertion<>(mapper,
+                                                                               new ToListAssertion<>())));
+    }
+
+    @Test
+    public void testFlatMappingClose() {
+        Function<Integer, Integer> classifier = i -> i;
+        AtomicInteger ai = new AtomicInteger();
+        Function<Integer, Stream<Integer>> flatMapper = i -> Stream.of(i, i).onClose(ai::getAndIncrement);
+        Map<Integer, List<Integer>> m = Stream.of(1, 2).collect(groupingBy(classifier, flatMapping(flatMapper, toList())));
+        assertEquals(m.size(), ai.get());
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testGroupingByWithFlatMapping(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+        Function<Integer, Stream<Integer>> flatMapperByNull = i -> null;
+        Function<Integer, Stream<Integer>> flatMapperBy0 = i -> Stream.empty();
+        Function<Integer, Stream<Integer>> flatMapperBy2 = i -> Stream.of(i, i);
+
+        exerciseMapCollection(data,
+                              groupingBy(classifier, flatMapping(flatMapperByNull, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FlatMappingAssertion<>(flatMapperBy0,
+                                                                                   new ToListAssertion<>())));
+        exerciseMapCollection(data,
+                              groupingBy(classifier, flatMapping(flatMapperBy0, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FlatMappingAssertion<>(flatMapperBy0,
+                                                                                   new ToListAssertion<>())));
+        exerciseMapCollection(data,
+                              groupingBy(classifier, flatMapping(flatMapperBy2, toList())),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new FlatMappingAssertion<>(flatMapperBy2,
+                                                                                   new ToListAssertion<>())));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoLevelGroupingBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 6;
+        Function<Integer, Integer> classifier2 = i -> i % 23;
+
+        // Two-level groupBy
+        exerciseMapCollection(data,
+                              groupingBy(classifier, groupingBy(classifier2)),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new GroupingByAssertion<>(classifier2, HashMap.class,
+                                                                                  new ToListAssertion<>())));
+        // with concurrent as upstream
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, groupingBy(classifier2)),
+                              new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new GroupingByAssertion<>(classifier2, HashMap.class,
+                                                                                  new ToListAssertion<>())));
+        // with concurrent as downstream
+        exerciseMapCollection(data,
+                              groupingBy(classifier, groupingByConcurrent(classifier2)),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new GroupingByAssertion<>(classifier2, ConcurrentHashMap.class,
+                                                                                  new ToListAssertion<>())));
+        // with concurrent as upstream and downstream
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, groupingByConcurrent(classifier2)),
+                              new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new GroupingByAssertion<>(classifier2, ConcurrentHashMap.class,
+                                                                                  new ToListAssertion<>())));
+
+        // With explicit constructors
+        exerciseMapCollection(data,
+                              groupingBy(classifier, TreeMap::new, groupingBy(classifier2, TreeMap::new, toCollection(HashSet::new))),
+                              new GroupingByAssertion<>(classifier, TreeMap.class,
+                                                        new GroupingByAssertion<>(classifier2, TreeMap.class,
+                                                                                  new ToCollectionAssertion<Integer>(HashSet.class, false))));
+        // with concurrent as upstream
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingBy(classifier2, TreeMap::new, toList())),
+                              new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new GroupingByAssertion<>(classifier2, TreeMap.class,
+                                                                                  new ToListAssertion<>())));
+        // with concurrent as downstream
+        exerciseMapCollection(data,
+                              groupingBy(classifier, TreeMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
+                              new GroupingByAssertion<>(classifier, TreeMap.class,
+                                                        new GroupingByAssertion<>(classifier2, ConcurrentSkipListMap.class,
+                                                                                  new ToListAssertion<>())));
+        // with concurrent as upstream and downstream
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
+                              new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new GroupingByAssertion<>(classifier2, ConcurrentSkipListMap.class,
+                                                                                  new ToListAssertion<>())));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testGroupubgByWithReducing(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Function<Integer, Integer> classifier = i -> i % 3;
+
+        // Single-level simple reduce
+        exerciseMapCollection(data,
+                              groupingBy(classifier, reducing(0, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+        // with concurrent
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, reducing(0, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+
+        // With explicit constructors
+        exerciseMapCollection(data,
+                              groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, TreeMap.class,
+                                                        new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+        // with concurrent
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+
+        // Single-level map-reduce
+        exerciseMapCollection(data,
+                              groupingBy(classifier, reducing(0, mDoubler, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, HashMap.class,
+                                                        new ReducingAssertion<>(0, mDoubler, Integer::sum)));
+        // with concurrent
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, reducing(0, mDoubler, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
+                                                        new ReducingAssertion<>(0, mDoubler, Integer::sum)));
+
+        // With explicit constructors
+        exerciseMapCollection(data,
+                              groupingBy(classifier, TreeMap::new, reducing(0, mDoubler, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, TreeMap.class,
+                                                        new ReducingAssertion<>(0, mDoubler, Integer::sum)));
+        // with concurrent
+        exerciseMapCollection(data,
+                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, mDoubler, Integer::sum)),
+                              new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
+                                                        new ReducingAssertion<>(0, mDoubler, Integer::sum)));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testSimplePartitioningBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Predicate<Integer> classifier = i -> i % 3 == 0;
+
+        // Single-level partition to downstream List
+        exerciseMapCollection(data,
+                              partitioningBy(classifier),
+                              new PartitioningByAssertion<>(classifier, new ToListAssertion<>()));
+        exerciseMapCollection(data,
+                              partitioningBy(classifier, toList()),
+                              new PartitioningByAssertion<>(classifier, new ToListAssertion<>()));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoLevelPartitioningBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        Predicate<Integer> classifier = i -> i % 3 == 0;
+        Predicate<Integer> classifier2 = i -> i % 7 == 0;
+
+        // Two level partition
+        exerciseMapCollection(data,
+                              partitioningBy(classifier, partitioningBy(classifier2)),
+                              new PartitioningByAssertion<>(classifier,
+                                                            new PartitioningByAssertion(classifier2, new ToListAssertion<>())));
+
+        // Two level partition with reduce
+        exerciseMapCollection(data,
+                              partitioningBy(classifier, reducing(0, Integer::sum)),
+                              new PartitioningByAssertion<>(classifier,
+                                                            new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
+        List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
+        List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
+        assertEquals(asList, asImmutableList);
+        try {
+            asImmutableList.add(0);
+            fail("Expecting immutable result");
+        }
+        catch (UnsupportedOperationException ignored) { }
+    }
+
+}
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -34,8 +34,19 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
-import java.util.stream.*;
+import java.util.function.Supplier;
+import java.util.stream.DoubleStream;
+import java.util.stream.DoubleStreamTestDataProvider;
+import java.util.stream.IntStream;
+import java.util.stream.IntStreamTestDataProvider;
+import java.util.stream.LongStream;
+import java.util.stream.LongStreamTestDataProvider;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.StreamTestDataProvider;
+import java.util.stream.TestData;
 
 import static java.util.stream.LambdaTestHelpers.*;
 import static java.util.stream.ThowableHelper.checkNPE;
@@ -66,6 +77,59 @@
         exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars));
     }
 
+    @Test
+    public void testClose() {
+        AtomicInteger before = new AtomicInteger();
+        AtomicInteger onClose = new AtomicInteger();
+
+        Supplier<Stream<Integer>> s = () -> {
+            before.set(0); onClose.set(0);
+            return Stream.of(1, 2).peek(e -> before.getAndIncrement());
+        };
+
+        s.get().flatMap(i -> Stream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+
+        s.get().flatMapToInt(i -> IntStream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+
+        s.get().flatMapToLong(i -> LongStream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+
+        s.get().flatMapToDouble(i -> DoubleStream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+    }
+
+    @Test
+    public void testIntClose() {
+        AtomicInteger before = new AtomicInteger();
+        AtomicInteger onClose = new AtomicInteger();
+
+        IntStream.of(1, 2).peek(e -> before.getAndIncrement()).
+                flatMap(i -> IntStream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+    }
+
+    @Test
+    public void testLongClose() {
+        AtomicInteger before = new AtomicInteger();
+        AtomicInteger onClose = new AtomicInteger();
+
+        LongStream.of(1, 2).peek(e -> before.getAndIncrement()).
+                flatMap(i -> LongStream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+    }
+
+    @Test
+    public void testDoubleClose() {
+        AtomicInteger before = new AtomicInteger();
+        AtomicInteger onClose = new AtomicInteger();
+
+        DoubleStream.of(1, 2).peek(e -> before.getAndIncrement()).
+                flatMap(i -> DoubleStream.of(i, i).onClose(onClose::getAndIncrement)).count();
+        assertEquals(before.get(), onClose.get());
+    }
+
     @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));
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Thu Feb 26 10:56:26 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,621 +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.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.StringJoiner;
-import java.util.TreeMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.stream.Collector;
-import java.util.stream.Collectors;
-import java.util.stream.LambdaTestHelpers;
-import java.util.stream.OpTestCase;
-import java.util.stream.Stream;
-import java.util.stream.StreamOpFlagTestHelper;
-import java.util.stream.StreamTestDataProvider;
-import java.util.stream.TestData;
-
-import org.testng.annotations.Test;
-
-import static java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.groupingByConcurrent;
-import static java.util.stream.Collectors.partitioningBy;
-import static java.util.stream.Collectors.reducing;
-import static java.util.stream.Collectors.toCollection;
-import static java.util.stream.Collectors.toConcurrentMap;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
-import static java.util.stream.Collectors.toSet;
-import static java.util.stream.LambdaTestHelpers.assertContents;
-import static java.util.stream.LambdaTestHelpers.assertContentsUnordered;
-import static java.util.stream.LambdaTestHelpers.mDoubler;
-
-/**
- * TabulatorsTest
- *
- * @author Brian Goetz
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class TabulatorsTest extends OpTestCase {
-
-    private static abstract class TabulationAssertion<T, U> {
-        abstract void assertValue(U value,
-                                  Supplier<Stream<T>> source,
-                                  boolean ordered) throws ReflectiveOperationException;
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    static class GroupedMapAssertion<T, K, V, M extends Map<K, ? extends V>> extends TabulationAssertion<T, M> {
-        private final Class<? extends Map> clazz;
-        private final Function<T, K> classifier;
-        private final TabulationAssertion<T,V> downstream;
-
-        protected GroupedMapAssertion(Function<T, K> classifier,
-                                      Class<? extends Map> clazz,
-                                      TabulationAssertion<T, V> downstream) {
-            this.clazz = clazz;
-            this.classifier = classifier;
-            this.downstream = downstream;
-        }
-
-        void assertValue(M map,
-                         Supplier<Stream<T>> source,
-                         boolean ordered) throws ReflectiveOperationException {
-            if (!clazz.isAssignableFrom(map.getClass()))
-                fail(String.format("Class mismatch in GroupedMapAssertion: %s, %s", clazz, map.getClass()));
-            assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(toSet()));
-            for (Map.Entry<K, ? extends V> entry : map.entrySet()) {
-                K key = entry.getKey();
-                downstream.assertValue(entry.getValue(),
-                                       () -> source.get().filter(e -> classifier.apply(e).equals(key)),
-                                       ordered);
-            }
-        }
-    }
-
-    static class ToMapAssertion<T, K, V, M extends Map<K,V>> extends TabulationAssertion<T, M> {
-        private final Class<? extends Map> clazz;
-        private final Function<T, K> keyFn;
-        private final Function<T, V> valueFn;
-        private final BinaryOperator<V> mergeFn;
-
-        ToMapAssertion(Function<T, K> keyFn,
-                       Function<T, V> valueFn,
-                       BinaryOperator<V> mergeFn,
-                       Class<? extends Map> clazz) {
-            this.clazz = clazz;
-            this.keyFn = keyFn;
-            this.valueFn = valueFn;
-            this.mergeFn = mergeFn;
-        }
-
-        @Override
-        void assertValue(M map, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
-            Set<K> uniqueKeys = source.get().map(keyFn).collect(toSet());
-            assertTrue(clazz.isAssignableFrom(map.getClass()));
-            assertEquals(uniqueKeys, map.keySet());
-            source.get().forEach(t -> {
-                K key = keyFn.apply(t);
-                V v = source.get()
-                            .filter(e -> key.equals(keyFn.apply(e)))
-                            .map(valueFn)
-                            .reduce(mergeFn)
-                            .get();
-                assertEquals(map.get(key), v);
-            });
-        }
-    }
-
-    static class PartitionAssertion<T, D> extends TabulationAssertion<T, Map<Boolean,D>> {
-        private final Predicate<T> predicate;
-        private final TabulationAssertion<T,D> downstream;
-
-        protected PartitionAssertion(Predicate<T> predicate,
-                                     TabulationAssertion<T, D> downstream) {
-            this.predicate = predicate;
-            this.downstream = downstream;
-        }
-
-        void assertValue(Map<Boolean, D> map,
-                         Supplier<Stream<T>> source,
-                         boolean ordered) throws ReflectiveOperationException {
-            if (!Map.class.isAssignableFrom(map.getClass()))
-                fail(String.format("Class mismatch in PartitionAssertion: %s", map.getClass()));
-            assertEquals(2, map.size());
-            downstream.assertValue(map.get(true), () -> source.get().filter(predicate), ordered);
-            downstream.assertValue(map.get(false), () -> source.get().filter(predicate.negate()), ordered);
-        }
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    static class ListAssertion<T> extends TabulationAssertion<T, List<T>> {
-        @Override
-        void assertValue(List<T> value, Supplier<Stream<T>> source, boolean ordered)
-                throws ReflectiveOperationException {
-            if (!List.class.isAssignableFrom(value.getClass()))
-                fail(String.format("Class mismatch in ListAssertion: %s", value.getClass()));
-            Stream<T> stream = source.get();
-            List<T> result = new ArrayList<>();
-            for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
-                result.add(it.next());
-            if (StreamOpFlagTestHelper.isStreamOrdered(stream) && ordered)
-                assertContents(value, result);
-            else
-                assertContentsUnordered(value, result);
-        }
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    static class CollectionAssertion<T> extends TabulationAssertion<T, Collection<T>> {
-        private final Class<? extends Collection> clazz;
-        private final boolean targetOrdered;
-
-        protected CollectionAssertion(Class<? extends Collection> clazz, boolean targetOrdered) {
-            this.clazz = clazz;
-            this.targetOrdered = targetOrdered;
-        }
-
-        @Override
-        void assertValue(Collection<T> value, Supplier<Stream<T>> source, boolean ordered)
-                throws ReflectiveOperationException {
-            if (!clazz.isAssignableFrom(value.getClass()))
-                fail(String.format("Class mismatch in CollectionAssertion: %s, %s", clazz, value.getClass()));
-            Stream<T> stream = source.get();
-            Collection<T> result = clazz.newInstance();
-            for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
-                result.add(it.next());
-            if (StreamOpFlagTestHelper.isStreamOrdered(stream) && targetOrdered && ordered)
-                assertContents(value, result);
-            else
-                assertContentsUnordered(value, result);
-        }
-    }
-
-    static class ReduceAssertion<T, U> extends TabulationAssertion<T, U> {
-        private final U identity;
-        private final Function<T, U> mapper;
-        private final BinaryOperator<U> reducer;
-
-        ReduceAssertion(U identity, Function<T, U> mapper, BinaryOperator<U> reducer) {
-            this.identity = identity;
-            this.mapper = mapper;
-            this.reducer = reducer;
-        }
-
-        @Override
-        void assertValue(U value, Supplier<Stream<T>> source, boolean ordered)
-                throws ReflectiveOperationException {
-            Optional<U> reduced = source.get().map(mapper).reduce(reducer);
-            if (value == null)
-                assertTrue(!reduced.isPresent());
-            else if (!reduced.isPresent()) {
-                assertEquals(value, identity);
-            }
-            else {
-                assertEquals(value, reduced.get());
-            }
-        }
-    }
-
-    private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) {
-        return (act, exp, ord, par) -> {
-            if (par && (!ordered || !ord)) {
-                TabulatorsTest.nestedMapEqualityAssertion(act, exp);
-            }
-            else {
-                LambdaTestHelpers.assertContentsEqual(act, exp);
-            }
-        };
-    }
-
-    private<T, M extends Map>
-    void exerciseMapTabulation(TestData<T, Stream<T>> data,
-                               Collector<T, ?, ? extends M> collector,
-                               TabulationAssertion<T, M> assertion)
-            throws ReflectiveOperationException {
-        boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
-
-        M m = withData(data)
-                .terminal(s -> s.collect(collector))
-                .resultAsserter(mapTabulationAsserter(ordered))
-                .exercise();
-        assertion.assertValue(m, () -> data.stream(), ordered);
-
-        m = withData(data)
-                .terminal(s -> s.unordered().collect(collector))
-                .resultAsserter(mapTabulationAsserter(ordered))
-                .exercise();
-        assertion.assertValue(m, () -> data.stream(), false);
-    }
-
-    private static void nestedMapEqualityAssertion(Object o1, Object o2) {
-        if (o1 instanceof Map) {
-            Map m1 = (Map) o1;
-            Map m2 = (Map) o2;
-            assertContentsUnordered(m1.keySet(), m2.keySet());
-            for (Object k : m1.keySet())
-                nestedMapEqualityAssertion(m1.get(k), m2.get(k));
-        }
-        else if (o1 instanceof Collection) {
-            assertContentsUnordered(((Collection) o1), ((Collection) o2));
-        }
-        else
-            assertEquals(o1, o2);
-    }
-
-    private<T, R> void assertCollect(TestData.OfRef<T> data,
-                                     Collector<T, ?, R> collector,
-                                     Function<Stream<T>, R> streamReduction) {
-        R check = streamReduction.apply(data.stream());
-        withData(data).terminal(s -> s.collect(collector)).expectedResult(check).exercise();
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testReduce(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        assertCollect(data, Collectors.reducing(0, Integer::sum),
-                      s -> s.reduce(0, Integer::sum));
-        assertCollect(data, Collectors.reducing(Integer.MAX_VALUE, Integer::min),
-                      s -> s.min(Integer::compare).orElse(Integer.MAX_VALUE));
-        assertCollect(data, Collectors.reducing(Integer.MIN_VALUE, Integer::max),
-                      s -> s.max(Integer::compare).orElse(Integer.MIN_VALUE));
-
-        assertCollect(data, Collectors.reducing(Integer::sum),
-                      s -> s.reduce(Integer::sum));
-        assertCollect(data, Collectors.minBy(Comparator.naturalOrder()),
-                      s -> s.min(Integer::compare));
-        assertCollect(data, Collectors.maxBy(Comparator.naturalOrder()),
-                      s -> s.max(Integer::compare));
-
-        assertCollect(data, Collectors.reducing(0, x -> x*2, Integer::sum),
-                      s -> s.map(x -> x*2).reduce(0, Integer::sum));
-
-        assertCollect(data, Collectors.summingLong(x -> x * 2L),
-                      s -> s.map(x -> x*2L).reduce(0L, Long::sum));
-        assertCollect(data, Collectors.summingInt(x -> x * 2),
-                      s -> s.map(x -> x*2).reduce(0, Integer::sum));
-        assertCollect(data, Collectors.summingDouble(x -> x * 2.0d),
-                      s -> s.map(x -> x * 2.0d).reduce(0.0d, Double::sum));
-
-        assertCollect(data, Collectors.averagingInt(x -> x * 2),
-                      s -> s.mapToInt(x -> x * 2).average().orElse(0));
-        assertCollect(data, Collectors.averagingLong(x -> x * 2),
-                      s -> s.mapToLong(x -> x * 2).average().orElse(0));
-        assertCollect(data, Collectors.averagingDouble(x -> x * 2),
-                      s -> s.mapToDouble(x -> x * 2).average().orElse(0));
-
-        // Test explicit Collector.of
-        Collector<Integer, long[], Double> avg2xint = Collector.of(() -> new long[2],
-                                                                   (a, b) -> {
-                                                                       a[0] += b * 2;
-                                                                       a[1]++;
-                                                                   },
-                                                                   (a, b) -> {
-                                                                       a[0] += b[0];
-                                                                       a[1] += b[1];
-                                                                       return a;
-                                                                   },
-                                                                   a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]);
-        assertCollect(data, avg2xint,
-                      s -> s.mapToInt(x -> x * 2).average().orElse(0));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testJoin(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        withData(data)
-                .terminal(s -> s.map(Object::toString).collect(Collectors.joining()))
-                .expectedResult(join(data, ""))
-                .exercise();
-
-        Collector<String, StringBuilder, String> likeJoining = Collector.of(StringBuilder::new, StringBuilder::append, (sb1, sb2) -> sb1.append(sb2.toString()), StringBuilder::toString);
-        withData(data)
-                .terminal(s -> s.map(Object::toString).collect(likeJoining))
-                .expectedResult(join(data, ""))
-                .exercise();
-
-        withData(data)
-                .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",")))
-                .expectedResult(join(data, ","))
-                .exercise();
-
-        withData(data)
-                .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",", "[", "]")))
-                .expectedResult("[" + join(data, ",") + "]")
-                .exercise();
-
-        withData(data)
-                .terminal(s -> s.map(Object::toString)
-                                .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
-                                .toString())
-                .expectedResult(join(data, ""))
-                .exercise();
-
-        withData(data)
-                .terminal(s -> s.map(Object::toString)
-                                .collect(() -> new StringJoiner(","),
-                                         (sj, cs) -> sj.add(cs),
-                                         (j1, j2) -> j1.merge(j2))
-                                .toString())
-                .expectedResult(join(data, ","))
-                .exercise();
-
-        withData(data)
-                .terminal(s -> s.map(Object::toString)
-                                .collect(() -> new StringJoiner(",", "[", "]"),
-                                         (sj, cs) -> sj.add(cs),
-                                         (j1, j2) -> j1.merge(j2))
-                                .toString())
-                .expectedResult("[" + join(data, ",") + "]")
-                .exercise();
-    }
-
-    private<T> String join(TestData.OfRef<T> data, String delim) {
-        StringBuilder sb = new StringBuilder();
-        boolean first = true;
-        for (T i : data) {
-            if (!first)
-                sb.append(delim);
-            sb.append(i.toString());
-            first = false;
-        }
-        return sb.toString();
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testSimpleToMap(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        Function<Integer, Integer> keyFn = i -> i * 2;
-        Function<Integer, Integer> valueFn = i -> i * 4;
-
-        List<Integer> dataAsList = Arrays.asList(data.stream().toArray(Integer[]::new));
-        Set<Integer> dataAsSet = new HashSet<>(dataAsList);
-
-        BinaryOperator<Integer> sum = Integer::sum;
-        for (BinaryOperator<Integer> op : Arrays.asList((u, v) -> u,
-                                                        (u, v) -> v,
-                                                        sum)) {
-            try {
-                exerciseMapTabulation(data, toMap(keyFn, valueFn),
-                                      new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class));
-                if (dataAsList.size() != dataAsSet.size())
-                    fail("Expected ISE on input with duplicates");
-            }
-            catch (IllegalStateException e) {
-                if (dataAsList.size() == dataAsSet.size())
-                    fail("Expected no ISE on input without duplicates");
-            }
-
-            exerciseMapTabulation(data, toMap(keyFn, valueFn, op),
-                                  new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class));
-
-            exerciseMapTabulation(data, toMap(keyFn, valueFn, op, TreeMap::new),
-                                  new ToMapAssertion<>(keyFn, valueFn, op, TreeMap.class));
-        }
-
-        // For concurrent maps, only use commutative merge functions
-        try {
-            exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn),
-                                  new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class));
-            if (dataAsList.size() != dataAsSet.size())
-                fail("Expected ISE on input with duplicates");
-        }
-        catch (IllegalStateException e) {
-            if (dataAsList.size() == dataAsSet.size())
-                fail("Expected no ISE on input without duplicates");
-        }
-
-        exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn, sum),
-                              new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class));
-
-        exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn, sum, ConcurrentSkipListMap::new),
-                              new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentSkipListMap.class));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testSimpleGroupBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        Function<Integer, Integer> classifier = i -> i % 3;
-
-        // Single-level groupBy
-        exerciseMapTabulation(data, groupingBy(classifier),
-                              new GroupedMapAssertion<>(classifier, HashMap.class,
-                                                        new ListAssertion<>()));
-        exerciseMapTabulation(data, groupingByConcurrent(classifier),
-                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                        new ListAssertion<>()));
-
-        // With explicit constructors
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, TreeMap::new, toCollection(HashSet::new)),
-                              new GroupedMapAssertion<>(classifier, TreeMap.class,
-                                                        new CollectionAssertion<Integer>(HashSet.class, false)));
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new,
-                                                   toCollection(HashSet::new)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
-                                                        new CollectionAssertion<Integer>(HashSet.class, false)));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTwoLevelGroupBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        Function<Integer, Integer> classifier = i -> i % 6;
-        Function<Integer, Integer> classifier2 = i -> i % 23;
-
-        // Two-level groupBy
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, groupingBy(classifier2)),
-                              new GroupedMapAssertion<>(classifier, HashMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, HashMap.class,
-                                                                                  new ListAssertion<>())));
-        // with concurrent as upstream
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, groupingBy(classifier2)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, HashMap.class,
-                                                                                  new ListAssertion<>())));
-        // with concurrent as downstream
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, groupingByConcurrent(classifier2)),
-                              new GroupedMapAssertion<>(classifier, HashMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, ConcurrentHashMap.class,
-                                                                                  new ListAssertion<>())));
-        // with concurrent as upstream and downstream
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, groupingByConcurrent(classifier2)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, ConcurrentHashMap.class,
-                                                                                  new ListAssertion<>())));
-
-        // With explicit constructors
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, TreeMap::new, groupingBy(classifier2, TreeMap::new, toCollection(HashSet::new))),
-                              new GroupedMapAssertion<>(classifier, TreeMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, TreeMap.class,
-                                                                                  new CollectionAssertion<Integer>(HashSet.class, false))));
-        // with concurrent as upstream
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingBy(classifier2, TreeMap::new, toList())),
-                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, TreeMap.class,
-                                                                                  new ListAssertion<>())));
-        // with concurrent as downstream
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, TreeMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
-                              new GroupedMapAssertion<>(classifier, TreeMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, ConcurrentSkipListMap.class,
-                                                                                  new ListAssertion<>())));
-        // with concurrent as upstream and downstream
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
-                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
-                                                        new GroupedMapAssertion<>(classifier2, ConcurrentSkipListMap.class,
-                                                                                  new ListAssertion<>())));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testGroupedReduce(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        Function<Integer, Integer> classifier = i -> i % 3;
-
-        // Single-level simple reduce
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, reducing(0, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, HashMap.class,
-                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
-        // with concurrent
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, reducing(0, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
-
-        // With explicit constructors
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, TreeMap.class,
-                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
-        // with concurrent
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
-                                                        new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
-
-        // Single-level map-reduce
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, reducing(0, mDoubler, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, HashMap.class,
-                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
-        // with concurrent
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, reducing(0, mDoubler, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
-
-        // With explicit constructors
-        exerciseMapTabulation(data,
-                              groupingBy(classifier, TreeMap::new, reducing(0, mDoubler, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, TreeMap.class,
-                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
-        // with concurrent
-        exerciseMapTabulation(data,
-                              groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, mDoubler, Integer::sum)),
-                              new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
-                                                        new ReduceAssertion<>(0, mDoubler, Integer::sum)));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testSimplePartition(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        Predicate<Integer> classifier = i -> i % 3 == 0;
-
-        // Single-level partition to downstream List
-        exerciseMapTabulation(data,
-                              partitioningBy(classifier),
-                              new PartitionAssertion<>(classifier, new ListAssertion<>()));
-        exerciseMapTabulation(data,
-                              partitioningBy(classifier, toList()),
-                              new PartitionAssertion<>(classifier, new ListAssertion<>()));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTwoLevelPartition(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        Predicate<Integer> classifier = i -> i % 3 == 0;
-        Predicate<Integer> classifier2 = i -> i % 7 == 0;
-
-        // Two level partition
-        exerciseMapTabulation(data,
-                              partitioningBy(classifier, partitioningBy(classifier2)),
-                              new PartitionAssertion<>(classifier,
-                                                       new PartitionAssertion(classifier2, new ListAssertion<>())));
-
-        // Two level partition with reduce
-        exerciseMapTabulation(data,
-                              partitioningBy(classifier, reducing(0, Integer::sum)),
-                              new PartitionAssertion<>(classifier,
-                                                       new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
-        List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
-        List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
-        assertEquals(asList, asImmutableList);
-        try {
-            asImmutableList.add(0);
-            fail("Expecting immutable result");
-        }
-        catch (UnsupportedOperationException ignored) { }
-    }
-
-}
--- a/test/java/util/zip/TestExtraTime.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/java/util/zip/TestExtraTime.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -71,6 +71,7 @@
         }
 
         testNullHandling();
+        testTimeConversions();
     }
 
     static void test(FileTime mtime, FileTime atime, FileTime ctime,
@@ -178,4 +179,33 @@
             // pass
         }
     }
+
+    // verify that setting and getting any time is possible as per the intent
+    // of 4759491
+    static void testTimeConversions() {
+        // Sample across the entire range
+        long step = Long.MAX_VALUE / 100L;
+        testTimeConversions(Long.MIN_VALUE, Long.MAX_VALUE - step, step);
+
+        // Samples through the near future
+        long currentTime = System.currentTimeMillis();
+        testTimeConversions(currentTime, currentTime + 1_000_000, 10_000);
+    }
+
+    static void testTimeConversions(long from, long to, long step) {
+        ZipEntry ze = new ZipEntry("TestExtraTime.java");
+        for (long time = from; time <= to; time += step) {
+            ze.setTime(time);
+            FileTime lastModifiedTime = ze.getLastModifiedTime();
+            if (lastModifiedTime.toMillis() != time) {
+                throw new RuntimeException("setTime should make getLastModifiedTime " +
+                        "return the specified instant: " + time +
+                        " got: " + lastModifiedTime.toMillis());
+            }
+            if (ze.getTime() != time) {
+                throw new RuntimeException("getTime after setTime, expected: " +
+                        time + " got: " + ze.getTime());
+            }
+        }
+    }
 }
--- a/test/jdk/lambda/separate/Compiler.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/jdk/lambda/separate/Compiler.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -54,7 +54,7 @@
     private static final AtomicInteger counter = new AtomicInteger();
     private static final String targetDir =
         System.getProperty("lambda.separate.targetDirectory",
-            System.getProperty("java.io.tmpdir") + File.separator + "gen-separate");
+            "." + File.separator + "gen-separate");
     private static final File root = new File(targetDir);
     private static ConcurrentHashMap<String,File> cache =
             new ConcurrentHashMap<>();
@@ -189,7 +189,7 @@
                 StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
         } catch (IOException e) {
             throw new RuntimeException(
-                "IOException encountered during compilation");
+                "IOException encountered during compilation: " + e.getMessage(), e);
         }
         Boolean result = ct.call();
         if (result == Boolean.FALSE) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native_sanity/simplenativelauncher/ProgramTest.java	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.OutputAnalyzer
+ * @build ProgramTest
+ * @run main/native ProgramTest
+ */
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+public class ProgramTest {
+    public static void main(String... args) throws Exception {
+        String lib = System.getProperty("test.nativepath");
+        ProcessBuilder pb = new ProcessBuilder(lib + "/sanity_SimpleNativeLauncher");
+        OutputAnalyzer output = ProcessTools.executeProcess(pb);
+        output.shouldHaveExitValue(0);
+        output.stdoutShouldContain("Hello");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native_sanity/simplenativelauncher/exesanity_SimpleNativeLauncher.c	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+ #include <stdio.h>
+
+int
+main(int argc, char** argv)
+{
+    printf("Hello\n");
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native_sanity/simplenativelib/NativeLib.java	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 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
+ * @run main/native NativeLib
+ */
+
+public class NativeLib {
+    public static void main(String... args) throws Exception {
+        System.loadLibrary("sanity_SimpleNativeLib");
+
+        int res = nativeFunc();
+        if (res != 4711) {
+            throw new Exception("Wrong value returned from native code: " + res);
+        }
+    }
+
+    static native int nativeFunc();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native_sanity/simplenativelib/libsanity_SimpleNativeLib.c	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+ #include <jni.h>
+
+JNIEXPORT jint JNICALL
+Java_NativeLib_nativeFunc(JNIEnv *env, jclass dummy)
+{
+    return 4711;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native_sanity/simplenativelib2/NativeLib.java	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 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
+ * @run main/native NativeLib
+ */
+
+public class NativeLib {
+    public static void main(String... args) throws Exception {
+        System.loadLibrary("sanity_SimpleNativeLib2");
+
+        int res = nativeFunc();
+        if (res != 4712) {
+            throw new Exception("Wrong value returned from native code: " + res);
+        }
+    }
+
+    static native int nativeFunc();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native_sanity/simplenativelib2/libsanity_SimpleNativeLib2.c	Mon Mar 02 10:09:03 2015 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+ #include <jni.h>
+
+JNIEXPORT jint JNICALL
+Java_NativeLib_nativeFunc(JNIEnv *env, jclass dummy)
+{
+    return 4712;
+}
--- a/test/sun/security/tools/keytool/KeyToolTest.java	Thu Feb 26 10:56:26 2015 -0800
+++ b/test/sun/security/tools/keytool/KeyToolTest.java	Mon Mar 02 10:09:03 2015 -0800
@@ -1612,7 +1612,7 @@
 
         // 8073181: keytool -ext honored not working correctly
         testOK("", simple+"-gencert -alias ca -infile test.req -ext " +
-                "honored=1.2.3,1.2.4:critical " +
+                "honored=1.2.3,KU,1.2.4:critical " +
                 "-debug -rfc -outfile test2.cert");
         testOK("", simple+"-importcert -file test2.cert -alias b");
         ks = loadStore("x.jks", "changeit", "JKS");